Здесь нет «правил» как таковых. Некоторые программы принимают входные данные от STDIN, а некоторые нет. Если программа может принимать входные данные из STDIN, она может быть передана, если нет, то не может.
Обычно вы можете сказать, будет ли программа принимать данные, думая о том, что она делает. Если работа программы заключается в том, чтобы каким-либо образом манипулировать содержимым файла (например grep, sedи awkт. Д.), Она обычно принимает входные данные из STDIN. Если его работа состоит в том, чтобы манипулировать сам файл (например mv, rm, cp) или процесс (например kill, lsof) или для возврата информации о чем - либо (например top, find, ps) , то это не делает.
Другой способ думать об этом - это разница между аргументами и вводом. Например:
mv foo bar
В приведенной выше команде mvнет ввода как такового. То, что было дано, это два аргумента. Он не знает или не заботится о том, что находится в любом из файлов, он просто знает, что это его аргументы, и он должен манипулировать ими.
С другой стороны
sed -e 's/foo/bar/' < file
--- -- ------------ ----
| | | |-> input
| | |------------> argument
| |--------------------> option/flag/switch
|------------------------> command
Здесь sedбыл дан ввод, а также аргумент. Так как он принимает ввод, он может читать его из STDIN, и он может быть передан по каналу.
Это становится более сложным, когда аргумент может быть входным. Например
cat file
Вот fileаргумент, который был дан cat. Чтобы быть точным, имя файла fileявляется аргументом. Однако, поскольку catэто программа, которая манипулирует содержимым файлов, ее вход - это то, что находится внутри file.
Это можно проиллюстрировать с straceпомощью программы, которая отслеживает системные вызовы, сделанные процессами. Если мы запустим cat fooчерез strace, мы увидим, что файл fooоткрыт:
$ strace cat foo 2| grep foo
execve("/bin/cat", ["cat", "foo"], [/* 44 vars */]) = 0
open("foo", O_RDONLY)
Первая строка выше показывает, что программа /bin/catбыла вызвана и ее аргументы были catи foo(первым аргументом всегда является сама программа). Позже аргумент fooбыл открыт в режиме только для чтения. Теперь сравните это с
$ strace ls foo 2| grep foo
execve("/bin/ls", ["ls", "foo"], [/* 44 vars */]) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
write(1, "foo\n", 4foo
Вот и lsвзял себя и в fooкачестве аргументов. Однако openвызова нет , аргумент не обрабатывается как ввод. Вместо этого lsвызывает системную statбиблиотеку (которая отличается от statкоманды), чтобы получить информацию о файле foo.
Таким образом, если команда, которую вы запускаете, будет читать входные данные, вы можете передать ее, а если нет, то не сможете.
pgrep,pkillиkillallкоманде.