管道将其输出发送到哪里?

管道将其输出发送到哪里?

我的理解是pipe,例如,

command1 | command2 

command1将的输出发送至command2。但是,我希望这能起作用:

echo "tmp.pdf" | evince 

但事实并非如此。echo "tmp.pdf"发送的输出在哪里?

答案1

你的理解是正确的。该序列command1 | command2将 的输出 (STDOUT) 发送command1到 的输入 (STDIN) command2。您的evince命令不起作用的原因是它evince不接受 STDIN 上的文件名。

答案2

管道将其输出发送到打开它以供读取的程序。在 shell 管道中,这是管道符号右侧的程序,即evince在您的示例中。

您正在发送文件名tmp.pdf以在其标准输入上显示。然而 evince 并不关心它的标准输入。与每个作用于文件的程序一样,它期望文件名作为命令行参数传递;如果您不在命令行上传递文件名,它会提供打开文件的功能。命令行参数与标准输入不同。人类有不同的输入器官来输入不同的东西(例如,你不能通过鼻子吃东西),同样,程序有不同的方式来接收用于不同目的的信息。

Evince 可以阅读文件(不是文件名)在标准输入上:evince /dev/stdin <"tmp.pdf". (这可能不适用于所有 Unix 变体。)文件名的/dev/stdin意思是“您已经在标准输入上打开的任何文件”。用于命令行的程序通常在没有给出文件名的情况下读取其标准输入,但 GUI 程序通常不会。 Evince 只能以这种方式打开常规文件,而不能打开来自管道的数据(例如cat tmp.pdf | evince /dev/stdin不起作用),因为它需要能够在页面之间导航时在文件中来回查找。

答案3

正如我最近自己意识到的那样,您可以按如下方式绕过这个问题。首先使用locate命令查找您希望在evince中打开的文件的路径。然后将此结果作为参数传递到evince中。假设您的文件名是abc_xyz.pdf并且您希望打开它。然后你就可以做- evince "$(sudo locate xyz | grep abc)".请注意,如果您的 pdf 文件的名称包含空格,那么您需要双引号 The $(sudo locate xyz | grep abc) Reason Why I am using another code (piped with sudo locate xyz) iegrep abc是为了进一步过滤结果。但这里有一个问题,那就是,您需要通过发出不断更新locate sudo updatedb。假设您将 pdf 的位置更改为某个新目录,然后locate 将无法找到 itz 新位置,因为 itz 数据库尚未更新。但是您可以使用带有“and”条件的“find”命令来完成实时搜索的工作。例如你可以这样做-

evince "$(find ~/ -iname "*abc*" -a -iname "*xyz*" -type f)"

并将其作为参数传递给 evince.here 参数-iname用于不区分大小写的搜索,并且-a是和条件。-type f只会返回文件。

相关内容