Como obter um sinal positivo após a conclusão bem-sucedida de um comando

1

Para cada um dos seguintes comandos (quatro no total), eu gostaria de obter uma exceção se um deles lançar uma exceção se houver um erro. Por fim, vou executar isso através do Python usando os.system ().

import os

x =\
    "../../../mysql/bin/mysqldump\
    --host=localhost\
    --port=3306\
    --databases ****\
    --user=****\
    --password=****\
    --default-character-set=utf8\
    --add-drop-database\
    --add-drop-table\
    --add-locks\
    --complete-insert\
    --extended-insert\
    --lock-all-tables\
    --create-options\
    --disable-keys\
    --quick\
    --order-by-primary\
    --set-charset\
    --tz-utc\
    > dump/test.sql;\
    cd dump;\
    tar -zcf test.sql.tar.gz test.sql;\
    rm test.sql;"

os.system(x)

Alguma idéia?

    
por user706838 28.12.2014 / 11:31

2 respostas

2

Assumindo que com "para cada um dos comandos" você quer dizer mysqldump , cd , tar e rm e com esses lançando uma exceção significando um status de saída que não é 0 (zero), você deve não use os.system() como você faz, pois ele só lida com um valor de saída.

Com base no requisito de ter uma exceção do Python com base no comando que encontra um erro, o% principal é o candidato subprocess.check_output() . É uma camada fina em torno de subprocess.call() , mas ao contrário da letra check_output() lançada e exceção na saída diferente de zero do comando chamado ( call() apenas retorna o valor de saída). Além disso, check_output() entrega a saída dos comandos para stdout back, que permite encadear os diferentes comandos no nível do python ou gravar a saída no arquivo (além de fornecer a possibilidade de verificar avisos na saída do programa que podem não ser acionados um status de saída diferente de zero).

Eu faria algo como

test_sql = subprocess.check_output([
 "../../../mysql/bin/mysqldump",
 "--host=localhost",
 "--port=3306",
 "--databases ****",
 "--user=****",
 "--password=****",
 "--default-character-set=utf8",
 "--add-drop-database",
 "--add-drop-table",
 "--add-locks",
 "--complete-insert",
 "--extended-insert",
 "--lock-all-tables",
 "--create-options",
 "--disable-keys",
 "--quick",
 "--order-by-primary",
 "--set-charset",
 "--tz-utc",
])
# analyse test_sql if necessary
with open("dump/test.sql", "w") as fp:
   fp.write(test_sql)
os.chdir('dump')
subprocess.check_output("tar -zcf test.sql.tar.gz test.sql".split())
os.remove("test.sql")

Usando check_output() s input argumento da palavra-chave (novo no Python 3.4 ) você também pode acabar escrevendo o arquivo test.sql e entregar o test_sql diretamente na segunda chamada check_output() . Mas então você poderia escrever diretamente o arquivo tar dentro do Python usando o módulo tarfile .

Com plumbum , é mais fácil seguir a estrutura das chamadas do programa shell, pois ele suporta o redirecionamento:

import sys
sys.path.insert(0, "../../../mysql")

from plumbum.cmd import myslqdump
(mysqldump[
  "--host=localhost",
  "--port=3306",
  "--databases ****",
  "--user=****",
  "--password=****",
  "--default-character-set=utf8",
  "--add-drop-database",
  "--add-drop-table",
  "--add-locks",
  "--complete-insert",
  "--extended-insert",
  "--lock-all-tables",
  "--create-options",
  "--disable-keys",
  "--quick",
  "--order-by-primary",
  "--set-charset",
  "--tz-utc",
 ] > "test.sql")()
    
por 29.12.2014 / 16:09
0

Altere esses pontos-e-vírgulas para && no pipeline de comando para que o shell pare no primeiro comando que falha e retorne seu status de saída e, em seguida, verifique o código de retorno de os.system ().

    
por 29.12.2014 / 16:15