我试图从bash传递数组到python使用旧的getenv方法,但我不断收到此错误:
./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不是从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
当你从shell中export
一个变量时,你真正要做的是把它添加到所有子进程继承的POSIX“环境”数组中。 但是POSIX环境是一个平面的名称=值字符串数组; 它本身不能包含数组。 所以Bash甚至不尝试把数组放在那里。 它会让你export
一个数组变量,并且这样做甚至会设置该变量的“导出”标志,但环境不会被触及。 您可以通过运行env
或bash
的新副本并查找“已导出”变量来验证这一事实:
$ export myArr=(this is an array) $ bash -c 'echo "${myArr[@]}"' $
(其他一些有数组的shell,特别是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脚本可以像这样恢复数组:
mdc_no = os.getenv('mdcList').split(',')
如果你的数组元素不只是数字,你可以用不太可能出现在元素中的逗号代替逗号; 传统的选择是ASCII单元分隔符(U + 001F,Bash中的$'\x1f'
'\x1f'
,Python中的'\x1f'
)。
我认为马克·里德已经给了你一个很好的解释和解决办法。 不过,你有没有考虑过使用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']