2010-09-16 13:40:08 +0000 2010-09-16 13:40:08 +0000
88
88

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

Пример:

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

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

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

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

Ответы (4)

123
123
123
2010-09-16 14:16:59 +0000

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

ls | echo

Подключает стандартный выход ls к стандартному входу эхо. Понятно? Ну, echo игнорирует стандартный вход и выдавливает свои аргументы командной строки - которых в данном случае нет - свой собственный stdout. Выход: совсем ничего.

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

ls | cat

Будет ‘работать’, в зависимости от того, какова ваша дефиниция работы.

А как же общий случай. На самом деле вы хотите преобразовать stdout одной команды в аргументы командной строки другой. Как говорили другие, xargs в данном случае является каноническим вспомогательным инструментом, чтение его командной строки аргументирует выполнение команды из stdin, а также построение команд для выполнения.

ls | xargs echo

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

echo $(ls)

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

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

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

19
19
19
2010-09-16 13:54:37 +0000

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

Обычно:

a | b

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


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

ls | xargs -L 1 echo
echo `ls`
for i in `ls` ; do echo $i ; done
13
13
13
2010-09-16 14:03:04 +0000

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

ls | xargs echo

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

3
3
3
2011-11-09 09:48:27 +0000

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

echo `ls`

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

echo "`ls -lrt`"