bash中变量中的管道元字符
在我的bash脚本中,我需要检查记录器二进制文件是否存在。如果是这样,我将应用程序输出通过管道传输到它 编辑---- |它需要管道,应用程序应该永久工作。 -------- 我试着把管道的东西放到一个变量中,以后再使用它。比如:bash中变量中的管道元字符,bash,shell,pipe,pipeline,Bash,Shell,Pipe,Pipeline,在我的bash脚本中,我需要检查记录器二进制文件是否存在。如果是这样,我将应用程序输出通过管道传输到它 编辑---- |它需要管道,应用程序应该永久工作。 -------- 我试着把管道的东西放到一个变量中,以后再使用它。比如: if [ -e /usr/bin/logger ]; then OUT=| /usr/bin/logger fi application param1 2>&1 $OUT > /dev/null & 但它不工作,输出没
if [ -e /usr/bin/logger ]; then
OUT=| /usr/bin/logger
fi
application param1 2>&1 $OUT > /dev/null &
但它不工作,输出没有通过管道传输到记录器。如果我将管道内容直接放入应用程序startine中,它就会工作。不幸的是,如果我在if/else语句中使用带或不带记录器的命令行,那么真正的脚本就变得太复杂了——原因是我已经有if/else了,添加新的命令行会使案例数量增加一倍
简单测试应用
TMP=| wc -m
echo aas bdsd vasd $TMP
给予
$./test.sh
0
原子吸收分光光度计
似乎command1和command2是分开执行的
我使用eval和双引号中的条件内容解决了测试脚本和真实脚本中的问题
TMP="| wc -m"
eval echo aas bdsd vasd $TMP
$./test.sh
十四,
这感觉像是一个解决办法。正确的方法是什么?试试看
if [ -e /usr/bin/logger ]; then
logger $(application param1 2>&1)
fi
一般规则:不要将命令放在变量中,并通过变量调用它。直接从脚本中运行即可。试试看
if [ -e /usr/bin/logger ]; then
logger $(application param1 2>&1)
fi
一般规则:不要将命令放在变量中,并通过变量调用它。直接从脚本中运行它。我尝试了一个类似的代码,并像这样指定了最后一行,它成功了
application param1 &2>1 ${OUT} > /dev/null
我尝试了一个类似的代码,并像这样指定了最后一行,它成功了
application param1 &2>1 ${OUT} > /dev/null
虽然ghostdog74的答案是正确的,但肯定有一种方法可以实现这一点
if [ -e /usr/bin/logger ]; then
OUT='| /usr/bin/logger'
fi
eval application param1 2>&1 $OUT > /dev/null
但我强烈建议您在使用eval之前三思而后行,然后不要使用它。尽管ghostdog74的答案是正确的,但肯定有一种方法可以做到这一点
if [ -e /usr/bin/logger ]; then
OUT='| /usr/bin/logger'
fi
eval application param1 2>&1 $OUT > /dev/null
但我强烈建议您在使用eval之前三思而后行,不要使用它。正确的方法是使用if/else: 编辑: 对于复杂构造,应使用以下函数:
foo () {
if [ ... ]
then
do_something
else
something_else
fi
while [ ... ]
do
loop_stuff
done
etc.
}
那么您的日志/无日志保持简单:
if [ -e /usr/bin/logger ]
then
foo 2>&1 | /usr/bin/logger > /dev/null &
else
foo > /dev/null 2>&1 &
fi
正确的方法是使用if/else: 编辑: 对于复杂构造,应使用以下函数:
foo () {
if [ ... ]
then
do_something
else
something_else
fi
while [ ... ]
do
loop_stuff
done
etc.
}
那么您的日志/无日志保持简单:
if [ -e /usr/bin/logger ]
then
foo 2>&1 | /usr/bin/logger > /dev/null &
else
foo > /dev/null 2>&1 &
fi
只需在混合中加入另一个选项,就可以将管道移到变量外部:
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进程并不是一个巨大的资源消耗,因此,如果它使代码更干净,那么浪费可能是值得的。为了在混合中加入另一个选项,可以将管道移到变量之外:
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过程并不是一个巨大的资源消耗,因此,如果它使您的代码更干净,那么可能值得浪费。不幸的是,在支撑变量名时,我看不到上述两个示例之间有任何差异。不幸的是,在支撑变量名时,我看不到上述两个示例之间有任何差异。这些是大括号:{},这些是双引号:。关于在变量中放置命令、管道或重定向,请参见。下面是我的答案。@Dennis Williamson谢谢你的留言和链接,非常有用这些是大括号:{},这些是双引号:。关于在变量中放置命令、管道或重定向,请参见。请看下面我的答案。@Dennis Williamson感谢您的注释和链接,非常有用谢谢您的回答,我同意对于一个简单的情况,最好使用if/else,并将记录器的内容直接放在命令行中。如果您已经有多个if/else案例,并且再添加一个会使其总数翻倍,那么这些案例又如何呢?维护它们会变得太困难。@Dmitry:只需将复杂的内容放在函数中,并保持记录器条件简单即可。请参阅我的编辑。谢谢你的回答,我同意对于一个简单的情况,最好使用if/else并将记录器的内容直接放在命令行中。如果您已经有多个if/else案例,并且再添加一个会使其总数翻倍,那么这些案例又如何呢?维护它们会变得太困难。@Dmitry:只需将复杂的内容放在函数中,并保持记录器条件简单即可。请参阅我的编辑。