Bash 如何把&燃气轮机/开发/空2>&;1“;变成一个变量?
我多么希望它能起作用Bash 如何把&燃气轮机/开发/空2>&;1“;变成一个变量?,bash,Bash,我多么希望它能起作用 if [ $debug = 0 ]; then silent="" else silent='> /dev/null 2>&1' fi #some command wget some.url $silent 因此,如果设置了$debug,它将变为 wget some.url > /dev/null 2>&1 wget some.url 否则,如果$debug未设置为1,它将变为 wget some.url >
if [ $debug = 0 ]; then
silent=""
else
silent='> /dev/null 2>&1'
fi
#some command
wget some.url $silent
因此,如果设置了$debug,它将变为
wget some.url > /dev/null 2>&1
wget some.url
否则,如果$debug未设置为1,它将变为
wget some.url > /dev/null 2>&1
wget some.url
在变量中存储“>/dev/null 2>&1”不起作用。如何才能做到这一点?您需要shell将变量内容实际解释为命令行的一部分,而不仅仅是作为参数传递给可执行文件的字符串。看看这本书 小心安全漏洞 使用
eval
:
eval wget some.url $silent
eval
使参数作为shell命令重新定义,而不是作为被调用程序的参数
小心;不要在未知或外部输入上运行
eval
,否则您将面临一个巨大的安全漏洞。这可能是使用shell函数的一个很好的借口:
silent() {
"$@" > /dev/null 2>&1
}
现在,您可以通过以下方式运行程序使其静音:
silent wget some.url
如果只想有条件地让事情安静下来,这很容易:
silent() {
if [[ $debug ]] ; then
"$@"
else
"$@" &>/dev/null
fi
}
一种稍有不同的方法,但类似的方法可能会奏效:
if [ $debug = 1 ]; then
exec > /dev/null
fi
#some command
wget some.url
它有条件地将
stdout
替换为/dev/null
使用“$@”
,而不是$*
。强制参考:如果[$debug=0],则可以使用;然后可能是“不”的;否则可能是沉默的;菲$也许你不知道,但是你为什么要这么做呢?silent
功能可以检查标志本身是否设置得很好。使用字符串拆分来形成命令行,即使不是完全邪恶,在极端情况下也很难预测;如果有人将$IFS
设置为,比如说,i
(不寻常,但并非闻所未闻——比如说,用奇数分隔符解析文件),那么$maybesilent wget some.url
将在maybesilent=silent
时变成s lent wget some.url
,wget
的-q
选项提供了您似乎正在寻找的确切功能。它不能以这种方式工作有一个很好的理由:将数据(如变量内容)转换为语法(如重定向)是一个安全噩梦eval
强制执行此操作——这正是您不应该使用eval
的原因。有关更多讨论,请参阅。这不仅仅是wget。我经常需要它。“wget some.url”更像是“any command”的占位符。既然可以建议一些安全的东西(函数使用),为什么还要建议一些危险的东西呢?使用eval
是非常危险的。尝试对名为$(rm-rf/)
的文件进行操作…在参数受到严格控制且不包含外部输入的情况下(如本例中),使用该文件是安全的。堆栈溢出点的一部分是知识基础。在一个知识库中找到答案,当在一个非常狭窄的安全窗口之外使用时会产生风险,这将使其成为一个雷区。此外,您永远不知道您编写的代码将来会如何更改或更新;第一次起草时为真的条件可能不会一直适用于整个生命周期。这里唯一的疑问是,$debug
应该用双引号引起来,或者应该用[[]]
代替[]
以防止测试在进行字符串拆分或全局扩展时解析到除单个令牌以外的任何其他令牌时表现不好。@CharlesDuffy同意。我故意没有改变任何东西,除了重定向,但这肯定是正确的做法。