web-dev-qa-db-fra.com

Utilisation de Python dans un script Bash

Si j'essaie de démarrer python dans un script bash, le script s'arrêtera et aucune commande ne s'exécutera après l'appel de "Python". Dans cet exemple simple, "TESTPRINT" ne sera pas imprimé. Il semble que le script s'arrête.

#!/bin/bash

python

print("TESTPRINT")

Echo

Comment puis-je continuer à exécuter le script après être entré dans Python? Je crois que j'ai eu le même problème il y a quelques années après avoir écrit un script qui avait d'abord besoin de Shell dans un téléphone Android Phone. Je ne me souviens pas comment je l'ai résolu à ce moment-là.

19
user364877

Pour exécuter un ensemble de commandes Python à partir d'un script bash, vous devez donner à l'interpréteur Python les commandes à exécuter, soit à partir d'un fichier (script Python) que vous créer dans le script, comme dans

#!/bin/bash -e

# Create script as "script.py"
cat >script.py <<'END_SCRIPT'
print("TESTPRINT")
END_SCRIPT

# Run script.py
python script.py

rm script.py

(cela crée un nouveau fichier appelé script.py ou écrase ce fichier s'il existe déjà, puis demande à Python de l'exécuter; il est ensuite supprimé)

... ou directement via une forme de redirection, par exemple un document ici:

#!/bin/bash

python - <<'END_SCRIPT'
print("TESTPRINT")
END_SCRIPT

Cela exécute python - Qui demande à l'interpréteur Python de lire le script à partir de l'entrée standard. Le shell envoie ensuite le texte du script Python (délimité par END_SCRIPT Dans le script Shell) au flux d'entrée standard du processus Python.

Notez que les deux bits de code ci-dessus sont subtilement différents en ce que le processus Python du deuxième script a son entrée standard connectée au script qu'il lit, tandis que le processus Python du premier script est libre pour lire des données autres que le script à partir de l'entrée standard. Cela est important si votre code Python lit à partir de l'entrée standard.

Python peut également prendre un ensemble de commandes depuis la ligne de commande directement avec son option -c:

#!/bin/bash

python -c 'print("TESTPRINT")'

Ce que vous ne pouvez pas faire est de "basculer vers Python" au milieu d'un script bash.

Les commandes d'un script sont exécutées par bash les unes après les autres, et pendant l'exécution d'une commande, le script lui-même attend qu'il se termine (s'il ne s'agit pas d'un travail d'arrière-plan).

Cela signifie que votre script d'origine démarrerait Python en mode interactif, suspendant temporairement l'exécution du script bash jusqu'à la fin du processus Python. Le script tentera alors d'exécuter print("TESTPRINT") en tant que commande Shell.

C'est un problème similaire avec l'utilisation de ssh comme ceci dans un script:

ssh user@server
cd /tmp
ls

(qui peut être similaire à ce que vous dites avoir essayé il y a quelques années).

Cela ne permettrait pas de se connecter au système distant et d'y exécuter les commandes cd et ls. Il démarrerait un shell interactif sur le système distant, et une fois ce shell terminé (redonner le contrôle au script), cd et ls serait exécuté localement.

Au lieu de cela, pour exécuter les commandes sur une machine distante, utilisez

ssh user@server "cd /tmp; ls"

(Ceci est un exemple boiteux, mais vous pouvez obtenir le point).


L'exemple ci-dessous montre comment vous pouvez réellement faire ce que vous proposez. Il est livré avec plusieurs étiquettes d'avertissement et mises en garde, et vous ne devriez jamais écrire de code comme celui-ci (car il est obscurci et donc impossible à maintenir et, oserais-je le dire , carrément mauvais).

python -
print("TESTPRINT")

Exécuter:

$ sh -s <script.sh
TESTPRINT

Ce qui se passe ici, c'est que le script est exécuté par sh -s. L'option -s De sh (et de bash) indique au Shell d'exécuter le script Shell arrivant sur le flux d'entrée standard.

Le script démarre alors python -, Qui indique Python pour exécuter tout ce qui arrive sur le flux d'entrée standard. La chose suivante sur ce flux, car elle est héritée de sh -s Par Python (et donc connectée à notre fichier texte de script), est la fonction Python commande print("TESTPRINT").

L'interpréteur Python continuerait alors à lire et à exécuter des commandes à partir du fichier de script jusqu'à ce qu'il soit épuisé ou exécute la commande Python exit().

43
Kusalananda

En plus de la réponse de Kusalananda, si vous voulez que tout le script soit exécuté par python vous pouvez simplement changer la première ligne en #!/usr/bin/env python3 et exécutez-le comme n'importe quel script Shell normal. De cette façon, vous n'avez pas à vous rappeler quel script vous devez exécuter avec quel interprète.

18
Akko

Vous pouvez également essayer le <<< (Here Strings) opérateur pour enregistrer sur les lignes:

$ python <<< 'print("MyTest")'
MyTest
9
IDDQD

Vous pouvez également définir le chemin python lors de l'appel du fichier python à partir du script bash:

export PYTHONPATH=/tmp/python_dep.Zip && python test_my.py
1
Kaushik Galiya