Обычно вы хотите использовать find -exec
для запуска команды для всех имен файлов, или find -print0
для передачи имен какой-нибудь команде, которая может читать записи, разделенные нулевыми байтами (например, xargs -0
).
Если вы действительно хотите иметь строки в кавычках, в Bash есть пара опций для этого:
$ find -exec bash -c 'printf "%s\n" "${@@Q}"' sh {} +
'./single'\''quote'
'./space 1'
$'./new\nline'
'./double"quote'
$ find -exec bash -c 'printf "%q\n" "$@"' sh {} +
./single\'quote
./space\ 1
$'./new\nline'
./double\"quote
Это требует дополнительного вызова оболочки, но позволяет обрабатывать несколько имен файлов одним exec.
Что касается сохранения битов разрешений (не ACL), вы можете сделать что-то вроде этого (в GNU find):
find -printf "%#m:%p\0" > files-and-modes
Это выведет записи с разрешениями, двоеточием, именем файла и байтом nul, например: 0644:имя с пробелами\0
. Это не экранирует ничего, но вместо этого выведет имена файлов как есть (если только вывод не идет на терминал, в этом случае по крайней мере новые строки будут искажены)
Вы можете прочитать результат с помощью Perl скрипта:
perl -0 -ne '($m, $f) = split/:/, $_, 2; chmod oct($m), $f; ' < files-and-modes
Или едва в Bash, см. комментарии:
while IFS=: read -r -d '' mode file ; do
# do something useful
printf "<%s> <%s>\n" "$mode" "$file"
chmod "$mode" "$file"
done < files-and-modes
Насколько я проверял, это работает с новыми строками, кавычками, пробелами и двоеточиями. Обратите внимание, что нам нужно использовать в качестве разделителя не пробелы, а что-то другое, поскольку установка IFS=" "
удалит пробелы в конце строки, если какие-либо имена их содержат.