Non ci sono "regole" in quanto tali. Alcuni programmi ricevono input da STDIN, altri no. Se un programma può ricevere input da STDIN, può essere reindirizzato, in caso contrario, non può.
Normalmente puoi dire se un programma prenderà input o meno pensando a cosa fa. Se il lavoro del programma è in qualche modo manipolare il contenuto di un file (ad es grep. sed, awkEcc.), Normalmente riceve input da STDIN. Se il suo compito è manipolare il file stesso (ad es mv. rm, cp) O un processo (ad es kill. lsof) O restituire informazioni su qualcosa (ad es top. find, ps) , Non funziona.
Un altro modo di pensarci è la differenza tra argomenti e input. Per esempio:
mv foo bar
Nel comando sopra, mvnon ha input in quanto tale. Ciò che è stato dato sono due argomenti. Non sa né si preoccupa di cosa c'è in nessuno dei file, sa solo che questi sono i suoi argomenti e dovrebbe manipolarli.
D'altro canto
sed -e 's/foo/bar/' < file
--- -- ------------ ----
| | | |-> input
| | |------------> argument
| |--------------------> option/flag/switch
|------------------------> command
Qui, sedè stato dato input e un argomento. Poiché accetta input, può leggerlo da STDIN e può essere reindirizzato.
Diventa più complicato quando un argomento può essere l'input. Per esempio
cat file
Ecco, filel'argomento che è stato dato cat. Per essere precisi, il nome del file fileè l'argomento. Tuttavia, poiché catè un programma che manipola il contenuto dei file, il suo input è quello che c'è dentro file.
Questo può essere illustrato usando straceun programma che tiene traccia delle chiamate di sistema effettuate dai processi. Se corriamo cat foovia strace, possiamo vedere che il file fooè aperto:
$ strace cat foo 2| grep foo
execve("/bin/cat", ["cat", "foo"], [/* 44 vars */]) = 0
open("foo", O_RDONLY)
La prima riga sopra mostra che il programma è /bin/catstato chiamato e i suoi argomenti erano cate foo(il primo argomento è sempre il programma stesso). Successivamente, l'argomento è foostato aperto in modalità di sola lettura. Ora, confronta questo con
$ 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
Anche qui, ha lspreso se stesso e foocome argomenti. Tuttavia, non vi è alcuna openchiamata, l'argomento non viene trattato come input. Al contrario, lsle chiamate del sistema statbiblioteca (che non è la stessa cosa del statcomando) per ottenere informazioni sul file foo.
In breve, se il comando che stai eseguendo leggerà il suo input, puoi inoltrarlo, in caso contrario, non puoi.
pgrep,pkillekillallcomandi.