Shell中的管道与xargs

在《程序员修炼之道:从小工到专家》这本书里,解答41给了一个Shell版本的测试器。

试了一下无法运行,问题出在下面这句话上:

#!/bin/sh
CMD="java dbc.dbc_ex"
failcount=0
expect_okay() {
    if echo "$*" | $CMD #>/dev/null 2>&1
    then
        :
    else
        echo "FAILED! $*"
        failcount='expr $failcount + 1'
    fi
}

在if这行,echo "$*"输出的参数,没有办法通过管道传递给后面的命令。

不知道作者的运行环境是什么,我在AIX和Cygwin上试验都失败了。


原因很简单,管道是通过stdin来传递的,而无法从stdin读取输入的命令,比如本例中的java,无法取到管道中的参数。

而awk等可以从stdin获取输入的命令则可以直接从管道获取数据。


解决方案很简单,增加xargs命令,改为:

#!/bin/sh
CMD="java dbc.dbc_ex"
failcount=0
expect_okay() {
    if echo "$*" | xargs $CMD #>/dev/null 2>&1
        then
        :
    else
        echo "FAILED! $*"
        failcount='expr $failcount + 1'
    fi
}
xargs可以从管道中获取参数,然后再将参数和后面的命令组合起来执行。(如果参数过长还会自动拆分并调用多次。)

这样等于变相解决了无法直接获取管道数据的命令和管道结合使用的问题。

详细说明参见:http://blog.youkuaiyun.com/peteryxk/article/details/1622491


顺便说一下>/dev/null 2>&1这句命令的意思是将stdout和stderr全部重定向到/dev/null中,也就是将产生的所有信息丢弃,避免输出。

常用于夜间批处理的场合。(本例中被注释掉了)

2>&1这种写法可以避免重定向时产生两个管道同时访问同一个目标。

具体说明参见:http://viplin.blog.51cto.com/241472/99568

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值