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
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)
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
.
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.
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)
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`
en plus de ce que Tichodroma a dit, vous pourriez finir par utiliser cette syntaxe:
outputString=$(python myPythonScript arg1 arg2 arg3)
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`