Tengo este script que busca archivos con permisos incorrectos. Si se encuentra alguno, le pregunta al usuario si desea arreglarlo o mostrarlo. Los resultados de la búsqueda se almacenan en una variable para evitar ejecutar el mismo comando varias veces:
#!/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
El problema chmod
arroja un error debido a las nuevas líneas:
chmod: cannot access 'test/foo'$'\n''test/bar'$'\n''test/foo bar': No such file or directory
Si elimino las comillas "$results"
, funciona un poco mejor, pero, por supuesto, los nombres de archivos que contienen espacios son problemáticos.
He estado jugando IFS=$'\n'
pero no estoy seguro de dónde debería configurarlo. Esto no parece funcionar:
IFS=$'\n' chmod 644 $results
Sin embargo, esto hace:
IFS=$'\n'
chmod 644 $results
unset IFS
Supongo que me pregunto si esto es correcto o si hay una manera mejor.
Respuesta1
Configurar IFS
solo las nuevas líneas ayuda, pero aún deja los problemas de 1) nombres de archivos con nuevas líneas (obviamente) y 2) nombres de archivos con caracteres globales. Por ejemplo, un archivo llamado *
se expandiría a todos los nombres de archivo del directorio.
En Bash, use mapfile
/ readarray
para completar una matriz en su lugar:
mapfile -d '' files < <(find . -type f ! -perm 0644 -print0)
printf "%d matching files found\n" "${#files[@]}"
printf "they are:\n"
printf " %q\n" "${files[@]}"
Ver también:
Respuesta2
En lugar de configurarlo IFS
antes chmod
y desarmarlo inmediatamente después, parece funcionar igual de bien si lo configuro/desconfiguro antes/después.find
yenvuelva el subshell en una matriz como se sugiere en los comentarios:
IFS=$'\n'
results=($(find "$0" -type f -not -perm 644))
unset IFS
De esta manera, la matriz tiene la cantidad correcta de elementos y chmod 644 "${results[@]}"
funciona como se esperaba, siempre y cuando no haya nombres de archivos que contengan caracteres de nueva línea (aunque no puedo imaginar por qué alguien haría tal cosa a propósito).