2015-11-20 42 views
5

我試圖通過從bash的數組使用舊的getenv方法,但是我不斷收到此錯誤的Python:傳遞慶典陣列Python列表

./crcFiles.sh: line 7: export: `0021': not a valid identifier 
Traceback (most recent call last): 
    File "/shares/web/vm3618/optiload/prog/legalLitres.py", line 30, in <module> 
    for i in mdcArray.split(' '): 
AttributeError: 'NoneType' object has no attribute 'split' 

可能有人請解釋爲什麼$ mdcNo ISN」 t從bash傳遞給python成功了嗎?

代碼.SH:

#!/bin/bash 

mdcNo=('0021' '0022' '0036' '0055' '0057' '0059' '0061' '0062' '0063' '0065' '0066' '0086' '0095' '0098' '0106' '0110' '0113' '0114' '0115' '0121' '0126' '0128' '0135' '0141' '0143' '0153' '0155' '0158') 

localDIR=/shares/web/vm3618/optiload/prog 

export mdcNo 

$localDIR/legalLitres.py 


for i in "${mdcNo[@]}" 
do 
echo $i 
cp $localDIR/MDC$i/*/QqTrkRec.txt $localDIR/crccalc/. 
cd $localDIR/crccalc 
./crccalc.py QqTrkRec.txt 
cp $localDIR/crccalc/QqTrkRec.txt $localDIR/MDC$i/. 
done 

代碼的.py:

#!/usr/bin/python 

import glob 
import os 

mdcArray = os.getenv('mdcNo') 

#Legal Litres that hex and decimal 
legalLitresHex = "47E0" 
legalLitresTxt = '18,400' 

# file name and Legal Litres header 
legalHeader = ":00F0:" 
hexFile = "QqTrkRec.txt" 

# insert comment to explain change 
comment = "#\n# 2015 Nov 20: Legal Litres changed to 18,400\n#\n" 
commentFlag0 = "# SetDATA" 
commentFlag1 = "# SetDATA" 

try: 
    for i in mdcArray.split(' '): 


     line = "" 

     Qqfile = glob.glob("/shares/web/vm3618/optiload/prog/MDC"+i+"/*/"+hexFile) 
     outFile = Qqfile[0]+".new" 

     print i 
+4

導出一個變量名*而不是其內容。 '出口mdcNo'不'出口$ mdcNo'。 –

+0

我假設你的問題比Etan的有效評論更多地與答案有關......如果是這樣,你能編輯你的問題,所以這不會因爲錯字而關閉嗎? – Foon

回答

9

當你export從shell變量,你真正做的是將它添加到POSIX 「環境」 陣所有子進程都繼承。但是POSIX環境是一個扁平的name = value字符串數組;它本身不能包含數組。所以Bash甚至不會嘗試將數組放在那裏。它會讓你export一個數組變量,甚至設置該變量的「導出」標誌,但環境沒有被觸及。您可以通過運行envbash新副本,並尋找「出口」變量驗證了這一事實:

$ export myArr=(this is an array) 
$ bash -c 'echo "${myArr[@]}"' 

$ 

(其他一些陣列具有殼,尤其是KSH,實際上將一個數組變量導出到環境,但導出的值將僅包含數組的第一個元素。)

如果要將shell數組傳遞給Python腳本,最好的方法是將其作爲命令行參數。如果你運行Python腳本是這樣的:

python code.py "${mdcNo[@]}" 

...那麼Python代碼可以剛過sys.argv循環,這始終是一個列表。 (具體來說,由於sys.argv[0]始終設置爲腳本本身的名稱,所以傳入的陣列將爲片段sys.argv[1:])。

如果這不是一個選項,那麼您必須將環境變量設置爲字符串與元素之間的一些分隔符,並將其分割到Python代碼中。事情是這樣的..

擊:

export mdcList='0021,0022,0036,0055,0057,0059,0061,0062,0063,0065,0066,0086,0095,0098,0106,0110,0113,0114,0115,0121,0126,0128,0135,0141,0143,0153,0155,0158' 

或者你也可以從陣列中建立起來的字符串:

export mdcList=${mdcNo[0]} 
for i in "${mdcNo[@]:1}"; do 
    mdcList+=,$i 
done 

不管怎樣,Python腳本可以恢復陣列像列表這個:

如果你的數組元素不只是數字,你可以用逗號替換逗號g不太可能出現在元素中;傳統的選擇是ASCII單元分隔符(Bash中的U + 001F,$'\x1f',Python中的'\x1f')。

2

我認爲馬克裏德已經給了你一個很好的解釋和解決方案。不過,你有沒有考慮過使用python的argparse

#!/usr/bin/env python 
import argparse 


def main(): 
    parser = argparse.ArgumentParser() 
    parser.add_argument('stuff', nargs='+') 
    args = parser.parse_args() 
    print args.stuff 

if __name__ == '__main__': 
    main() 

用途:

$ mdcNo=('0021' '0022' '0036' '0055' '0057' '0059' '0061' '0062' '0063' '0065' '0066' '0086' '0095' '0098' '0106' '0110' '0113' '0114' '0115' '0121' '0126' '0128' '0135' '0141' '0143' '0153' '0155' '0158') 
$ python argp.py "${mdcNo[@]}" 
['0021', '0022', '0036', '0055', '0057', '0059', '0061', '0062', '0063', '0065', '0066', '0086', '0095', '0098', '0106', '0110', '0113', '0114', '0115', '0121', '0126', '0128', '0135', '0141', '0143', '0153', '0155', '0158'] 
+0

@MarkReed我不知道我理解你的問題。 'args.stuff'是一個列表 – lorenzog

+0

@MarkReed我的壞 - 我已經修復它的源代碼(我第一次在代碼中使用'action ='append'')但沒有修復輸出。謝謝 – lorenzog