【问题标题】:passing bash array to python list将 bash 数组传递给 python 列表
【发布时间】:2016-02-23 02:29:32
【问题描述】:

我正在尝试使用旧的 getenv 方法将数组从 bash 传递到 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 没有成功地从 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

【问题讨论】:

  • 您导出变量 name 而不是其内容。 export mdcNo 不是 export $mdcNo
  • 我假设您的问题与答案有关,而不是 Etan 的有效评论……如果是这样,您能否编辑您的问题,以免因错字而被关闭?

标签: python arrays linux bash


【解决方案1】:

如果你想将一个 shell 数组传递给 Python 脚本,最好的办法是作为命令行参数来做。如果你像这样运行 Python 脚本:

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

... 那么 Python 代码可以循环遍历sys.argv,它始终是一个列表。 (具体来说,传入的数组将是切片sys.argv[1:],因为sys.argv[0] 始终设置为脚本本身的名称。)

你试图通过环境传递它;问题在于环境是一维字符串数组,不支持数组。如果命令行不是一个选项并且您别无选择,只能使用环境,则必须将环境变量设置为一个字符串,元素之间有一些分隔符,并在 Python 代码中将其拆分。该案例的 bash 看起来像这样:

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'

或者如果你已经有一个 bash 数组,你可以从中构建强:

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',Python 中的 '\x1f')。

【讨论】:

    【解决方案2】:

    我认为 Mark Reed 已经给了你一个很好的解释和解决方案。 不过,你有没有考虑过使用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']
    

    【讨论】:

    • @MarkReed 我不确定我是否理解你的问题。 args.stuff 是一个列表
    • @MarkReed 我的错 - 我已经在源代码中修复了它(我首先在代码中使用了 action='append')但没有修复输出。谢谢
    猜你喜欢
    • 2016-07-24
    • 2019-05-30
    • 2011-04-27
    • 1970-01-01
    • 2015-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-23
    相关资源
    最近更新 更多