Không có "quy tắc" nào như vậy. Một số chương trình lấy đầu vào từ STDIN, và một số thì không. Nếu một chương trình có thể lấy đầu vào từ STDIN, thì nó có thể được dẫn đến, nếu không, nó không thể.
Thông thường bạn có thể biết liệu một chương trình sẽ nhận đầu vào hay không bằng cách suy nghĩ về những gì nó làm. Nếu công việc của chương trình là bằng cách nào đó thao tác các nội dung của một tập tin (ví dụ như grep
, sed
, awk
vv), nó thường có đầu vào từ STDIN. Nếu công việc của mình là để thao tác các tập tin riêng của mình (ví dụ như mv
, rm
, cp
) hoặc một quá trình (ví dụ kill
, lsof
) hoặc thông tin trở về một cái gì đó (ví dụ top
, find
, ps
) sau đó nó không.
Một cách nghĩ khác về nó là sự khác biệt giữa các đối số và đầu vào. Ví dụ:
mv foo bar
Trong lệnh trên, mv
không có đầu vào như vậy. Những gì nó đã được đưa ra là hai đối số. Nó không biết hoặc quan tâm những gì trong một trong hai tệp, nó chỉ biết đó là những đối số của nó và nó nên thao túng chúng.
Mặt khác
sed -e 's/foo/bar/' < file
--- -- ------------ ----
| | | |-> input
| | |------------> argument
| |--------------------> option/flag/switch
|------------------------> command
Ở đây, sed
đã được đưa ra đầu vào cũng như một đối số. Vì nó nhận đầu vào, nó có thể đọc nó từ STDIN và nó có thể được dẫn đến.
Nó trở nên phức tạp hơn khi một đối số có thể là đầu vào. Ví dụ
cat file
Đây file
là lý lẽ đã được đưa ra cat
. Nói chính xác, tên tập tin file
là đối số. Tuy nhiên, vì cat
là một chương trình thao túng nội dung của các tệp, nên đầu vào của nó là bất cứ thứ gì bên trong file
.
Điều này có thể được minh họa bằng cách sử dụng strace
, một chương trình theo dõi các cuộc gọi hệ thống được thực hiện bởi các quy trình. Nếu chúng tôi chạy cat foo
qua strace
, chúng tôi có thể thấy rằng tệp foo
được mở:
$ strace cat foo 2| grep foo
execve("/bin/cat", ["cat", "foo"], [/* 44 vars */]) = 0
open("foo", O_RDONLY)
Dòng đầu tiên ở trên cho thấy rằng chương trình /bin/cat
đã được gọi và các đối số của nó là cat
và foo
(đối số đầu tiên luôn luôn là chính chương trình). Sau đó, đối số foo
được mở trong chế độ chỉ đọc. Bây giờ, so sánh điều này với
$ 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
Ở đây cũng vậy, ls
lấy chính nó và foo
làm đối số. Tuy nhiên, không có open
cuộc gọi, đối số không được coi là đầu vào. Thay vào đó, hãy ls
gọi stat
thư viện của hệ thống (không giống với stat
lệnh) để lấy thông tin về tệp foo
.
Tóm lại, nếu lệnh bạn đang chạy sẽ đọc đầu vào của nó, bạn có thể chuyển sang lệnh đó, nếu không, bạn không thể.
pgrep
,pkill
vàkillall
lệnh.