Если у меня есть каталог, содержащий некоторые файлы, имена которых имеют пробелы, например
$ ls -1 dir1
file 1
file 2
file 3
Я могу успешно скопировать их все в другой каталог, например так:
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
Однако выходные данные find dir1 -mindepth 1
содержат неэкранированные пробелы:
$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3
Если я использую print0
вместо print
, вывод все еще содержит неэкранированные пробелы:
$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3
Чтобы скопировать эти файлы вручную cp
, мне нужно было бы избежать пробелов; но кажется, что в этом нет необходимости, когда cp
приходят аргументы find
, независимо от того, использую я +
или \;
в конце команды.
В чем причина этого?
find..exec
может обрабатывать странные имена файлов самостоятельно ..Вопрос состоит из двух частей:
find
управлять с программами обработки вызовов с использованием-exec
не сталкиваясь с проблемами пространств , вложенных в именах файлов, и-print0
вариант?Во-первых,
find
это системный вызов, фактически один из группы связанных вызовов, называемых «exec» . Он передает имя файла в качестве аргумента непосредственно этому вызову, который затем передается напрямую (после создания нового процесса) без потери информации о имени файла.POSIX
find
особенность+
объясняется следующим образом , в обосновании :Это « в частности
-print0
, первичный» относится к GNUfind
иxargs
которые решают эту проблему по-другому. Это также поддерживается FreeBSDfind
иxargs
. Если вы добавили-0
опцию (см. Страницу руководства ) кxargs
вызову, то эта программа принимает строки, оканчивающиеся символами «нулевой байт». В свою очередьxargs
вызывает exec -functions для выполнения своей работы. Основное различие между-print0
и-0
особенности по сравнению с+
особенностью является то , что бывший передает имена файлов через трубу, а второй нет. Разработчики находят применение практически для любой функции; трубы не являются исключением.Вернемся к примеру OP, в котором используется
-t
опцияcp
: которая не найдена в POSIX cp . Скорее, это расширение (также называемое «нестандартной функцией»), предоставляемое GNU cp .-0
Расширениеxargs
не улучшит этот пример, но есть и другие случаи , когда могут быть эффективно использованы по поддержанию в виду , что есть портативная альтернатива+
, которая GNUfind
принимает.источник
( Это должен быть комментарий, но он слишком большой. )
Для тех, кто любит пробовать вещи:
Создайте скрипт, в котором перечислены переданные позиционные параметры, вызовите его
list_positional_parameters.sh
.Запустите
find
его в некотором каталоге $ dir:Как и ожидалось, во всех вызовах есть только один параметр - имя файла, есть ли в его имени пробелы или нет.
источник
printf
лайкprintf '"%s"\n' "$@"
для распечатки всех указанных позиционных аргументов для визуальной проверки.