I have this script which finds files with incorrect permissions. If any are found, it asks the user if they want to fix them or show them. The find results are stored in a variable in order to avoid running the same command multiple times:
#!/usr/bin/env sh
results=$(find "$0" -type f -not -perm 644)
if [ -z "$results" ]; then
echo 'No files with incorrect permissions found'
else
while true; do
read -p 'Fix files with incorrect permissions? (yes/no/show) ' ans
case "$ans" in
Y | y | yes)
echo 'Changing file permissions...'
chmod 644 "$results"
break;;
N | n | no)
break;;
S | s | show)
echo "$results";;
*)
echo 'Please answer yes or no';;
esac
done
fi
The problem is chmod
throws an error due to the newlines:
chmod: cannot access 'test/foo'$'\n''test/bar'$'\n''test/foo bar': No such file or directory
If I remove the quotes around "$results"
, it works a little better, but then of course file names containing spaces are problematic.
I've been messing around with IFS=$'\n'
but am not sure where I should set that. This doesn't seem to work:
IFS=$'\n' chmod 644 $results
However, this does:
IFS=$'\n'
chmod 644 $results
unset IFS
I guess I'm just wondering if this is correct or if there's a better way.
results=($(find "$0" -type f -not -perm 644))
. A much better + safer option would bereadarray -t results < <(find "$0" -type f -not -perm 644)
. Then you can check for empty results (if ((! ${#results[@]})); then ...; fi
) and loop over the results (for result in "${results[@]}"; do ...; done
). – Andrej Podzimek Oct 25 '21 at 00:44