Reputation: 5444
In this function, a directory of files are processed. The directory should only contain what is allowed as specified/configured in the EXT array. The purpose of the function is to check to see if an extension is present in the directory that is not allowed ie if you have configured only .mp3
and .png
in the EXT array, when the function runs, if it detects a .gif
file, it throws an error. My code technically works as is right now, but the problem is it always fails when looping through the extensions.
# USER VARIABLES
INPUT=/home/administrator/music/v1.1/input
OUTPUT=/home/administrator/music/v1.1/output
declare -a EXT
EXT[0]=".png"
EXT[1]=".mp3"
function CHECK_EXT()
{
for FULLPATH in $INPUT/*; do
FULLNAME=$(basename -- "$FULLPATH")
i=0
for i in "${!EXT[@]}"; do
EXT="${EXT[$i]}"
if [[ $FULLNAME != *"$EXT" ]]; then
ERROR="Unsupported file type detected!"
return 0
fi
done
done
return 1
}
Upvotes: 2
Views: 296
Reputation: 203807
ONLY addressing the test you asked about, this is all you need to do:
# USER VARIABLES
INPUT=/home/administrator/music/v1.1/input
OUTPUT=/home/administrator/music/v1.1/output
declare -A EXT
EXT[".png"]=1
EXT[".mp3"]=1
function CHECK_EXT()
{
for FULLPATH in $INPUT/*; do
if (( "${EXT[${FULLPATH##*.}]}" != 1 )); then
ERROR="Unsupported file type detected!"
return 0
fi
done
return 1
}
There are also other ways the script could be improved, e.g. lower case variables, local variable declarations, quoted variables, standard success/fail return values, and a shebang. This, untested, is closer to how you should really write it:
#!/usr/bin/env bash
# USER VARIABLES
input_dir='/home/administrator/music/v1.1/input'
output_dir='/home/administrator/music/v1.1/output'
declare -A exts
exts[".png"]=1
exts[".mp3"]=1
function check_exts() {
local input_dir="$1" full_path ext
for full_path in "$input_dir"/*; do
ext="${full_path##*.}"
if (( "${exts[$ext]}" != 1 )); then
error='Unsupported file extension "'"$ext"'" detected!'
return 1
fi
done
return 0
}
check_exts "$input_dir" || { printf 'Failed\n' >&2; exit 1; }
idk how the variable error
really works into your real code.
Upvotes: 0
Reputation: 85710
You can re-write the logic to check the extension part as below. The idea is generate a string for alternate match with all the possible extensions supported i.e.
declare -A ext
ext[0]="png"
ext[1]="mp3"
now generate the string containing the possible extension matches and store it in a variable using the printf -v
syntax which stores the formatted string in a variable.
printf -v globStr '!(%s)' "$(IFS="|"; printf '%s' "${ext[*]}")"
Now with thr !(opt1|opt2)
pattern of the bash extglob
syntax we match the filename extension as below. Notice that we removed the .
character from the array extension. The ${filename##*.}
syntax removes parts of filename leaving only the extension part.
if [[ ${filename##*.} == $globStr ]]; then
printf '%s\n' "Only ${ext[*]} files are supported"
fi
Putting everything together
#!/usr/bin/env bash
# ^^^^ needed for [[ operator to work, not POSIX compliant
input=/home/administrator/music/v1.1/input
output=/home/administrator/music/v1.1/output
declare -A ext
ext[0]="png"
ext[1]="mp3"
# The array expansion of type "${arr[*]}" generates a single string
# with the array contents based on the IFS value set. For alternate
# match we define a custom IFS value inside "$(..)" as the value
# defined inside it is not reflected outside.
printf -v globStr '!(%s)' "$(IFS="|"; printf '%s' "${ext[*]}")"
for file in "$input"/*; do
[ -f "$file" ] || continue
filename=$(basename -- "$file")
# The '==' inside the '[[..]]' enables the extglob option
# using which we match the set of not allowed filename extensions
if [[ ${filename##*.} == $globStr ]]; then
printf '%s\n' "Only ${ext[*]} files are supported - got $filename"
fi
done
Notice the use of lower-case variable names for user-defined variables. It is always a good practice to do this as the uppercase names are reserved to be used by the shell.
Upvotes: 2
Reputation:
Your problem is here:
EXT="${EXT[$i]}"
You overwrite your EXT
array content in each run. Also instead of looping over array indices, You could write that loop block like this:
for FULLPATH in $INPUT/*; do
# check whether the file extension is NOT in the allowed EXT array
if [[ ! " ${EXT[@]} " =~ "$(basename -- "$FULLPATH")" ]]; then
ERROR="Unsupported file type detected!"
return 1
fi
done
Upvotes: 0