Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bash中变量中的管道元字符_Bash_Shell_Pipe_Pipeline - Fatal编程技术网

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 & 但它不工作,输出没

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

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

我试着把管道的东西放到一个变量中,以后再使用它。比如:

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:只需将复杂的内容放在函数中,并保持记录器条件简单即可。请参阅我的编辑。