我的理解是,pipe
例如,
command1 | command2
Run Code Online (Sandbox Code Playgroud)
将 的输出发送command1
到command2
。但是,我原以为这会起作用:
echo "tmp.pdf" | evince
Run Code Online (Sandbox Code Playgroud)
但事实并非如此。echo "tmp.pdf"
被发送的输出在哪里?
你的理解是正确的。该序列command1 | command2
将 的输出 (STDOUT) 发送command1
到 的输入 (STDIN) command2
。您的evince
命令不起作用的原因是evince
不接受 STDIN 上的文件名。
管道将其输出发送到打开它以供读取的程序。在 shell 管道中,这是管道符号右侧的程序,即evince
在您的示例中。
您将文件名发送tmp.pdf
到其标准输入上的 evince。然而 evince 并不关心它的标准输入。就像每个作用于文件的程序一样,它希望文件名作为命令行参数传递;如果你没有在命令行上传递文件名,它会提供打开一个文件。命令行参数与标准输入不同。人类有不同的输入器官,可以输入不同的东西(例如,你不能通过鼻子进食),类似的程序也有不同的接收信息的方式,用于不同的目的。
Evince 可以在标准输入上读取文件(不是文件名):evince /dev/stdin <"tmp.pdf"
. (这可能不适用于所有 Unix 变体。)文件名的/dev/stdin
意思是“您已经在标准输入上打开的任何文件”。用于命令行的程序通常在没有给出文件名时读取它们的标准输入,但 GUI 程序通常不会。Evince 只能以这种方式打开常规文件,而不是来自管道的数据(例如cat tmp.pdf | evince /dev/stdin
,不起作用),因为在页面之间导航时,它需要能够在文件中来回查找。