xargs
выполняет собственную специальную обработку своего ввода.
Он обрабатывает все последовательности символов новой строки и пробелов (, по крайней мере, пробела и табуляции, а в некоторых реализациях )больше как разделители, игнорирует начальные и конечные символы и обрабатывает кавычки по-своему :'...'
, "..."
и \
можно использовать для заключения в кавычки, но иначе, чем в синтаксисе sh
(и "..."
, и '...'
являются сильными кавычками, но не могут содержать новую строку, а \newline
является буквальным переводом строки вместо продолжения строки ).
Итак, при вводе типа:
"foo \ bar" 'x'\
y
xargs
генерирует два аргумента foo \ bar
и x<newline>y
.
Подстановка команды (как в архаичной `...`
, так и в современной $(...)
формах )без кавычек в контекстах списка в оболочках POSIX — это оператор split+glob. Ввод разбивается на $IFS
символов с использованием сложных правил, а полученные слова подвергаются генерации имени файла . Там вообще нет обработки котировок.
При вводе типа
"a* b"
Со значением по умолчанию$IFS
(SPC, TAB, NL ),он генерирует слово "a*
, которое далее расширяется до списка имен файлов в текущем каталоге, начинающихся с "a
и слова b"
.
Командная строка типа:
cmd "a* b"
cmd2 "x\"y"
— это код в синтаксисе оболочки. В синтаксисе оболочки пробелы, новые строки и кавычки также имеют особое значение и интерпретируются по-разному для xargs
. Приведенный выше код анализируется как две команды, так как команды разделяются новой строкой, cmd "a* b"
анализируется как два слова:cmd
и a* b
, поскольку слова разделяются пробелом, а "..."
является оператором кавычек оболочки, который предотвращает *
и SPC внутри от особого обращения... и т. д.
Чтобы выполнить токенизацию так же, как это делает оболочка, zsh
имеет квалификатор z
glob для этого (обратите внимание, что zsh по умолчанию не соответствует POSIX, поскольку он разделяет только, а не разделяет + glob при отсутствии кавычек. подстановки команд в контекстах списка ), а также квалификатор Q
glob для удаления одного уровня цитирования. В этой оболочке вы можете сделать:
output_of_cmd=$(find...) # no split+glob here as we're assigning to
# scalar variable. It's not a list context
words=("${(Q@)${(z)output_of_cmd}}") # array assignment
your-app "${words[@]}"