stocker la valeur de retour d'un script Python dans un script bash

je veux exécuter un script python à partir d'un script bash, et je veux stocker la sortie du script python dans une variable.

dans mon script python, j'imprime quelques trucs à l'écran et à la fin je renvoie une chaîne avec:

sys.exit(myString) 

Dans mon script bash, j'ai fait la suivante:

outputString=`python myPythonScript arg1 arg2 arg3 `

mais quand je vérifie la valeur de outputString avec echo $outputString j'obtiens tout ce que le script Python avait imprimé à l'écran, mais pas la valeur de retour myString !

Comment faire?

EDIT: j'ai besoin de la chaîne car cela me dit Où se trouve un fichier créé par le script Python. Je veux faire quelque chose comme:

fileLocation=`python myPythonScript1 arg1 arg2 arg1`
python myPythonScript2 $fileLocation
31
demandé sur Ricky Robinson 2012-08-10 15:35:36

7 réponses

sys.exit(myString) ne signifie pas "retourner cette chaîne". Si vous passez une corde à sys.exit , sys.exit considérera cette chaîne de caractères comme un message d'erreur, et écrira cette chaîne de caractères à stderr . Le concept le plus proche d'une valeur de retour pour un programme entier est son exit status , qui doit être un entier.

si vous voulez capturer la sortie écrite à stderr, vous pouvez faire quelque chose comme

python yourscript 2> return_file

Vous pourriez faire quelque chose comme ça dans votre script bash

output=$((your command here) 2> &1)

ce n'est pas garanti de capturer seulement la valeur passée à sys.exit , cependant. Tout ce qui est écrit à stderr sera également saisi, ce qui peut inclure des résultats de journalisation ou des traces de pile.

exemple:

test.py

print "something"
exit('ohoh') 

T. sh

va=$(python test.py 2>&1)                                                                                                                    
mkdir $va

bash t.sh

modifier

Je ne sais pas pourquoi mais dans ce cas, j'écrirais un script principal et deux autres scripts... Mélanger python et bash est inutile sauf si vous en avez vraiment besoin.

import script1
import script2

if __name__ == '__main__':
    filename = script1.run(sys.args)
    script2.run(filename)
28
répondu Loïc Faure-Lacroix 2018-06-14 23:29:35

sys.exit() devrait retourner un entier, pas une chaîne de caractères:

sys.exit(1)

la valeur 1 est dans $? .

$ cat e.py
import sys
sys.exit(1)
$ python e.py
$ echo $?
1

Edit:

si vous voulez écrire à stderr, utilisez sys.stderr .

19
répondu 2012-08-10 11:48:58

Ne pas utiliser sys.exit comme ceci. Lorsqu'il est appelé avec un argument string, le code de sortie de votre processus sera 1, signalant une condition d'erreur. La chaîne est imprimée à l'erreur standard pour indiquer ce que l'erreur pourrait être. sys.exit ne doit pas être utilisé pour fournir une "valeur de retour" de votre script.

au lieu de cela, vous devriez simplement imprimer la "valeur de retour" à la sortie standard en utilisant un print , puis appeler sys.exit(0) , et capturer la sortie dans le Shell.

7
répondu chepner 2012-08-10 12:35:00

lire docs . Si vous retournez autre chose qu'un int ou None , il sera imprimé à stderr .

pour obtenir juste stderr tout en rejetant stdout faire:

output=$(python foo.py 2>&1 >/dev/null)
5
répondu Theodros Zelleke 2012-08-10 11:55:05

la documentation Python pour sys.exit ([arg])dit:

l'argument optionnel arg peut être un entier donnant l'état de sortie (défaut à zéro), ou un autre type d'objet. S'il s'agit d'un entier, Zéro est considéré comme une "terminaison réussie" et toute valeur non nulle est considérée comme une "terminaison anormale" par les shells et autres. La plupart des systèmes exigent qu'il soit dans la gamme 0-127, et produisent des résultats non définis autrement.

de plus pour récupérer la valeur de retour du dernier programme exécuté vous pourriez utiliser le $? variable prédéfinie de bash.

de toute façon si vous mettez une chaîne comme arg dans sys.exit() il doit être imprimé à la fin de votre programme de sortie dans une ligne distincte, de sorte que vous pouvez récupérer avec juste un peu de l'analyse. À titre d'exemple, considérons ceci:

outputString=`python myPythonScript arg1 arg2 arg3 | tail -0`
1
répondu Giovanni Lombardo 2012-08-10 11:54:03

en plus de ce que Tichodroma a dit, vous pourriez finir par utiliser cette syntaxe:

outputString=$(python myPythonScript arg1 arg2 arg3)
0
répondu Alp 2012-08-10 11:37:48

vous avez répondu à votre propre question. Si vous voulez lancer un script Python à partir de bash et stocker la sortie dans une variable bash, soyez sélectif dans ce que votre script Python imprime.

crée un drapeau" verbeux " que vous pouvez désactiver dans votre script Python pour supprimer le texte supplémentaire que vous ne voulez pas stocker dans votre variable bash. Ne vous impliquez pas dans l'écriture d'une sortie valide vers stderr ou en outrepassant les codes de sortie! (c'est ce que les mauvais enfants...)

Try quelque chose comme ceci:

fileLocation=`python myPythonScript1 arg1 arg2 arg1 --verbose off`
0
répondu cs01 2015-09-27 01:00:10