bash 变量中的管道元字符

发布于 2024-09-27 09:56:01 字数 945 浏览 1 评论 0原文

在我的 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

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

In my bash script I need to check if logger binary exists. If so, I pipe the application output to it.

Edit--------
| It needs to be piping, the application should work permanently.
---------------

I tried to put the pipeline stuff to a variable and use it later. Something like:

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

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

but it doesn't work, the output is not piped to the logger. If I put the pipeline stuff directly into the application startline, it works. Unfortunately the real script becomes too complicated if I use command lines with and without logger stuff in if/else statements - the reason is that I already have if/else there and adding new ones will double the number of cases.

Simple test application

TMP=| wc -m
echo aas bdsd vasd $TMP

gives

$ ./test.sh
0
aas bdsd vasd

Seems that somehow command1 and command2 are executed separately.

I managed to solve the problem (in both test and real scripts) using eval and putting the conditional stuff in double quotes.

TMP="| wc -m"
eval echo aas bdsd vasd $TMP

$ ./test.sh
14

It feels like a workaround. What is the right way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

玩心态 2024-10-04 09:56:01

正确的方法是使用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.
}

然后您的日志/无日志< code>if 保持简单:

if [ -e /usr/bin/logger ]
then
    foo  2>&1 | /usr/bin/logger >  /dev/null &
else
    foo > /dev/null 2>&1 &
fi

The correct way to do this is to use 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

Edit:

In the case of a complex construct, you should use a function:

foo () {
    if [ ... ]
    then
        do_something
    else
        something_else
    fi
    while [ ... ]
    do
        loop_stuff
    done
    etc.
}

Then your log/no log if stays simple:

if [ -e /usr/bin/logger ]
then
    foo  2>&1 | /usr/bin/logger >  /dev/null &
else
    foo > /dev/null 2>&1 &
fi
巷子口的你 2024-10-04 09:56:01

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

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 进程并没有那么大的资源消耗,因此,如果它使您的代码更干净,那么浪费可能是值得的。

Just to throw another option into the mix, you could move the pipe outside the variable:

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

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

This avoids having duplicate commands for the two cases (or having to wrap everything in functions, per Dennis' suggestion). The disadvantage is that it's inefficient about how it handles the case where logger doesn't exist -- creating a cat process just to feed output to /dev/null is a complete waste. But a cat process isn't that big a resource drain, so if it makes your code cleaner it might be worth the waste.

甲如呢乙后呢 2024-10-04 09:56:01

尝试

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

一般规则:不要将命令放入变量中并通过变量调用它。只需直接从脚本中运行它即可。

Try

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

General rule: don't put commands inside variables and call it through the variable. Just run it directly off your script.

清晨说晚安 2024-10-04 09:56:01

我尝试了类似的代码并指定了最后一行,它起作用了

application  param1  &2>1   ${OUT}   >  /dev/null

I tried a similar code and specified the last line like this and it worked

application  param1  &2>1   ${OUT}   >  /dev/null
玩套路吗 2024-10-04 09:56:01

虽然 Ghostdog74 的答案是正确的,但肯定有一种方法可以完成这项工作

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

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

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

While ghostdog74's answer is correct, there is certainly a way to make this work

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

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

But I highly recommend that you think twice before using eval, and then don't use it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文