在我的bash脚本中,我需要检查logger二进制文件是否存在。如果是这样,我将应用程序输出传递给它。
修改--------
| 它需要管道,应用程序应该永久工作
的 ---------------
我尝试将管道内容放到变量中,稍后再使用它。类似的东西:
if [ -e /usr/bin/logger ]; then
OUT=| /usr/bin/logger
fi
application param1 2>&1 $OUT > /dev/null &
但它不起作用,输出不通过管道输出到记录器。如果我将管道内容直接放入应用程序启动行,它就可以工作。 不幸的是,如果我在if / else语句中使用带有和没有记录器的命令行,那么真正的脚本会变得太复杂 - 原因是我已经有了if / else,并且添加新的将加倍数量例。
简单的测试应用
TMP=| wc -m
echo aas bdsd vasd $TMP
给出
$ ./test.sh
0
aas bdsd vasd
似乎不知何故,command1和command2分别执行。
我设法使用eval
解决问题(在测试和实际脚本中)并将条件内容放在双引号中。
TMP="| wc -m"
eval echo aas bdsd vasd $TMP
$ ./test.sh
14
感觉就像一个解决方法。什么是正确的方法?
答案 0 :(得分:2)
执行此操作的正确方法是使用if/else
:
if [ -e /usr/bin/logger ]
then
application param1 2>&1 | /usr/bin/logger > /dev/null &
else
application param1 > /dev/null 2>&1 &
fi
修改强>
对于复杂构造,您应该使用函数:
foo () {
if [ ... ]
then
do_something
else
something_else
fi
while [ ... ]
do
loop_stuff
done
etc.
}
然后您的日志/无日志if
保持简单:
if [ -e /usr/bin/logger ]
then
foo 2>&1 | /usr/bin/logger > /dev/null &
else
foo > /dev/null 2>&1 &
fi
答案 1 :(得分:2)
只需向混合中添加另一个选项,您可以将管道移动到变量之外:
if [ -e /usr/bin/logger ]; then
logcmd=/usr/bin/logger
else
logcmd=/bin/cat
fi
application param1 2>&1 | $logcmd >/dev/null &
根据Dennis的建议,这可以避免两种情况下的重复命令(或者必须将所有内容包装在函数中)。缺点是它如何处理不存在记录器的情况效率低下 - 创建一个cat
进程只是为了将输出提供给/ dev / null是一个完全的浪费。但是cat
进程并非 消耗大量资源,因此如果它使代码更清晰,则可能值得浪费。
答案 2 :(得分:1)
尝试
if [ -e /usr/bin/logger ]; then
logger $(application param1 2>&1)
fi
一般规则:不要将命令放在变量中并通过变量调用它。只需直接从脚本中运行它。
答案 3 :(得分:0)
我尝试了类似的代码并指定了最后一行,并且它有效
application param1 &2>1 ${OUT} > /dev/null
答案 4 :(得分:0)
虽然ghostdog74的答案是正确的,但肯定有办法让这项工作
if [ -e /usr/bin/logger ]; then
OUT='| /usr/bin/logger'
fi
eval application param1 2>&1 $OUT > /dev/null
但我强烈建议您在使用eval之前再三考虑,然后不要使用它。