Связь между процессами запуска оболочки и средой родительского процесса

Обычно вы хотите использовать 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=" " удалит пробелы в конце строки, если какие-либо имена их содержат.

1
13.04.2017, 15:36
0 ответов

Теги

Похожие вопросы