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