web-dev-qa-db-fra.com

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 stocker la sortie du script python dans une variable. 

Dans mon script python, j'imprime quelques éléments à l'écran et, à la fin, je retourne une chaîne avec:

sys.exit(myString) 

Dans mon script bash, j'ai fait ce qui suit:

outputString=`python myPythonScript arg1 arg2 arg3 `

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

Comment dois-je faire cela?

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
39
Ricky Robinson

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

Si vous voulez capturer une sortie écrite en stderr, vous pouvez faire quelque chose comme

python yourscript 2> return_file

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

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

Cependant, cela ne garantit pas uniquement la valeur transmise à sys.exit. Tout ce qui est écrit sur stderr sera également capturé, ce qui peut inclure la sortie de journalisation ou les 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 trop pourquoi mais dans ce cas, j'écrirais un script principal et deux autres scripts ... Mélanger python et bash est inutile à moins que vous n'en ayez vraiment besoin.

import script1
import script2

if __== '__main__':
    filename = script1.run(sys.args)
    script2.run(filename)
31
Loïc Faure-Lacroix

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

sys.exit(1)

La valeur 1 est dans $?.

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

Modifier:

Si vous voulez écrire sur stderr, utilisez sys.stderr .

20
user647772

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

Au lieu de cela, vous devriez simplement imprimer la "valeur de retour" sur la sortie standard en utilisant une instruction print, puis appeler sys.exit(0) et capturer la sortie dans le shell.

7
chepner

lisez-le dans docs . Si vous renvoyez autre chose qu'un int ou None, il sera imprimé à stderr 

Pour obtenir simplement stderr tout en jetant stdout, faites:

output=$(python foo.py 2>&1 >/dev/null)
5
Theodros Zelleke

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

L'argument optionnel arg peut être un entier indiquant le statut de sortie (zéro par défaut) 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 similaires. La plupart des systèmes exigent qu'il soit compris entre 0 et 127 et produisent sinon des résultats non définis. 

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

Quoi qu'il en soit, si vous mettez une chaîne comme argument dans sys.exit (), elle devrait être imprimée à la fin de la sortie du programme, sur une ligne distincte, afin que vous puissiez la récupérer simplement avec un peu d'analyse. A titre d'exemple, considérons ceci:

outputString=`python myPythonScript arg1 arg2 arg3 | tail -0`
1
Giovanni Lombardo

En plus de ce que Tichodroma a dit, vous pourriez utiliser la syntaxe suivante:

outputString=$(python myPythonScript arg1 arg2 arg3)
0
Alp

Vous avez répondu à votre propre question. Si vous souhaitez exécuter un script Python à partir de bash et stocker la sortie dans une variable bash, choisissez de manière sélective ce que votre script Python affiche.

Créez un indicateur "détaillé" que vous pouvez désactiver dans votre script Python pour supprimer le texte supplémentaire que vous ne souhaitez pas stocker dans votre variable bash. Ne vous mêlez pas de l'écriture d'une sortie valide dans la variable stderr ou du code de sortie! (c'est ce que font les mauvais enfants ...)

Essayez quelque chose comme ça:

fileLocation=`python myPythonScript1 arg1 arg2 arg1 --verbose off`
0
cs01