混合python和bash shell的xargs命令怀疑

时间:2016-05-15 06:07:41

标签: python bash xargs

system : Centos 6.7 Lasted 
Shell : bash 
python : 2.6.6

这让我非常困惑!以下示例:

5个文件:

a1111  a2222  b1111  b2222  t.py

t.py内容:

import sys

if __name__ == '__main__':
    a1 = sys.argv[1]
    print 'id(a1)=%s, len(a1)=%s, str(a1)=%s, type(a1)=%s' % (id(a1), len(a1), str(a1), type(a1))

这样做:

ls | xargs -I{} echo $(python t.py '{}')

输出:

id(a1)=139821454683184, len(a1)=2, str(a1)=a1111, type(a1)=<type 'str'>
id(a1)=139821454683184, len(a1)=2, str(a1)=a2222, type(a1)=<type 'str'>
id(a1)=139821454683184, len(a1)=2, str(a1)=b1111, type(a1)=<type 'str'>
id(a1)=139821454683184, len(a1)=2, str(a1)=b2222, type(a1)=<type 'str'>
id(a1)=139821454683184, len(a1)=2, str(a1)=t.py, type(a1)=<type 'str'>

我的问题是为什么len(a1)= 2,但str(a1)= a1111 ?, 字符串长度显然不等于2

没有回音是好的,但这不是我的问题。我使用xargs -p选项打印cmd

ls | xargs -I{} python t.py '{}'

2 个答案:

答案 0 :(得分:6)

发生这种情况的原因是{<1}}表达式在传递给$(python t.py '{}')之前正在评估xargs打印“id(a1)= 139821454683184,len(a1)= 2,str(a1)= {},类型(a1)=”,所以传递给{{ 1}},用每个文件名替换$(python t.py '{}') ...

这是一个shell跟踪,显示正在发生的事情:

xargs

“+”行显示shell实际执行的内容。 (您可以忽略{}的参数以单引号显示;这只是因为$ set -x # turn on tracing $ ls | xargs -I{} echo $(python t.py '{}') + ls ++ python t.py '{}' + xargs '-I{}' echo 'id(a1)=4560222208,' 'len(a1)=2,' 'str(a1)={},' 'type(a1)=<type' ''\''str'\''>' id(a1)=4560222208, len(a1)=2, str(a1)=a1111, type(a1)=<type 'str'> id(a1)=4560222208, len(a1)=2, str(a1)=a2222, type(a1)=<type 'str'> id(a1)=4560222208, len(a1)=2, str(a1)=b1111, type(a1)=<type 'str'> id(a1)=4560222208, len(a1)=2, str(a1)=b2222, type(a1)=<type 'str'> id(a1)=4560222208, len(a1)=2, str(a1)=t.py, type(a1)=<type 'str'> 的输出被拆分为单词,但其输出中的其他shell元字符被忽略,并且得到直接在命令行上产生相同的效果,你必须引用(/ escape)参数。)

顺便说一句,还有另外一个赠品:这就是正在发生的事情:每一行的id都是相同的,但如果xargs实际上是为每一行单独执行的,那么你会得到不同的ID。

答案 1 :(得分:2)

当您看到此输出时:

len(a1)=2

这实际上是在replStr选项-I之后使用xargs的长度。这是{}因此长度为2

如果您使用其他replStr

ls | xargs -I% echo $(python ./t.py '%')

然后,您会在输出中看到len=1,因为%的长度为1

id(a1)=4342949968, len(a1)=1, str(a1)=a1111, type(a1)=<type 'str'>
id(a1)=4342949968, len(a1)=1, str(a1)=a2222, type(a1)=<type 'str'>
id(a1)=4342949968, len(a1)=1, str(a1)=b1111, type(a1)=<type 'str'>
id(a1)=4342949968, len(a1)=1, str(a1)=b2222, type(a1)=<type 'str'>
id(a1)=4342949968, len(a1)=1, str(a1)=t.py, type(a1)=<type 'str'>

原因是您使用时:

ls | xargs -I{} echo $(python ./t.py '{}')

你实际上是在子shell中调用python程序,并且将文字{}传递给python。

以下是显示相同的调试输出:

bash -cx 'ls | xargs -I{} echo $(python ./t.py "{}")' >/dev/null
+ ls
++ python ./t.py '{}'
+ xargs '-I{}' echo 'id(a1)=4460329040,' 'len(a1)=2,' 'str(a1)={},' 'type(a1)=<type' ''\''str'\''>'

但是你使用:

bash -cx 'ls | xargs -I{} python ./t.py "{}"' >/dev/null
+ ls
+ xargs '-I{}' python ./t.py '{}'

您可以在xargs调用python命令行的方式中看到不同的行为。