it-swarm-ru.tech

Как передать вывод команды другим командам?

Пример:

ls | echo ничего не печатает (фактически пустая строка). Я ожидаю, что это напечатает список файлов.

ls | grep 'foo', с другой стороны, работает как положено (печатает файлы с именем 'foo').

В этих ситуациях я делаю что-то вроде: ls | while read OUT; do echo $OUT; done, но это довольно громоздко.

Почему конвейер работает с некоторыми командами, но не с другими? Как я могу обойти эту проблему?

81
Mihai Rotaru

Существует различие между аргументами командной строки и стандартным вводом. Канал соединит стандартный вывод одного процесса со стандартным вводом другого. Так

ls | echo

Подключает стандартный вывод ls к стандартному вводу эха. Хорошо верно? Что ж, echo игнорирует стандартный ввод и выводит свои аргументы командной строки (которых в данном случае нет) в свой собственный стандартный вывод. Выход: вообще ничего.

В этом случае есть несколько решений. Одним из них является использование команды, которая читает stdin и создает дамп в stdout, например, cat.

ls | cat

Будет «работать», в зависимости от вашего определения работы.

Но как насчет общего случая. Что вам действительно нужно, так это преобразовать стандартный вывод одной команды в аргументы командной строки другой. Как уже говорили другие, xargs в этом случае - канонический вспомогательный инструмент, считывающий аргументы командной строки для команды из своего стандартного ввода и создающий команды для запуска.

ls | xargs echo

Вы также можете преобразовать это, используя команду подстановки $()

echo $(ls)

Также будет делать то, что вы хотите.

Оба эти инструмента являются ядром сценариев Shell, вы должны изучить оба.

Для полноты, как вы указали в вопросе, другой базовый способ преобразования stdin в аргументы командной строки - встроенная в оболочку команда read. Он преобразует «слова» (слова, как определено в переменной IFS) во временную переменную, которую вы можете использовать при любом запуске команды.

115
Rich Homolka

ls | echo печатает только пустую строку, потому что echo не читает ничего; последняя команда конвейера на самом деле echo, которая печатает только пустую строку.

В общем-то:

a | b

гарантирует, что выходные данные a станут входными данными b. Я предлагаю вам прочитать раздел Pipelines в man bash.


Если вы действительно хотите использовать ls и echo вместе, вот несколько (довольно бесполезных) примеров:

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
18
cYrus

Если вы хотите echo, команда ls попробуйте:

ls | xargs echo

Это вызовет echo с выводом ls.

9
Nathan Fellman

Почему бы просто не использовать:

echo `ls`

Или намного безопаснее:

echo "`ls -lrt`"
3
Urbwzrd