代码之家  ›  专栏  ›  技术社区  ›  Dmitry Yudakov

bash变量中的管道元字符

  •  1
  • Dmitry Yudakov  · 技术社区  · 15 年前

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

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

    我尝试将管道材料放到变量中,稍后再使用它。类似:

    if [ -e /usr/bin/logger ]; then
      OUT=| /usr/bin/logger 
    fi
    
    application  param1  2>&1   $OUT   >  /dev/null &
    

    但它不起作用,输出不会通过管道传输到记录器。如果我把管道的东西直接放到应用程序中,它会起作用。 不幸的是,如果我在使用命令行的同时使用和不使用记录器的东西,那么真正的脚本就变得太复杂了。 在if/else语句中-原因是我已经有了if/else,并且添加新的if/else语句将使案例数增加一倍。

    简单测试应用

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

    给予

    $/Test.SH

    美国国家标准协会

    看来command1和command2是分开执行的。

    我用 eval 把有条件的东西放在双引号里。

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

    $/Test.SH
    十四

    感觉像是一个权宜之计。正确的方法是什么?

    5 回复  |  直到 15 年前
        1
  •  2
  •   Dennis Williamson    15 年前

    正确的方法是使用 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
    
        2
  •  2
  •   Gordon Davisson    15 年前

    只需将另一个选项放入混合中,就可以将管道移出变量:

    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的过程是完全浪费。但一 过程不是 那个 资源消耗很大,所以如果它使代码更干净,那么可能值得浪费。

        3
  •  1
  •   ghostdog74    15 年前

    尝试

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

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

        4
  •  0
  •   Raghuram    15 年前

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

    application  param1  &2>1   ${OUT}   >  /dev/null
    
        5
  •  0
  •   sorpigal    15 年前

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

    if [ -e /usr/bin/logger ]; then
      OUT='| /usr/bin/logger'
    fi
    
    eval application param1 2>&1 $OUT > /dev/null
    

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