Nie ma „zasad” jako takich. Niektóre programy pobierają dane ze STDIN, a niektóre nie. Jeśli program może pobierać dane wejściowe ze STDIN, może być przesyłany potokowo, jeśli nie, nie może.
Zwykle możesz stwierdzić, czy program pobierze dane, myśląc o tym, co robi. Jeśli praca programu jest w jakiś sposób manipulować zawartość z pliku (np grep, sed, awketc.), to zwykle trwa wejściowe z stdin. Jeśli jego zadaniem jest manipulowanie sam plik (np mv, rm, cp) lub proces (np kill, lsof) lub powrotnej do informacji o czymś (np top, find, ps), to nie.
Innym sposobem myślenia na ten temat jest różnica między argumentami a danymi wejściowymi. Na przykład:
mv foo bar
W powyższym poleceniu mvnie ma danych wejściowych jako takich. Podano dwa argumenty. Nie wie ani nie obchodzi, co jest w żadnym z plików, po prostu wie, że to są jego argumenty i powinien nimi manipulować.
Z drugiej strony
sed -e 's/foo/bar/' < file
--- -- ------------ ----
| | | |-> input
| | |------------> argument
| |--------------------> option/flag/switch
|------------------------> command
Tutaj sedpodano dane wejściowe oraz argument. Ponieważ pobiera dane wejściowe, może je odczytać ze STDIN i może być przesyłane potokowo.
Staje się bardziej skomplikowane, gdy argumentem może być dane wejściowe. Na przykład
cat file
Oto fileargument, który został podany cat. Mówiąc ściślej, argumentem jest nazwa pliku file. Ponieważ jednak catjest to program, który manipuluje zawartością plików, jego wejściem jest wszystko, co jest w środku file.
Można to zilustrować za stracepomocą programu, który śledzi wywołania systemowe wykonywane przez procesy. Jeśli uruchomimy cat fooprzez strace, możemy zobaczyć, że plik foojest otwarty:
$ strace cat foo 2| grep foo
execve("/bin/cat", ["cat", "foo"], [/* 44 vars */]) = 0
open("foo", O_RDONLY)
Pierwszy wiersz powyżej pokazuje, że program /bin/catzostał wywołany, a jego argumentami były cati foo(pierwszym argumentem jest zawsze sam program). Później argument foozostał otwarty w trybie tylko do odczytu. Teraz porównaj to z
$ 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
Tutaj także lswziął siebie i foojako argumenty. Jednak nie ma openwywołania, argument nie jest traktowany jako dane wejściowe. Zamiast tego lswywołuje statbibliotekę systemową (co nie jest tym samym co statpolecenie), aby uzyskać informacje o pliku foo.
Podsumowując, jeśli uruchomione polecenie odczyta jego dane wejściowe, możesz przesłać do niego potokiem, jeśli nie, nie możesz.
pgrep,pkillikillallpoleceń.