I'm trying to implement simple wrapper for find to find files, links or both. Here is path of my code:
typeArr=()
if [[ "$type" == "f" || "$type" == "l" ]]; then
typeArr=("-type" "$type")
elif [[ "$type" == "b" ]]; then
typeArr=("\(" "-type" "f" "-o" "-type" "l" "\)")
fi
mapfile -t targetFilesArray < <(find "$targetDir" "${typeArr[@]}" -name "${prefix}*" -exec basename {} \;)
Everything is working with f or l, but with b (both) I'm getting this error:
find: paths must precede expression: `\)'
When I paste array content manually - all good:
find "$targetDir" \( -type f -o -type l \) -name "${prefix}*"
/srv/...
echo "${typeArr[@]}"
\( -type f -o -type l \)
find "$targetDir" "${typeArr[@]}" -name "${prefix}*"
find: paths must precede expression: `\)'
Looks like this problem comes from inserting escaped parentheses into find command, but I haven't find a way to fix it (except of not using array and simply insert them into command itself).
Thanks for help, I removed escaping (quotes will work too) and all good:
typeArr=("(" "-type" "f" "-o" "-type" "l" ")")
If you use ( and ) in command line bash will try to create an array,
So you have to escape it with \ so they are given to find as ( ) and not an array of the args in between.
But when you put () in a sting (between quotes) bash will not interpret them. so you don't need to escape them.
If you want to use array you will do without escape because they are in between quotes:
typeArr=('(' '-type' 'f' '-o' '-type' 'l' ')')
̶O̶t̶h̶e̶r̶w̶i̶s̶e̶ ̶y̶o̶u̶ ̶c̶a̶n̶ ̶d̶o̶ ̶w̶i̶t̶h̶ ̶s̶i̶m̶p̶l̶e̶ ̶s̶t̶i̶n̶g̶s̶ ̶(̶n̶o̶ ̶a̶r̶r̶a̶y̶,̶ ̶m̶o̶r̶e̶ ̶r̶e̶a̶d̶a̶b̶l̶e̶ ̶i̶ ̶t̶h̶i̶n̶k̶)̶:̶
More readable but less secure without array :
typeArr=()
if [[ "$type" == "f" || "$type" == "l" ]]; then
typeArg="-type $type"
elif [[ "$type" == "b" ]]; then
typeArg='-type f -o -type l'
else
echo 'Error: Unknow type'
fi
mapfile -t targetFilesArray < <(find "$targetDir" $typeArg -name "${prefix}*"" -exec basename {} \;)
In this case you can see that
$typeArghave no quotes because you want to give find multiple args not just one strings