Aqui está um script que escrevi um tempo atrás para corrigir permissões em arquivos copiados de um sistema FAT. Não funcionará se os nomes dos arquivos contiverem novas linhas (embora, se alguém quiser corrigi-lo, fique à vontade):
#!/bin/sh
[ $# != 0 ] && dir="$1" || dir=.
[ -d "$dir" ] || { echo "usage: $0 [dir]"; exit 1; }
cat <<- EOF
Will recursively alter permissions under directory '$dir'.
Consider backing up permissions with 'getfacl -R $dir' first.
Continue? [Y/n]"
EOF
read reply
[ "$reply" = Y ] || exit 0
echo "Changing all directories to mode 755..."
find "$dir" -type d -exec chmod 755 {} +
# simplest way for now is just to make all files non executable, then fix ones which should be
echo "Changing all files to mode 644..."
find "$dir" -type f -exec chmod 644 {} +
# use a temp file instead of a variable since the shell will strip nulls from the string
tmpfile=$(mktemp)
# screwed if filename contains a newline - fixable with a better sed script
echo "Using magic to find executables..."
find $dir -type f -exec file -hN0 -e apptype -e cdf -e compress -e elf -e tar -e tokens {} + |
sed -n '/\x0.*executable/p' >"$tmpfile"
# ELF binaries
echo "\nSetting ELF executables to mode 755...\n"
sed '/\x0.*ELF/!d; s/\x0.*$//' "$tmpfile" | xargs -rd '\n' chmod -c 755
scripts=$(sed '/\x0.*text/!d; s/\x0.*$//' "$tmpfile")
IFS="
"
# only make scripts executable if they have a shebang
echo "\nSetting scripts with a shebang to mode 755...\n"
for file in $scripts
do
head "$file" | grep -q '^#!' && chmod -c 755 "$file"
done
rm "$tmpfile"