Создадим тестовый файл:

Создадим тестовый файл:

Я уже некоторое время борюсь с этой проблемой и был бы очень признателен, если бы кто-нибудь мог мне ее прояснить. Предположим, я пытаюсь объединить две команды. readlinkиcat

readlink Command output
$ readlink -f SUService.log
/cygdrive/c/SUService.log

Теперь, если я попробую что-то подобное (не получится)

$ readlink -f SUService.log | cat

Хотя что-то вроде этого будет работать

$ readlink -f SUService.log | xargs cat

Я хотел узнать, почему это так? Я прочиталэтотпост здесь, в котором у ОП был похожий вопрос иэтотпост, который пытается объяснить разницу между аргументом и вводом, однако я все еще не могу уложить в голове принятый ответ(ы). Насколько я понимаю, это readlinkвозвращает результат в stdout, который является экраном терминала, в то время как catхочет ввод в качестве аргумента. Это в свою очередь побуждает меня спросить, как мне узнать, может ли вывод команды (например, locate или readlink) работать как аргумент или нет для следующей команды? Я больше читал, и оказалось, что я хотел бы знать, когда мне следует использовать команду xarg?

решение1

Ваш пример довольно запутан.

Обычно вы не отправляете в cat просто так символы.

Обычно вы отправляете файл в cat.

Тем не менее, когда вы отправляете какие-либо символы в cat, он их выводит.

$ echo abc12123 | cat
abc12123

Обычно вы отправляете имя файла в cat

$ cat abc12123
cat: abc12123: No such file or directory

Обратите внимание, что сам cat по-разному обращается с забавными персонажами, переданными ему по конвейеру, и с теми, которые передаются ему в качестве параметра.

$ cat b.b
textofb.b

$ echo b.b | cat
b.b

$ cat b.b
textofb.b

Я буду использовать более простой пример, чем ваш.

$ echo b.b | xargs cat
textofb.b

см., он выводит содержимое bb, поскольку asdfasdfs | xargs cat, отправит вывод asdfasdfs в качестве параметра в cat.

Так

echo b.b | xargs cat   
=  
cat b.b

В то время как echo b.b | cat это не то же самое, чтоcat b.b

решение2

Следующая команда делаетнетфейл. Он просто делает то, чего вы не ожидали:

readlink -f SUService.log | cat

Когда catзадан stdin, он копирует его в stdout. Он не ищет в нем имена файлов.

В качестве альтернативы будет выполнено чтение из указанного файла:

cat "$(readlink -f SUService.log)"

xargsтакже поместит имя в catкомандную строку, что даст тот же результат:

readlink -f SUService.log | xargs cat

решение3

Взгляните на страницы руководства по cat и xargs, чтобы узнать, что они делают.

man cat

cat - concatenate files and print on the standard output

И:

man xargs

xargs - build and execute command lines from standard input

Вот небольшая демонстрация

Создадим тестовый файл:

echo "a" > test
echo "b" >> test
echo "c" >> test

кот

cat test

Читает файл и выдает:

a
b
c

эхо | кот

echo test | cat

Согласно man cat, это делает то же самое, что:

echo test | cat -

Который передается testв stdin кошки и сообщает ей, что нужно читать из stdin.

эхо | xargs кот

echo test | xargs cat

Генерирует и выполняет следующую команду:

cat test

Результат этого мы уже показали.

Если мы побежим

<test xargs -n1 cat

Xargs видит это при вводе:

a
b
c

И он генерирует следующие команды:

cat a
cat b
cat c

Что должно привести к трем ошибкам, поскольку эти файлы не существуют.

Почему -n1?

Согласно man xargs, -n1xargs указывает использовать один аргумент (считанный из stdin) в каждой генерируемой им команде.

Если вместо этого мы используем -n2, то сгенерируем следующее, в котором используется до двух параметров на команду:

cat a b
cat c

А если мы используем -n3или выше, или просто опускаем -n:

< test xargs cat

Мы получаем:

cat a b c

Связанный контент