Reputation: 1
I'm a beginner in Bash scripting. I'm using Kali Linux. I wrote a bash file. It's supposed to ask for user input to fill in every single parameter of the command and then at the end, it will echo out the full command, that it intends to execute, in simple text form, and then execute that exact command with all the given information (The command that it's supposed to execute in the end is "find"). Everything works fine except for the last part where it's supposed to execute the "find" command. This is an example:
find '/home/kali/Desktop' -type f -user 'kali' -iname 'this text file.txt'
I copied this line and executed it from the terminal directly with all the same arguments and it worked, but when I indirectly executed it through the Bash file, it didn't work. And it kept saying "find: ‘'kali'’ is not the name of a known user".
find '/home/kali/Desktop' -type f -user kali -iname 'this text file.txt'
When I removed the quotes around the word "kali", it gave me this as output: "find: paths must precede expression: `text'"
I tried using "sh" and "bash" followed by the file's name as parameter in the terminal like this:
sh <filename>
bash <filename>
and it still didn't work. I even tried changing the shebang from #!/usr/bin/env bash
to #!/bin/bash
, but it still didn't work.
Here's the full code of the bash script that I wrote:
#!/bin/bash
true_path=""
find_type=""
all_types=("f" "d" "l" "c" "b" "p")
find_name=""
find_user=""
find_group=""
declare -A byte_math
keys=("c" "w" "b" "k" "M" "G")
values=(1 2 512 1024 1048576 1073741824)
for ((i = 0; i < ${#keys[@]}; i++)); do
byte_math["${keys[i]}"]="${values[i]}"
done
all_units=("c" "w" "b" "k" "M" "G")
lower_limit_size_in_bytes=""
upper_limit_size_in_bytes=""
find_size_ll=""
find_size_ul=""
function step1 () { # Asking for the path
read -p "
Where do you want to search? (enter path):
/home/kali/" path
if ! [[ -d "/home/kali/${path}" ]]; then
echo "
Invalid directory path. Try Again."
path=""
step1
return 0
fi
true_path+="'/home/kali/${path}' "
step2
}
function step2 () {
read -p "
Do you want to add another path? (Y/N): " repeat
if [[ "${repeat,,}" == "y" ]]; then
step1
elif ! [[ "${repeat,,}" == "y" || "${repeat,,}" == "n" ]]; then
echo "
Invalid Input. Try Again."
repeat=""
step2
return 0
fi
return 0
}
step1
echo "
All paths given: ${true_path} "
function step3 () { # Asking for "-type" parameter
read -p "
Type of files or folders you want to search for:
f: Regular files
d: Directories
l: Symbolic link
c: Character devices
b: Block devices
p: Named pipes (FIFO)
skip: skip
Which type?: " type_filter # If the user chooses "skip", it will skip this option
if [[ " ${all_types[*]} " == *" ${type_filter,,} "* ]]; then
find_type="-type ${type_filter,,} "
elif ! [[ "${type_filter,,}" == "skip" ]]; then
echo "
Invalid type. Try Again."
type_filter=""
step3
return 0
fi
return 0
}
step3
echo "
${find_type}"
function step4 () { # Asking for the name of the file/directory that the user is looking for
read -p "
Do you want to specify the name of the files/folders? [Y/N]: " name_Y_N
if [[ "${name_Y_N,,}" == "y" ]]; then
read -p "
File/Folder name: " file_foldername
find_name="-iname '${file_foldername}' "
elif [[ "${name_Y_N,,}" != "n" && "${name_Y_N,,}" != "y" ]]; then
echo "
Invalid input. Try Again."
name_Y_N=""
step4
return 0
fi
return 0
}
function step5 () { # Asking if the user wants to specify the user of the file they're looking for
read -p "
Do you want to look for files/folders owned by a specific user? [Y/N]: " user_Y_N
if [[ "${user_Y_N,,}" == "y" ]]; then
read -p "
Username: " username
find_user="-user ${username} "
elif [[ "${user_Y_N,,}" != "n" && "${user_Y_N,,}" != "y" ]]; then
echo "
Invalid input. Try Again."
user_Y_N=""
step5
return 0
fi
return 0
}
step5
echo "
${find_user}"
function step6 () { # Same as the one above but with group
read -p "
Do you want to look for files/folders owned by a specific group? [Y/N]: " group_Y_N
if [[ "${group_Y_N,,}" == "y" ]]; then
read -p "
Group name: " groupname
find_group="-group '${groupname}' "
elif [[ "${group_Y_N,,}" != "n" && "${group_Y_N,,}" != "y" ]]; then
echo "
Invalid input. Try Again."
group_Y_N=""
step6
return 0
fi
return 0
}
step6
echo "
${find_group}"
function step7 () { # From here (step7 to step 11) is just asking for size specification
read -p "
Do you want to specify the size of the files/folders that you're looking for? [Y/N]: " size_Y_N
if [[ "${size_Y_N,,}" == "y" ]]; then
step8
elif [[ "${size_Y_N,,}" != "n" && "${size_Y_N,,}" != "y" ]]; then
echo "
Invalid Input. Try Again."
size_Y_N=""
step7
return 0
fi
return 0
}
function step8 () {
read -p "
Do you want to specify a lower limit for the size of the files that you're looking for? [Y/N]: " lower_limit_Y_N
if [[ "${lower_limit_Y_N,,}" == "y" ]]; then
step9
elif [[ "${lower_limit_Y_N,,}" != "y" && "${lower_limit_Y_N,,}" != "n" ]]; then
echo "
Invalid Input. Try Again."
lower_limit_Y_N=""
step8
return 0
fi
step10
return 0
}
function step10 () {
read -p "
Do you want to specify a upper limit for the size of the files that you're looking for? [Y/N]: " upper_limit_Y_N
if [[ "${upper_limit_Y_N,,}" == "y" ]]; then
step11
elif [[ "${upper_limit_Y_N,,}" != "y" && "${upper_limit_Y_N,,}" != "n" ]]; then
echo "
Invalid Input. Try Again."
upper_limit_Y_N=""
step10
return 0
fi
return 0
}
function step9 () {
read -p "
Lower Limit. Choose your byte unit (Case Sensitive):
c: Bytes
w: Words (1 word = 2 bytes)
b: 512-byte blocks
k: Kilobytes (1024 bytes)
M: Megabytes (1024 kilobytes)
G: Gigabytes (1024 megabytes)
Unit: " lower_limit_unit
# $lower_limit_unit=${lower_limit_unit,,}
if ! [[ " ${all_units[*]} " == *" ${lower_limit_unit} "* ]]; then
echo "
Invalid unit. Try Again."
lower_limit_unit=""
step9
return 0
fi
read -p "
Enter size in number: " lower_limit_size
find_size_ll="-size +${lower_limit_size}${lower_limit_unit} "
return 0
}
function step11 () {
read -p "
Upper Limit. Choose your byte unit (Case Sensitive):
c: Bytes
w: Words (1 word = 2 bytes)
b: 512-byte blocks
k: Kilobytes (1024 bytes)
M: Megabytes (1024 kilobytes)
G: Gigabytes (1024 megabytes)
Unit: " upper_limit_unit
# $upper_limit_unit=${upper_limit_unit,,}
if ! [[ " ${all_units[*]} " == *" ${upper_limit_unit} "* ]]; then
echo "
Invalid unit. Try Again."
upper_limit_unit=""
step11
return 0
fi
read -p "
Enter size in number: " upper_limit_size
if [[ -n $find_size_ll ]]; then
upper_limit_size_in_bytes=$(($upper_limit_size * ${byte_math[$upper_limit_unit]}))
lower_limit_size_in_bytes=$(($lower_limit_size * ${byte_math[$lower_limit_unit]}))
if [[ $upper_limit_size_in_bytes -lt $lower_limit_size_in_bytes ]]; then
echo "
Error. Upper limit size (${upper_limit_size_in_bytes} bytes) can't be smaller than lower limit size (${lower_limit_size_in_bytes} bytes). Try Again."
step9
step10
return 0
fi
fi
find_size_ul="-size -${upper_limit_size}${upper_limit_unit} "
return 0
}
step7
echo "
${find_size_ll}${find_size_ul}"
step4
echo "
${find_name}"
echo "
find ${true_path}${find_type}${find_user}${find_group}${find_size_ll}${find_size_ul}${find_name}
" # Here it will echo out the command in plain text before executing it on the line below
find ${true_path}${find_type}${find_user}${find_group}${find_size_ll}${find_size_ul}${find_name} # Here's where the command gets executed
Upvotes: 0
Views: 42