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
, awk
Ecc.), 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, mv
non 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, file
l'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 strace
un programma che tiene traccia delle chiamate di sistema effettuate dai processi. Se corriamo cat foo
via 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/cat
stato chiamato e i suoi argomenti erano cat
e foo
(il primo argomento è sempre il programma stesso). Successivamente, l'argomento è foo
stato 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 ls
preso se stesso e foo
come argomenti. Tuttavia, non vi è alcuna open
chiamata, l'argomento non viene trattato come input. Al contrario, ls
le chiamate del sistema stat
biblioteca (che non è la stessa cosa del stat
comando) 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
,pkill
ekillall
comandi.