如何防止 bash 命令替换输出被转义?

如何防止 bash 命令替换输出被转义?

我尝试在 bash 脚本中使用命令替换来基于变量输出重定向符号,如下所示:

IS_VERBOSE=false
curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

也就是说,如果冗长,请添加-i开关,否则,丢弃标准输出中的所有内容。问题是当IS_VERBOSE为 false 时,我的命令变成

curl $BLAH \> /dev/null

更一般地说,命令替换会转义字符> >> & | # $和可能的其他字符。如何使用命令替换输出这些符号而不转义?

答案1

替换发生后(顺便说一句,POSIX 中只能针对任何 ">" 之前的左侧),不再评估是否有 ">",因此您设想的方法将不起作用。

如果您不关心 POSIX 一致性(毕竟您将其标记为“bash”),您仍然可以通过动态设置右侧来找到解决方案,但我个人会采用完全不同的方法;看一下下面的文章,详细介绍了基于自定义文件描述符的详细/静默模式:https://stackoverflow.com/a/20942015/2261442

该帖子的代码摘录显示了它的样子:

# Some confirmations:
printf "%s\n" "This message is seen at verbosity level 3 and above." >&3
printf "%s\n" "This message is seen at verbosity level 4 and above." >&4
printf "%s\n" "This message is seen at verbosity level 5 and above." >&5

答案2

我知道这并不能解决你的逃避问题(我还不确定是否可能),但来自男子卷曲,这将实现您想要做的事情:

BLAH=localhost

IS_VERBOSE=true
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS=""

curl $BLAH -s $OPTIONS
    <html>
    <p>hi</p>
    </html>

IS_VERBOSE=false
OPTIONS="-o /dev/null"
$IS_VERBOSE && OPTIONS="-i"

curl $BLAH -s $OPTIONS

后者什么也不输出。并且对不同 shell(bash、sh 等)的依赖较少,因此更加可移植。

答案3

根据 bash 手册,shell 扩展的顺序是大括号扩展、波形符扩展、参数和变量扩展、命令替换、算术扩展、分词和路径名扩展。还指出重定向发生在命令执行之前 - 即在 shell 扩展之后。因此,这样的命令是有道理的:

redir='>'
echo value $redir file

echo value $(echo '>') file

会放价值在文件中文件

不幸的是,情况并非如此,因为首先解析命令行并且重定向令牌是仅有的现阶段已确定。稍后,在执行命令之前,将根据这些令牌执行重定向。

eval curl $BLAH $( $IS_VERBOSE && echo '-i' || echo '> /dev/null' )

通过重新解析命令来工作,从而识别重定向,但它也执行 shell 的扩展,这使用起来有点棘手,并且可能会导致意外的行为。

笔记:>$varbash 中对和有特殊处理>&$var

相关内容