Como verificar o status do script de shell bash ao executar a partir do script Python?

2

Eu tenho um script Python simples que executará um script de shell usando o módulo subprocess em Python.

Abaixo está meu script de shell Python que está chamando testing.sh script de shell e funciona bem.

import os
import json
import subprocess

jsonData = '{"pp": [0,3,5,7,9]}'
jj = json.loads(jsonData)

os.putenv( 'jj3', ' '.join( str(v) for v in jj['pp']  ) )

print "start"
proc = subprocess.Popen('testing.sh', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if stderr:
   print "Shell script gave some error"
   print stderr
else:
   print stdout
   print "end" # Shell script ran fine.

E abaixo está o meu script de shell testing.sh -

#!/bin/bash

dir1=some_directory
dir2=some_directory

length1=some_number
length2=some_number

if [ "$dir1" = "$dir2" ] && [ "$length1" -gt 0 ] && [ "$length2" -gt 0 ]
then
    for el in $jj3
    do
        scp david@machineB:/data/be_t1_snapshot/20131215/t1_"$el"_5.data /data01/primary/. || scp david@machineC:/data/be_t1_snapshot/20131215/t1_"$el"_5.data /data01/primary/.
    done        
fi

O que meu script de shell acima faz é copiar os arquivos de machineB OR machineC para machineA . Se os arquivos não estão lá em machineB , então deve estar lá em machineC sempre. Então, ele tentará copiar os arquivos de machineB para machineA , mas se os arquivos não estiverem em machineB , ele tentará copiar os arquivos de machineC para machineA .

Agora, meu script Python acima (que estou executando em machineA ) tenta executar o script de shell acima e ver se meu script foi executado com êxito ou não. Como estou armazenando o stderr do meu script de shell e stdout também.

Descrição do problema: -

Com a abordagem acima, há um problema que estou vendo. Como mencionei se os arquivos não estão em machineB , ele tentará copiar os arquivos de machineC para machineA . Então, sempre que eu executo meu script Python, que chama meu script de shell, o que acontece é que alguns arquivos não estão lá em machineB , então lança alguma exceção e tenta copiar os arquivos de machineC , mas quando a chamada volta Python script, ele sempre entra em if stderr: block porque houve um erro ao copiar os arquivos de machineB (que não é o que eu quero) e end print statement não é impresso.

Portanto, a questão é se os arquivos não estão lá em machineB , ele tentará copiar os arquivos de machineC e se o arquivo for machineC e foi copiado com êxito para machineA sem nenhum erro, então quero chamar isso como success em vez de failure . No cenário atual, o que está acontecendo, se os arquivos não estão lá em machineB e foram copiados com sucesso de machineC , então ele ainda conta como uma falha e end print statement não é impresso.

Eu também quero ver se o meu shell script tem algum problema durante a execução do Python. Se sim, não quero imprimir a declaração end .

Como devo superar esse problema?

ATUALIZAÇÃO: -

O que acontecerá com o script de shell abaixo? Como o primeiro loop for falhou porque david não é um comando linux, mas meu comando scp funciona bem. Então, ainda vou ver o código de status como não igual a 0?

for i in $( david ); do
    echo item: $i
done

dir1=some_directory
dir2=some_directory

length1=some_number
length2=some_number

if [ "$dir1" = "$dir2" ] && [ "$length1" -gt 0 ] && [ "$length2" -gt 0 ]
then
    for el in $jj3
    do
        scp david@machineB:/data/be_t1_snapshot/20131215/t1_"$el"_5.data /data01/primary/. || scp david@machineC:/data/be_t1_snapshot/20131215/t1_"$el"_5.data /data01/primary/.
    done        
fi
    
por arsenal 01.01.2014 / 06:29

1 resposta

1

De Documento de subprocesso do Python :

Popen.returncode

The child return code, set by poll() and wait() (and indirectly by communicate()). A None value indicates that the process hasn’t terminated yet.
A negative value -N indicates that the child was terminated by signal N (Unix only).

Assim, você pode verificar o status de saída usando:

proc.returncode

mas é pouco irônico que isso seja zero 0 significa False em Python.

Exemplo:

if (var == False) :
    # this will execute if var is False or 0 (or 0.0, 0L, 0j)

Leia as Armadilhas do Python

    
por 01.01.2014 / 07:50