我尝试在 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 的扩展,这使用起来有点棘手,并且可能会导致意外的行为。
笔记:>$var
bash 中对和有特殊处理>&$var