1

在我的 bash 脚本中,我需要检查记录器二进制文件是否存在。如果是这样,我将应用程序输出通过管道传输给它。

编辑--------
| 它需要是管道,应用程序应该永久工作。
---------------

我试图将管道的东西放到一个变量中,然后再使用它。就像是:

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

感觉像是一种解决方法。正确的方法是什么?

4

5 回答 5

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
于 2010-10-13T14:34:28.597 回答
2

只是为了混合另一个选项,您可以将管道移到变量之外:

if [ -e /usr/bin/logger ]; then
    logcmd=/usr/bin/logger
else
    logcmd=/bin/cat
fi

application param1 2>&1 | $logcmd >/dev/null &

这避免了两种情况下的重复命令(或者根据丹尼斯的建议,必须将所有内容包装在函数中)。缺点是它如何处理不存在记录器的情况效率低下——创建一个cat仅将输出提供给 /dev/null 的进程完全是浪费。但是一个cat进程并没有那么大的资源消耗,所以如果它让你的代码更干净,那么浪费可能是值得的。

于 2010-10-13T16:03:03.133 回答
1

尝试

if [ -e /usr/bin/logger ]; then
  logger $(application  param1 2>&1)
fi

一般规则:不要将命令放在变量中,并通过变量调用它。直接从你的脚本中运行它。

于 2010-10-13T09:57:16.850 回答
0

我尝试了类似的代码并像这样指定了最后一行并且它有效

application  param1  &2>1   ${OUT}   >  /dev/null
于 2010-10-13T10:01:34.627 回答
0

虽然 ghostdog74 的回答是正确的,但肯定有办法使这项工作

if [ -e /usr/bin/logger ]; then
  OUT='| /usr/bin/logger'
fi

eval application param1 2>&1 $OUT > /dev/null

但我强烈建议你在使用 eval 之前三思而后行,然后不要使用它。

于 2010-10-13T11:51:28.907 回答