2015-11-20 15 views
5

Próbuję przekazać tablicę z bash do Python przy użyciu starej metody getenv jednak wciąż otrzymuję ten błąd:przechodzącą bash tablica do listy Pythona

./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' 

może ktoś proszę wyjaśnić dlaczego ISN $ mdcNo” t przechodzenie z bash do python pomyślnie?

Kod 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 

kod .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

wyeksportować zmienną * Imię * nie obejmuje jej zawartości. 'export mdcNo' nie' export $ mdcNo'. –

+0

Zakładam, że twój problem miał więcej wspólnego z odpowiedzią niż ważny komentarz Etana ... jeśli tak, czy mógłbyś edytować swoje pytanie, więc nie zostanie ono zamknięte jako literówka? – Foon

Odpowiedz

9

Kiedy export zmienna z powłoki, co naprawdę robi jest dodanie go do POSIX "środowisko" array wszystkie procesy potomne dziedziczą. Ale środowisko POSIX jest płaską tablicą ciągów nazwa = wartość; nie może sam zawierać tablic. Więc Bash nawet nie próbuje umieścić tam tablic. Pozwoli ci to uzyskać zmienną tablicową, a nawet ustawia flagę "wyeksportowaną" dla tej zmiennej, ale środowisko nie zostanie dotknięte. Możesz sprawdzić ten fakt poprzez uruchomienie env lub nową kopię bash i szukasz „eksportowanych” Zmienna:

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

$ 

(Niektóre inne muszle array-konieczności, zwłaszcza ksh, będzie faktycznie wyeksportować zmienną tablicową dla środowiska , ale wyeksportowana wartość będzie składać się tylko z pierwszego elementu tablicy.)

Jeśli chcesz przekazać tablicę powłoki do skryptu w języku Python, najlepiej jest zrobić to jako argumenty wiersza poleceń. Jeśli uruchomić skrypt Pythona takiego:

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

... wtedy kod Python może po prostu pętli nad sys.argv, która zawsze jest lista. (W szczególności przekazywana tablica będzie numerem sys.argv[1:], ponieważ sys.argv[0] jest zawsze ustawiona na nazwę samego skryptu.)

Jeśli to nie jest opcja, musisz ustawić zmienną środowiskową na ciąg znaków z ogranicznikiem między elementami i podziel go wewnątrz kodu Pythona. Coś takiego ..

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' 

Albo można zbudować ciąg znad tablicy:

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

czy inaczej, skrypt Pythona można odzyskać tablicę jako listę jak to:

Jeśli twoje elementy tablicy to nie tylko liczby, możesz zastąpić przecinek czymś g mniej prawdopodobne pojawienie się w elemencie; tradycyjny wybór to separator jednostek ASCII (U + 001F, $'\x1f' w Bash, '\x1f' w języku Python).

2

Myślę, że Mark Reed dał już bardzo dobre wyjaśnienie i rozwiązanie. Mimo to, czy zastanawiałeś się nad korzystaniem z Pythona 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() 

Zastosowanie:

$ 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 Nie jestem pewien, czy rozumiem twoje pytanie. 'args.stuff' to lista – lorenzog

+0

@MarkReed my bad - Naprawiłem ją w źródle (najpierw użyłem' action = 'append'' w kodzie), ale nie naprawiłem wyjścia. Dzięki – lorenzog

Powiązane problemy