使用管道的 Bash 语法问题

使用管道的 Bash 语法问题

我正在尝试将变量设置为程序(lynx)返回的值。我无法超越我使用哪个括号或方括号来实现我的目标。

我有这个:

DEBFILE=${(lynx -listonly -dump https://gridtracker.org/release.html) | grep .deb | grep nwjs | awk '{ print $2 }'}

我哪里会出轨。对我轻松一些。我已经有一段时间没有搞乱这个了。

我简化了语句以包含 URL。最终,我还想在该代码块中使用 URL 变量。

例如...

DEBFILE=${(lynx -listonly -dump ${GT_DOWNLOAD_LINK} ) | grep .deb | grep nwjs | awk '{ print $2 }'}

因为它已经在我的脚本开头附近定义了。

我知道这是一个语法问题,因为我将其分解为几行,将命令回显到文件,然后以这种方式将其读回到变量中。

这有效

echo $(lynx -listonly -dump https://gridtracker.org/release.html | grep .deb | grep nwjs) | awk '{ print $2 }' >> temp.txt
        DEBFILE=$(cat temp.txt)
        echo $DEBFILE

答案1

您确实存在嵌套语法错误,可能是由于对变量扩展和命令替换的混淆而引起的。

你想要实现的是命令替换,即你想分配给DEBFILE变量输出的一个命令。这是按如下方式完成的:

DEBFILE=$( your command )

${ ... }您在最初尝试中使用的语法是参数/变量扩展,您可以在其中“取消引用”其名称放在花括号中的 shell 变量。请注意,这${VARIABLE}与 基本相同$VARIABLE,因此对于您显示的第一个命令,您的 shell 会尝试查找一个变量,该变量的姓名(lynx -listonly -dump https://gridtracker.org/release.html) | grep .deb | grep nwjs | awk '{ print $2 }'并将其值赋给DEBFILE. (1)

实现目标的正确方法应该是

DEBFILE=$(lynx -listonly -dump https://gridtracker.org/release.html | grep .deb | grep nwjs | awk '{ print $2 }')

您可能可以用单个命令替换grep- grep-管道,这可能看起来像awkawk

DEBFILE=$(lynx -listonly -dump https://gridtracker.org/release.html | awk '/\.grep/ && /nwjs/ { print $2 }')

或者

DEBFILE=$(lynx -listonly -dump https://gridtracker.org/release.html | awk '(index($0,".deb") && index($0,"nwjs")) { print $2 }')

笔记您标记为“This Works”的代码基本上完全符合我的建议,只是有一个不必要的echo中间步骤,即将输出写入文件,并从中读回变量$DEBFILE

  • echo $(lynx ... | grep .deb | grep nwjs)具有相同的效果lynx ... | grep .deb | grep nwjs(但可能会引入不必要的空白重新格式化),因为它基本上使管道的控制台输出lynx ... | grep ... | grep ...成为 的参数echo,这将简单地将其打印到控制台(再次)。
  • 所以,echo $(lynx ... | grep .deb | grep nwjs) | awk '{ print $2 }'lynx ... | grep .deb | grep nwjs | awk '{ print $2 }'

(1)正如 Stéphane Chazelas 所指出的,ksh93实际上确实支持某种${ cmd; }形式的命令替换,但它要求命令以 a 结尾;,它不兼容 POSIX,并且 Bash 也不支持它。

相关内容