我尝试了三种不同的“别名”函数,通过给定参数从命令行显示图像。有人能告诉我为什么输入的处理方式与我仅将 URL 提供给最终命令时不同吗?
function xkcd() {pandoc -f html -t plain https://xkcd.com/"$1"/ | grep *.png | display;}
function xkcd() {pandoc -f html -t plain https://xkcd.com/"$1"/ | grep *.png | w3m;}
function xkcd() {pandoc -f html -t plain https://xkcd.com/"$1"/ | grep *.png | open;}
function xkcd() {pandoc -f html -t plain https://xkcd.com/"$1"/ | grep *.png | eog;}
#where $1 is a number in the range of values present in the site's structure
当我使用图像 URL 作为参数单独运行 w3m 时,它会弹出一个裁剪过的 imagemagick 小窗口,其中包含图像(该函数的预期结果)。当它从管道接收 URL 运行时(表面上),它会打开一个页面,上面只打印了 URL 文本。
运行显示也工作正常,然后使用管道出现错误:
display-im6.q16: no decode delegate for this image format `' @ error/constitute.c/ReadImage/575.
打开后给了我它的帮助对话框:
xdg-open - opens a file or URL in the user's preferred application
Synopsis
xdg-open { file | URL }
xdg-open { --help | --manual | --version }
Use 'man xdg-open' or 'xdg-open --manual' for additional info.
eog 为两者打开了一个空白窗口,因此在此过程中没有用。
我不知道我是否做错了什么,对管道期望太高,或者有一些我无法识别的简单语法错误,因为我仍在学习,但这让我发疯。
function xkcd() { pandoc -t https://xkcd.com/"$1" | grep ".png" | cat; }
按预期返回图像 URL。
function xkcd() { pandoc -t https://xkcd.com/"$1" | grep ".png" | echo; }
返回一个空白行,我猜这是问题的关键,但我希望有人可以向我解释或指出正确的方向,让我了解这里到底发生了什么?TIA。
PS:如果有帮助的话,在 debian bullseye 上使用 bash
答案1
命令行参数不是标准输入/输出。当您eog foobar
使用 URL 作为命令行参数运行时,它接收该参数的方式与您使用的方式完全不同echo foobar | eog
- 不像阅读将来自 stdin 的数据作为“文件”后,程序直接获得一个参数列表作为“argv”数组。
我们不期望程序会以相同的方式对待两者;事实上,大多数程序都应以相同的方式对待它们不同地。例如,ImageMagickdisplay
期望从 stdin 读取原始图像数据,而不是文件名,而 EoG 根本不关心 stdin。(当然,在您自己的示例中,grep
能够从 stdin 读取文本和从其命令行获取正则表达式模式。)
当您有一个管道并想将其输出用作程序的命令行参数时,最常见的方法是使用工具xargs
:
echo https://xkcd.com/1168/ | xargs -d '\n' w3m
或者,使用 shell 的$(…)
或`…`
运算符将程序的输出捕获到变量中:
url=$(pandoc this | grep that) && w3m "$url"
display "$(pandoc https://xkcd | grep '\.png')"
还要注意:1)grep
接受正则表达式,而不是 shell 通配符;2) 未加引号的通配符由 shell 扩展,不会以“原始”形式传递给程序,除非扩展失败。
因此,如果您使用| grep *.png
并在当前目录中拥有一些 PNG 文件,您的函数最终将运行| grep foo.png
,而不会产生正确的输出。
如果你引用该参数以防止扩展并使用| grep "*.png"
,它仍然不起作用 - 它甚至不是一个有效的正则表达式(在正则表达式中,*
是一个修饰符并且需要某物在它之前)。
您想使用其中之一grep ".*\.png"
或者仅仅grep "\.png"
使用代替。