Не існує "правил" як таких. Деякі програми приймають дані від 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
команді.