在观看有关管道恶作剧的视频后,我尝试了以下命令。
man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -
它基本上将手册页列表打印到 dmenu 供用户选择其中一个,然后它使用 xargs 运行man -Tpdf %
(从 xargs 的输入打印到标准输出手册页 git 的 pdf)并将 pdf 传递给 pdf 阅读器(zathura )。
问题是(正如您在视频中看到的那样)pdf 阅读器甚至在我在 dmenu 中选择一个联机帮助页之前就开始了。如果我单击 Esc 并选择无,pdf 阅读器仍然打开,根本没有显示任何文档。
如何使 pdf 阅读器(以及管道链中的任何其他命令)仅在其输入到达文件末尾或完全接收到输入时运行?或者,或者,如何使管道链在其中一个链接命令返回非零退出状态后停止(这样如果 dmenu 由于未选择选项而返回错误,则以下命令不会运行)?
有
ifne
(在 Debian 中它在moreutils
包中):在你的情况下:
管道中的所有命令几乎同时启动。只有管道上的 I/O 才能同步它们。此外,管道只能保存管道缓冲区允许的信息。
因此,您无法避免运行管道的一个阶段,因为
相反,在让管道完成的同时将输出写入文件。然后使用该文件。
示例(作为一个接受一个参数的函数):
zathura
如果管道失败(xargs
返回非零的部分)或生成的文件为空,这也不会运行程序。在
bash
shell 中,您还可以设置pipefail
shell 选项,set -o pipefail
以使管道返回失败的管道中第一个命令的退出状态。你会想要使tmpfile
变量local
:如果尚未设置,这将设置
pipefail
函数持续时间的选项,然后在需要时取消设置。它摆脱了-s
对输出文件的测试。Pdf 文件应该是可搜索的;任何 pdf 查看器都必须首先查看预告片,然后从那里跳转到外部参照表的偏移量。
由于管道不可搜索,
zathura
因此使用了混淆技巧,将所有输入复制到临时文件,然后像往常一样使用该临时文件。这种“聪明”的把戏正在制造虚假的希望,并导致人们认为 pdf 文件是可流式传输的。但无论如何,在显示文档之前
zathura
确实会等待 EOF,您无需为此做任何事情:问题是
zathura
没有选项只能在文件正常的情况下打开窗口,如果不是这种情况则退出并出现错误 - 它只会留在那里,就好像一切正常:因此,即使您自己将输出重定向到临时文件,并且仅
zathura
在一切正常时才运行,也不能保证如果zathura
由于某种原因不喜欢输出,用户将不会看到黑色窗口.顺便提一句,
将在 X11 窗口中显示联机帮助页
gxditview
,即使它看起来直接来自 '70 ;-)而且,当然,您总是可以使用:
除了许多其他增强功能外,它还允许您在搜索和正确的文本选择中使用正则表达式。