Интересно, что когда мы должны использовать конвейер, а когда нет.
Скажем, например, чтобы убить определенный процесс, который обрабатывает PDF-файлы, следующее не будет работать с использованием конвейера:
ps aux | grep pdf | awk '{print $2}'|kill
Вместо этого мы можем сделать это только следующими способами:
kill $(ps aux| grep pdf| awk '{print $2}')
или
ps aux | grep pdf | awk '{print $2}'| xargs kill
Согласно man bash
(версия 4.1.2
):
The standard output of command is connected via a pipe to the standard input of command2.
Для приведенного выше сценария:
- стандарт
grep
является стандартнымps
. Это работает. - стандарт
awk
является стандартнымgrep
. Это работает. - стандарт
kill
является стандартнымawk
. Это не работает
Stdin следующей команды всегда получает ввод из stdout предыдущей команды.
- Почему это не работает с
kill
илиrm
? - Что различались
kill
,rm
вход сgrep
,awk
входом? - Есть ли правила?
pgrep
,pkill
иkillall
команде.pgrep
и остальные могут достичь этого отлично :)Ответы:
Существует два распространенных способа ввода данных в программы:
kill
использует только аргументы командной строки. Он не читает из STDIN. Программы любятgrep
иawk
читают из STDIN (если имена файлов не указаны в качестве аргументов командной строки) и обрабатывают данные в соответствии с их аргументами командной строки (шаблон, операторы, флаги, ...).Вы можете передавать только STDIN других процессов, а не аргументы командной строки.
Общее правило состоит в том, что программы используют STDIN для обработки произвольного количества данных. Все дополнительные входные параметры или, если их вообще мало, передаются аргументами командной строки. Если командная строка может быть очень длинной, например, для длинных
awk
программных текстов, часто есть возможность прочитать их из дополнительных программных файлов (-f
опцияawk
).Чтобы использовать STDOUT программ в качестве аргументов командной строки, используйте
$(...)
или в случае большого количества данныхxargs
.find
может также это напрямую с-exec ... {} +
.Для полноты: чтобы записать аргументы командной строки в STDOUT, используйте
echo
.источник
gzip
в ОПИСАНИИ не говорится, что в качестве входных данных необходимо указать имя файла. Я смотрю, есть ли более систематический способ определить это.xargs
Точно не позволит вам «передать аргументы командной строки»?xargs
. Он вызывает команду при необходимости более одного раза (размер командной строки ограничен) и имеет множество других опций.Это интересный вопрос, и он касается части философии Unix / Linux.
Итак, в чем разница между программами , такими как
grep
,sed
,sort
с одной стороны , иkill
,rm
,ls
с другой стороны? Я вижу два аспекта.Фильтр аспект
Первый вид программ также называется фильтрами . Они принимают входные данные, либо из файла, либо из STDIN, модифицируют его и генерируют некоторый вывод, в основном в STDOUT. Они предназначены для использования в конвейере с другими программами в качестве источников и назначений.
Второй вид программ действует на вход, но вывод, который они дают, часто не связан с вводом.
kill
не имеет выхода, когда он работает регулярно, и не делаетls
. Просто есть возвращаемое значение, чтобы показать успех. Обычно они не принимают входные данные от STDIN, но в основном выдают выходные данные для STDOUT.Для подобных программ
ls
аспект фильтра не работает так хорошо. Конечно, он может иметь вход (но не нужен), и выход тесно связан с этим входом, но он не работает как фильтр. Однако для таких программ другой аспект все еще работает:Семантический аспект
Для фильтров их ввод не имеет семантического значения . Они просто читают данные, изменяют данные, выводят данные. Не имеет значения, является ли это списком числовых значений, некоторыми именами файлов или исходным кодом HTML. Значение этих данных дается только кодом, который вы предоставляете фильтру: регулярное выражение
grep
, правилаawk
или программа Perl.Для других программ, таких как
kill
илиls
, их ввод имеет значение , обозначение .kill
ожидает номера процессов,ls
ожидает имена файлов или путей. Они не могут обрабатывать произвольные данные и не предназначены для этого. Многие из них даже не нуждаются ни в каком входе или параметрах, какps
. Они обычно не читают из STDIN.Вероятно, можно объединить эти два аспекта. Фильтр - это программа, входные данные которой не имеют смыслового значения для программы.
Я уверен, что где-то читал об этой философии, но в данный момент я не помню никаких источников, извините. Если у кого-то есть источники, пожалуйста, не стесняйтесь редактировать.
источник
Здесь нет «правил» как таковых. Некоторые программы принимают входные данные от STDIN, а некоторые нет. Если программа может принимать входные данные из STDIN, она может быть передана, если нет, то не может.
Обычно вы можете сказать, будет ли программа принимать данные, думая о том, что она делает. Если работа программы заключается в том, чтобы каким-либо образом манипулировать содержимым файла (например
grep
,sed
иawk
т. Д.), Она обычно принимает входные данные из STDIN. Если его работа состоит в том, чтобы манипулировать сам файл (напримерmv
,rm
,cp
) или процесс (напримерkill
,lsof
) или для возврата информации о чем - либо (напримерtop
,find
,ps
) , то это не делает.Другой способ думать об этом - это разница между аргументами и вводом. Например:
В приведенной выше команде
mv
нет ввода как такового. То, что было дано, это два аргумента. Он не знает или не заботится о том, что находится в любом из файлов, он просто знает, что это его аргументы, и он должен манипулировать ими.С другой стороны
Здесь
sed
был дан ввод, а также аргумент. Так как он принимает ввод, он может читать его из STDIN, и он может быть передан по каналу.Это становится более сложным, когда аргумент может быть входным. Например
Вот
file
аргумент, который был данcat
. Чтобы быть точным, имя файлаfile
является аргументом. Однако, посколькуcat
это программа, которая манипулирует содержимым файлов, ее вход - это то, что находится внутриfile
.Это можно проиллюстрировать с
strace
помощью программы, которая отслеживает системные вызовы, сделанные процессами. Если мы запустимcat foo
черезstrace
, мы увидим, что файлfoo
открыт:Первая строка выше показывает, что программа
/bin/cat
была вызвана и ее аргументы былиcat
иfoo
(первым аргументом всегда является сама программа). Позже аргументfoo
был открыт в режиме только для чтения. Теперь сравните это сВот и
ls
взял себя и вfoo
качестве аргументов. Однакоopen
вызова нет , аргумент не обрабатывается как ввод. Вместо этогоls
вызывает системнуюstat
библиотеку (которая отличается отstat
команды), чтобы получить информацию о файлеfoo
.Таким образом, если команда, которую вы запускаете, будет читать входные данные, вы можете передать ее, а если нет, то не сможете.
источник
kill
иrm
не нужен STDIN.Для
kill
иrm
, пользователи предоставляют свою настраиваемую информацию в качестве аргумента и$(cmd)
помогают взять STDOUTcmd
и преобразовать ее в информационный аргумент.Для
grep
иawk
пользователи предоставляют аргументы и, кроме того, такжеSTDIN
или обычный файл, который будет обрабатываться командой.STDIN
может быть передан с конвейером|
или вручную.Прочитайте руководство или исходные коды. И если вы не найдете ничего, что вам нужно, вы можете сделать простой, но, возможно, опасный тест:
Просто введите интересующую вас команду с аргументами, которые вы уже поняли, и посмотрите, приостановлена ли команда (ничего не происходит). Если он приостановился, он фактически ожидает STDIN (вы можете попробовать
cat
иecho
увидеть другое). Вы вводите вручную,Ctrl-D
и команда идет вперед (показать результаты или ошибки) и возвращает. Такая команда нуждается в STDIN в этой ситуации (с аргументами, которые вы предоставляете).Одна и та же команда может не нуждаться в STDIN в разных ситуациях (например,
cat
ожидает STDIN, ноcat file.txt
не).источник