2016-05-15 46 views
4
system : Centos 6.7 Lasted 
Shell : bash 
python : 2.6.6 

這讓我非常困惑!下面的例子:混合python和bash shell的xargs命令疑惑

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 '{}' 
+0

轉載於OS X上python 2.7.10和3.5.1 – cdarke

回答

6

發生這種情況的原因是$(python t.py '{}')表達式正在評估之前它被傳遞到xargs$(python t.py '{}')打印出「id(a1)= 139821454683184,len(a1)= 2,str(a1)= {},type(a1)=」,所以被傳遞到xargs,該文件將{}替換爲每個文件名...

這裏有一個殼痕跡,顯示發生的事情:

$ 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'> 

的「+」線展示一下外殼實際執行。 (您可以忽略xargs的參數顯示爲單引號;這是因爲t.py的輸出被分割爲單詞,但其輸出中的其他shell元字符被忽略,並直接在命令行上獲得相同效果你必須引用(/逃避)參數。)

順便說一句,這是發生了什麼事情:這是發生了什麼事情:每行都是相同的,但如果t.py實際上是爲每一行分別執行的,你會得到不同的ID。

+0

很好的解釋,另一個快速示例顯示長度爲十個字符(儘管可能通過使用find來避免未端接引號)'r = $ 「長度= 10」;找 。 -maxdepth 1 -print0 | xargs -I $ r -0 echo $(python t.py $ r)' –

2

當你看到這樣的輸出:

len(a1)=2 

這實際上是正在被之後的xargs-I選項一起使用的replStr長度。這是{}因此長度是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的呼籲蟒蛇命令行。

+0

它是參數字符串的長度,您不必更改'-I'來查看:'ls | xargs -I {} echo $(python3 gash.py'{}')'給出長度爲4.問題是「爲什麼?」 python在'sys.argv [1]'中得到的字符串不是'{}'。對不起,但你所做的只是描述問題,而不是解釋它。 – cdarke

+0

我已經添加了一些調試輸出以及爲什麼'str(a1)= {}'沒有傳遞給python – anubhava

+0

如果python被髮送了一個由5個字符組成的字符串,那麼爲什麼長度報告爲2.我不認爲你已經解釋了這一點。順便說一句,我也無法解釋它。 – cdarke