Sen*_*nha 12 scripting pipe shell-script
在观看有关管道恶作剧的视频后,我尝试了以下命令。
man -k . | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf | zathura -
Run Code Online (Sandbox Code Playgroud)
它基本上将联机帮助页列表打印到 dmenu 供用户选择其中一个,然后使用 xargs 运行man -Tpdf %(从 xargs 的输入打印到标准输出联机帮助页 git 的 pdf)并将 pdf 传递给 pdf 阅读器(zathura )。
问题是(如您在视频中看到的)pdf 阅读器甚至在我在 dmenu 中选择一个联机帮助页之前就已启动。如果我单击 Esc 并选择无,则 pdf 阅读器仍处于打开状态,根本不显示任何文档。
如何使 pdf 阅读器(以及管道链中的任何其他命令)仅在其输入到达文件结尾或接收到输入时才运行?或者,或者,在链接的命令之一返回非零退出状态后,如何使管道链停止(以便如果 dmenu 返回未选择选项的错误,则不会运行以下命令)?
Kam*_*ski 13
如何使 pdf 阅读器(以及管道链中的任何其他命令)仅在其输入到达文件结尾或接收到输入时才运行?
有ifne(在 Debian 中它在moreutils包中):
ifne当且仅当标准输入不为空时运行以下命令。
在你的情况下:
… | ifne zathura -
Run Code Online (Sandbox Code Playgroud)
管道中的所有命令几乎同时启动。只有通过管道的 I/O 才能同步它们。此外,管道只能保存管道缓冲区允许的信息。
因此,您无法避免运行管道的一个阶段,因为
相反,在让管道完成的同时将输出写入文件。然后使用该文件。
示例(作为带一个参数的函数):
myman () {
tmpfile=$( mktemp )
if man -k "$1" | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf >"$tmpfile" && [ -s "$tmpfile" ]
then
zathura "$tmpfile"
fi
rm -f "$tmpfile"
}
Run Code Online (Sandbox Code Playgroud)
zathura如果管道失败(xargs部分返回非零)或生成的文件为空,这也不会运行程序。
在bashshell 中,您可能还想设置pipefailshell 选项set -o pipefail以让管道返回管道中失败的第一个命令的退出状态。你会想要创建tmpfile变量local:
myman () {
local tmpfile=$( mktemp )
if [ -o pipefail ]; then
set -o pipefail
trap 'set +o pipefail' RETURN
fi
if man -k "$1" | dmenu -l 20 | awk '{print $1}' | xargs -r man -Tpdf >"$tmpfile"
then
zathura "$tmpfile"
fi
rm -f "$tmpfile"
}
Run Code Online (Sandbox Code Playgroud)
这会设置pipefail函数持续时间的选项(如果尚未设置),然后在需要时取消设置。它摆脱了-s对输出文件的测试。
PDF 文件应该是可查找的;任何 pdf 查看器都必须首先查看预告片,然后从那里跳转到外部参照表的偏移量。
由于管道不可搜索,zathura因此使用了一种混淆技巧,它将所有输入复制到一个临时文件中,然后像往常一样使用该临时文件。这种“聪明”的伎俩正在制造虚假的希望,并导致人们认为 pdf 文件是可流式传输的。
但是不管怎么说,zathura确实不等待EOF显示文档之前,您不必为实现这一目标hapen做任何事情:
(sleep 10; cat file.pdf) | zathura -
# will really show the content of file.pdf after 10 seconds
Run Code Online (Sandbox Code Playgroud)
问题是,zathura如果文件正常,则无法选择仅打开窗口,如果情况不是这样,则退出并显示错误 - 它只会留在那里,好像一切正常:
$ dd if=file.pdf bs=50000 count=1 status=none | zathura -
error: could not open document # its window still hanging around showing nothing
$ echo $?
0 # really?
Run Code Online (Sandbox Code Playgroud)
因此,即使您自己将输出重定向到临时文件,并且仅zathura在一切正常的情况下才运行,也不能保证如果zathura出于某种原因不喜欢输出,用户将不会看到黑色窗口.
顺便提一句,
man -X man
Run Code Online (Sandbox Code Playgroud)
将在带有 的 X11 窗口中显示联机帮助页gxditview,即使它看起来直接来自 '70 ;-)
而且,当然,您始终可以使用:
... | xargs xterm -e man
Run Code Online (Sandbox Code Playgroud)
除了许多其他增强功能外,它还可以让您在搜索和正确的文本选择中使用正则表达式。
| 归档时间: |
|
| 查看次数: |
1526 次 |
| 最近记录: |