IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Les bases de la programmation Python par l’exemple


précédentsommairesuivant

V. Exécution des commandes externes

Note de traduction : dans ce contexte, certains termes n’ont pas été francisés (Shell, wildcards, etc.).

Certaines parties affichées peuvent être différentes en fonction de votre environnement de travail, de votre nom d’utilisateur, votre répertoire de travail, etc.

V-A. Appel de commandes Shell

 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
#!/usr/bin/python3

import subprocess

# Exécuter la commande externe 'date'
subprocess.call('date')

# Passer  des options et des arguments à la commande 
print("\nToday is ", end="", flush=True)
subprocess.call(['date', '-u', '+%A'])

# Autre exemple 
print("\nSearching for 'hello world'", flush=True)
subprocess.call(['grep', '-i', 'hello world', 'hello_world.py'])
  • L’instruction import est utilisée pour charger le module subprocess qui fait partie de la bibliothèque Python standard).
  • La fonction call du module subprocess est une des solutions pour appeler une commande externe.
  • En passant la valeur True à l’argument flush (False par défaut), vous vous assurez que votre message sera affiché avant subprocess.call.
  • Pour transmettre des arguments à la commande, une liste de chaînes de caractères est passée au lieu d'une chaîne de caractère unique.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
$ ./calling_shell_commands.py 
Tue Jun 21 18:35:33 IST 2016

Today is Tuesday

Searching for 'hello world'
print("Hello World")

Lecture complémentaire :

V-B. Appel de commandes Shell avec expansion

 
Sélectionnez
#!/usr/bin/python3

import subprocess

# Exécution sans expansion 
print("Pas  expansion shell  quand shell=False", flush=True)
subprocess.call(['echo', 'Hello $USER'])

# Exécution avec l’expansion Shell 
print("\nexpansionshell  quand shell=True", flush=True)
subprocess.call('echo Hello $USER', shell=True)

# Echappement de la chaîne si nécessaire 
print("\nSearching for 'hello world'", flush=True)
subprocess.call('grep -i \'hello world\' hello_world.py', shell=True)
  • Par défaut subprocess.call n’est pas étendu (jolers du Shell), lors de l’exécution d'une substitution de commande, etc.
  • Vous pouvez outrepasser ce comportement en passant la valeur True à l’argument shell.
  • Notez que la commande entière est maintenant passée en tant que chaîne et non en tant que liste de chaînes.
  • Les apostrophes (quotes : ')doivent être échappées (\').
  • Utilisez shell=True seulement si vous êtes sûr que la commande doit être exécutée dans l’environnement Shell, sinon il pourrait y avoir une faille de sécurité.
  • documentation Python – subprocess, Popen.
 
Sélectionnez
1.
2.
3.
4.
5.
6.
7.
8.
9.
$ ./shell_expansion.py 
Pas d' expansion  shell quand shell=False
Hello $USER

expansion shell quand shell=True
Hello learnbyexample

Recherche pour 'hello world'
print("Hello World")
  • Dans certains cas, vous pouvez éviter l’échappement en alternant l’utilisation de guillemets et d’apostrophes comme suit :
 
Sélectionnez
# utilisation alternée d'apostrophes et de guillemets
subprocess.call('grep -i "hello world" hello_world.py', shell=True)

# ou ceci
subprocess.call("grep -i 'hello world' hello_world.py", shell=True)
 
Sélectionnez
# pour plus de clarté, utilisez des variables et évitez les longues chaînes dans des fonctions
cmd = "grep -h 'test' report.log test_list.txt > grep_test.txt"
subprocess.call(cmd, shell=True)

Solution de remplacement de l’utilisation de Shell=True.

 
Sélectionnez
>>> import subprocess, os
>>> subprocess.call(['echo', 'Hello', os.environ.get("USER")])
Hello learnbyexample
0
  • os.environ.get("USER") permet de récupérer la variable d’environnement USER.
  • 0 est la valeur de retour / de sortie, indiquant la bonne réalisation de la commande. C'est une notification de l'interpréteur python qui affiche également la valeur de retour.

V-C. Gérer les commandes de flux sortants et les redirections

 
Sélectionnez
#!/usr/bin/python3

import subprocess

# La sortie inclut les messages d’erreur 
print("Obtenir la sortie de la commande  'pwd' ", flush=True)
curr_working_dir = subprocess.getoutput('pwd')
print(curr_working_dir)

# Obtenir le statut et les retours de la commande exécutée  
# Toute autre valeur que `0` est considérée comme une commande ayant rencontré une erreur 
ls_command = 'ls hello_world.py xyz.py'
print("\nAppel de la  commande '{}'".format(ls_command), flush=True)
(ls_status, ls_output) = subprocess.getstatusoutput(ls_command)
print("status: {}\nsortie : '{}'".format(ls_status, ls_output))

# Vous pouvez supprimer les messages d’erreurs si vous le souhaitez 
# subprocess.call() renvoie le statut de la commande et qui peut être utilisé 
print("\nCalling command with error msg suppressed", flush=True)
ls_status = subprocess.call(ls_command, shell=True, stderr=subprocess.DEVNULL)
print("status: {}".format(ls_status))
  • La sortie de getstatusoutput() est un de type de données tuple – plus d’informations et d’exemples dans les prochains chapitres.
  • getstatusoutput() et getoutput() sont des fonctions héritées.
  • D’autres fonctions plus récentes et plus d'options de sécurité :

 
Sélectionnez
$ ./shell_command_output_redirections.py 
Obtention de la sortie de  la commande 'pwd'
/home/learnbyexample/Python/python_programs

Appel de la commande 'ls hello_world.py xyz.py'
status: 2
sortie : 'ls: cannot access xyz.py: No such file or directory
hello_world.py'

Appel de la commande avec messages d'erreur supprimés
hello_world.py
status: 2

précédentsommairesuivant

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2018 Sundeep Agarwal. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.