Appel d'une commande externe en Python

Comment puis-je appeler une commande externe (comme si je l'avais tapée à L'invite de commande Unix shell ou Windows) à partir d'un script Python?

3772
demandé sur igaurav 2008-09-18 05:35:30

30 réponses

regardez le module de sous-processus dans la bibliothèque standard:

from subprocess import call
call(["ls", "-l"])

l'avantage de subprocess vs. system est qu'il est plus flexible (vous pouvez obtenir le stdout, stderr, le code" réel " de l'état, une meilleure gestion des erreurs, etc...).

le documentation officielle recommande le sous-processus module sur le os alternatifs.système ():

le module subprocess fournit des installations plus puissantes pour la reproduction de nouveaux processus et la récupération de leurs résultats; l'utilisation de ce module est préférable à l'utilisation de cette fonction [ os.system() ].

le" remplaçant les anciennes fonctions par le Module de sous-processus "section dans le sous-processus la documentation peut contenir des recettes utiles.

documentation officielle sur le sous-processus module:

3622
répondu David Cournapeau 2018-06-03 14:41:52

voici un résumé des façons d'appeler les programmes externes et les avantages et inconvénients de chacun:

  1. os.system("some_command with args") passe la commande et les arguments à l'interpréteur de commandes de votre système. C'est bien parce que vous pouvez exécuter plusieurs commandes à la fois de cette manière et configurer les pipes et la redirection des entrées/sorties. Par exemple:

    os.system("some_command < input_file | another_command > output_file")  
    

    cependant, bien que ce soit pratique, vous devez manipuler manuellement l'échappement des caractères shell tels que les espaces, etc. D'un autre côté, cela vous permet également d'exécuter des commandes qui sont simplement des commandes shell et pas réellement des programmes externes. Voir la documentation .

  2. stream = os.popen("some_command with args") va faire la même chose que os.system sauf qu'il vous donne un objet file-like que vous pouvez utiliser pour accéder entrée/sortie standard pour ce processus. Il ya 3 autres variantes de popen que tous manipulez l'e/s légèrement différemment. Si vous passez tout comme une chaîne, alors votre commande est passée à l'interpréteur de commandes; si vous les Passez comme une liste, alors vous n'avez pas besoin de vous soucier d'échapper à quoi que ce soit. Voir la documentation .

  3. la classe Popen du module subprocess . Il s'agit du remplacement de os.popen mais il présente l'inconvénient d'être un peu plus compliqué du fait qu'il complet. Par exemple, vous diriez:

    print subprocess.Popen("echo Hello World", shell=True, stdout=subprocess.PIPE).stdout.read()
    

    au lieu de:

    print os.popen("echo Hello World").read()
    

    mais il est agréable d'avoir toutes les options là-bas dans une classe unifiée au lieu de 4 fonctions popen différentes. Voir la documentation .

  4. la fonction call du module subprocess . C'est essentiellement comme la classe Popen et prend tous les mêmes arguments, mais il attend simplement que la commande complète et vous donne le code de retour. Par exemple:

    return_code = subprocess.call("echo Hello World", shell=True)  
    

    voir la documentation .

  5. si vous êtes sur Python 3.5 ou plus tard, vous pouvez utiliser la nouvelle fonction subprocess.run , qui est un peu comme ci-dessus, mais encore plus flexible et renvoie un objet CompletedProcess lorsque la commande fini de s'exécuter.

  6. le module os a aussi toutes les fonctions fork/exec/spawn que vous auriez dans un programme C, mais je ne recommande pas de les utiliser directement.

le module subprocess devrait probablement être celui que vous utilisez.

enfin s'il Vous Plaît être conscient que pour toutes les méthodes où vous passez la commande finale d'être exécuté par le shell comme une chaîne de caractères et vous êtes responsable pour lui échapper. Il y a de graves répercussions sur la sécurité si une partie de la chaîne que vous transmettez ne peut pas être pleinement confiance. Par exemple, si un utilisateur entre une partie quelconque de la chaîne. Si vous n'êtes pas sûr, n'utiliser ces méthodes avec des constantes. Pour vous donner une idée des implications, considérez ce code:

print subprocess.Popen("echo %s " % user_input, stdout=PIPE).stdout.read()

et d'imaginer que l'utilisateur entre "ma maman ne m'aime && rm -rf /".

2531
répondu Eli Courtwright 2016-04-11 19:18:11

je l'utilise généralement:

import subprocess

p = subprocess.Popen('ls', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in p.stdout.readlines():
    print line,
retval = p.wait()

vous êtes libre de faire ce que vous voulez avec les données stdout dans le tuyau. En fait, vous pouvez tout simplement omettre ces paramètres ( stdout= et stderr= ) et il se comportera comme os.system() .

271
répondu EmmEff 2016-12-10 13:22:55

quelques conseils pour détacher le processus enfant du processus appelant (démarrer le processus enfant en arrière-plan).

supposons que vous voulez démarrer une longue tâche à partir d'un script CGI, c'est-à-dire que le processus enfant devrait vivre plus longtemps que le processus D'exécution du script CGI.

l'exemple classique du module subprocess docs est:

import subprocess
import sys

# some code here

pid = subprocess.Popen([sys.executable, "longtask.py"]) # call subprocess

# some more code here

l'idée ici est que vous ne voulez pas attendre dans la ligne 'sous-processus d'appel' jusqu'à ce que les longtask.py c'est fini. Mais il n'est pas clair ce qui se passe après la ligne " code plus ici de l'exemple.

ma plate-forme cible était freebsd, mais le développement était sur windows, donc j'ai fait face au problème sur windows en premier.

sur windows (win xp), le processus parent ne sera pas terminé jusqu'à ce que le longtask.py a terminé son travail. Ce n'est pas ce que vous voulez dans CGI-script. Le problème n'est pas spécifique à Python, dans la communauté PHP les problèmes sont de même.

la solution consiste à passer process Creation Flag à la fonction CreateProcess sous-jacente de L'API win. Si vous avez installé pywin32, vous pouvez importer le drapeau du module win32process, sinon vous devez le définir vous-même:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

/ * UPD 2015.10.27 @eryksun dans un commentaire ci-dessous note, que le drapeau sémantiquement correct est CREATE_NEW_CONSOLE (0x00000010) * /

sous freebsd nous avons un autre problème: lorsque le processus parent est terminé, il finit aussi les processus enfants. Et ce n'est pas non plus ce que vous voulez dans CGI-script. Certaines expériences ont montré que le problème semblait être de partager LA SAJR.la sortie standard stdout. Et la solution de travail était la suivante:

pid = subprocess.Popen([sys.executable, "longtask.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

Je n'ai pas vérifié le code sur d'autres plateformes et je ne sais pas les raisons du comportement sur freebsd. Si quelqu'un sait, merci de partager vos idées. Googler sur le démarrage des processus de background en Python ne fait pas encore la lumière.

165
répondu newtover 2017-07-27 21:35:57

je recommande d'utiliser le module subprocess au lieu du système d'exploitation.système parce qu'il ne shell échapper pour vous et est donc beaucoup plus sûr: http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost'])
103
répondu sirwart 2014-04-04 19:46:08
import os
cmd = 'ls -al'
os.system(cmd)

Si vous voulez retourner les résultats de la commande, vous pouvez utiliser os.popen . Cependant, ceci est déprécié depuis la version 2.6 en faveur du module de sous-processus , que d'autres réponses ont bien couvert.

102
répondu Alexandra Franks 2016-01-26 16:53:05
import os
os.system("your command")

notez que c'est dangereux, puisque la commande n'est pas nettoyée. Je vous laisse à google pour la documentation pertinente sur les modules' os 'et' sys'. Il y a un tas de fonctions (exec* et spawn*) qui vont faire des choses similaires.

89
répondu nimish 2018-06-03 17:10:00

j'utilise toujours fabric pour ce genre de choses:

from fabric.operations import local
result = local('ls', capture=True)
print "Content:/n%s" % (result, )

Mais cela semble être un bon outil: sh (Python sous-processus de l'interface) .

regardez un exemple:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)
54
répondu Jorge E. Cardona 2013-07-23 18:28:23

vérifiez aussi la bibliothèque" pexpect " Python.

il permet le contrôle interactif de programmes/commandes externes, même ssh, ftp, telnet, etc. Vous pouvez taper quelque chose comme:

child = pexpect.spawn('ftp 192.168.0.24')

child.expect('(?i)name .*: ')

child.sendline('anonymous')

child.expect('(?i)password')
53
répondu athanassis 2017-05-28 23:02:27

il y a beaucoup de bibliothèques différentes qui vous permettent d'appeler des commandes externes avec Python. Pour chaque bibliothèque, j'ai donné une description et montré un exemple d'appel d'une commande externe. La commande que j'ai utilisée comme exemple est ls -l (list all files). Si vous voulez en savoir plus sur les bibliothèques que j'ai énumérés et liés à la documentation pour chacun d'eux.

Sources:

ce sont toutes les bibliothèques:

espérons que cela vous aidera à prendre une décision sur la bibliothèque à utiliser:)

sous-processus

sous-processus permet d'appeler des commandes externes et de les connecter à leurs pipes d'entrée/sortie/erreur (stdin, stdout et stderr). Subprocess est le choix par défaut pour exécuter des commandes, mais parfois d'autres modules sont meilleurs.

subprocess.run(["ls", "-l"]) # Run command
subprocess.run(["ls", "-l"], stdout=subprocess.PIPE) # This will run the command and return any output
subprocess.run(shlex.split("ls -l")) # You can also use the shlex library to split the command

os

os est utilisé pour "système d'exploitation dépendant de la fonctionnalité". Il peut également être utilisé pour appeler des commandes externes avec os.system et os.popen (Note: Il y a aussi un sous-processus.popen). os exécutera toujours le shell et est une alternative simple pour les gens qui n'ont pas besoin, ou ne savent pas comment utiliser subprocess.run .

os.system("ls -l") # run command
os.popen("ls -l").read() # This will run the command and return any output

sh

sh est une interface de sous-processus qui vous permet d'appeler des programmes comme s'ils étaient des fonctions. Ceci est utile si vous souhaitez exécuter une commande plusieurs fois.

sh.ls("-l") # Run command normally
ls_cmd = sh.Command("ls") # Save command as a variable
ls_cmd() # Run command as if it were a function

plumbum

plumbum est une bibliothèque de programmes en Python. Vous pouvez appeler des programmes comme des fonctions comme dans sh . Plumbum est utile si vous souhaitez exécuter un pipeline sans la coquille.

ls_cmd = plumbum.local("ls -l") # get command
ls_cmd() # run command

pexpect

pexpect vous permet de lancer des applications enfant, de les contrôler et de trouver des modèles dans leur sortie. C'est une meilleure alternative au sous-processus pour les commandes qui s'attendent à un tty sur Unix.

pexpect.run("ls -l") # Run command as normal
child = pexpect.spawn('scp foo user@example.com:.') # Spawns child application
child.expect('Password:') # When this is the output
child.sendline('mypassword')

tissu

tissu est une bibliothèque python 2.5 et 2.7. Il vous permet d'exécuter des commandes shell locales et distantes. Fabric est une alternative simple pour exécuter des commandes dans un shell sécurisé (SSH)

fabric.operations.local('ls -l') # Run command as normal
fabric.operations.local('ls -l', capture = True) # Run command and receive output

envoyé

envoyé est connu sous le nom "sous-processus pour l'homme". Il est utilisé pour envelopper le module subprocess .

r = envoy.run("ls -l") # Run command
r.std_out # get output

commandes

commands contient des fonctions d'enrubannage pour os.popen , mais il a été supprimé de Python 3 depuis subprocess est une meilleure alternative.

Le montage a été basée sur J. F. Sebastian commentaire.

52
répondu Tom Fuller 2017-05-28 23:14:34

Si vous avez besoin de la sortie de la commande que vous appelez, vous pouvez alors utiliser le sous-processus .check_output (Python 2.7+).

>>> subprocess.check_output(["ls", "-l", "/dev/null"])
'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'

note également le paramètre shell .

si shell est True , la commande spécifiée sera exécutée à travers le shell. Cela peut être utile si vous utilisez Python principalement pour le flux de contrôle amélioré qu'il offre sur la plupart des systèmes shells et veulent toujours un accès pratique à d'autres fonctionnalités de shell telles que les pipes shell, les caractères génériques des noms de fichiers, l'extension de la variable d'environnement, et l'extension de ~ vers le répertoire personnel d'un utilisateur. Cependant, notez que Python lui-même offre des implémentations de nombreuses fonctionnalités de type shell (en particulier, glob , fnmatch , os.walk() , os.path.expandvars() , os.path.expanduser() , et shutil ).

47
répondu Facundo Casco 2018-06-03 20:18:34

C'est comme ça que je exécute mes commandes. Ce code a tout ce dont vous avez besoin

from subprocess import Popen, PIPE
cmd = "ls -l ~/"
p = Popen(cmd , shell=True, stdout=PIPE, stderr=PIPE)
out, err = p.communicate()
print "Return code: ", p.returncode
print out.rstrip(), err.rstrip()
42
répondu Usman Khan 2012-10-28 05:44:05

Avec Bibliothèque Standard

le Utiliser module de sous-processus (Python 3):

import subprocess
subprocess.run(['ls', '-l'])

C'est la norme recommandée. Cependant, des tâches plus compliquées (pipes, outputs, input, etc.) peut être fastidieux de construire et d'écrire.

Note sur la version Python: Si vous utilisez toujours Python 2, subprocess.appeler fonctionne de manière similaire.

ProTip: shlex.split peut vous aider à analyser la commande pour run , call , et d'autres subprocess fonctions dans le cas où vous ne voulez pas (ou vous ne pouvez pas!) les fournir sous forme de listes:

import shlex
import subprocess
subprocess.run(shlex.split('ls -l'))

Avec Dépendances Externes

si vous ne faites pas attention aux dépendances externes, utilisez plumbum :

from plumbum.cmd import ifconfig
print(ifconfig['wlan0']())

C'est le meilleur emballage subprocess . Il est multi-plateforme, c'est-à-dire qu'il fonctionne à la fois sur Windows et sur des systèmes de type Unix. Installation par pip install plumbum .

une autre bibliothèque populaire est sh :

from sh import ifconfig
print(ifconfig('wlan0'))

Toutefois, sh a chuté de support de Windows, de sorte qu'il n'est pas aussi impressionnant qu'il a utilisé pour être. Installer par pip install sh .

39
répondu Honza Javorek 2018-09-19 13:55:27

mise à jour:

subprocess.run est l'approche recommandée à partir de Python 3.5 si votre code n'a pas besoin de maintenir la compatibilité avec les versions antérieures de Python. C'est plus cohérent et offre la même facilité d'utilisation que l'Envoyé. (Tuyauterie n'est pas aussi simple. Voir cette question pour savoir comment .)

Voici quelques exemples de les docs .

Lancer un processus:

>>> subprocess.run(["ls", "-l"])  # doesn't capture output
CompletedProcess(args=['ls', '-l'], returncode=0)

Élever sur l'échec de l'exécution:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1

sortie de Capture:

>>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE)
CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0,
stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')

réponse originale:

je vous recommande d'essayer Envoyé . C'est un wrapper pour subprocess, qui à son tour vise à remplacer les anciens modules et fonctions. Envoy est un sous-processus pour les humains.

exemple d'utilisation de le readme :

>>> r = envoy.run('git config', data='data to pipe in', timeout=2)

>>> r.status_code
129
>>> r.std_out
'usage: git config [options]'
>>> r.std_err
''

Pipe trucs autour de trop:

>>> r = envoy.run('uptime | pbcopy')

>>> r.command
'pbcopy'
>>> r.status_code
0

>>> r.history
[<Response 'uptime'>]
36
répondu Joe 2017-05-23 12:26:36

sans la sortie du résultat:

import os
os.system("your command here")

avec sortie du résultat:

import commands
commands.getoutput("your command here")
or
commands.getstatusoutput("your command here")
32
répondu Zuckonit 2017-05-28 22:59:14

https://docs.python.org/2/library/subprocess.html

...ou pour une commande très simple:

import os
os.system('cat testfile')
24
répondu Ben Hoffstein 2014-11-02 04:00:55

il y a aussi Plumbum

"
>>> from plumbum import local
>>> ls = local["ls"]
>>> ls
LocalCommand(<LocalPath /bin/ls>)
>>> ls()
u'build.py\ndist\ndocs\nLICENSE\nplumbum\nREADME.rst\nsetup.py\ntests\ntodo.txt\n'
>>> notepad = local["c:\windows\notepad.exe"]
>>> notepad()                                   # Notepad window pops up
u''                                             # Notepad window is closed by user, command returns
23
répondu stuckintheshuck 2014-10-10 17:41:13

os.system est OK, mais un peu daté. Il n'est également pas très sécurisé. Au lieu de cela, essayez subprocess . subprocess n'appelle pas directement sh et est donc plus sûr que os.system .

obtenir plus d'information ici .

23
répondu Martin W 2016-12-10 13:25:05

utiliser:

import os

cmd = 'ls -al'

os.system(cmd)

os-ce module fournit une façon portable d'utiliser la fonctionnalité dépendante du système d'exploitation.

pour les fonctions plus os , ici est la documentation.

22
répondu Priyankara 2017-05-28 23:05:23

cela peut être aussi simple:

import os
cmd = "your command"
os.system(cmd)
19
répondu Samadi Salahedine 2018-06-08 12:06:53

appel à une commande externe en Python

Simple, utiliser subprocess.run , qui renvoie un CompletedProcess objet:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

pourquoi?

à partir de Python 3.5, la documentation recommande le sous-processus .exécuter :

l'approche recommandée pour invoquer des sous-processus est d'utiliser la fonction run() pour tous les cas d'utilisation it peut gérer. Pour les cas d'utilisation plus avancés, L'interface Popen sous-jacente peut être utilisée directement.

voici un exemple de l'usage le plus simple possible - et il fait exactement comme demandé:

>>> import subprocess
>>> completed_process = subprocess.run('python --version')
Python 3.6.1 :: Anaconda 4.4.0 (64-bit)
>>> completed_process
CompletedProcess(args='python --version', returncode=0)

run attend la commande pour terminer avec succès, puis renvoie un objet CompletedProcess . Il peut à la place soulever TimeoutExpired (si vous lui donnez un argument timeout= ) ou CalledProcessError (si elle échoue et vous passez check=True ).

comme vous pouvez le déduire de l'exemple ci-dessus, stdout et stderr sont tous les deux raccordés à votre propre stdout et stderr par défaut.

, Nous pouvons inspecter l'objet retourné et voir la commande qui a été donné et le code_retour:

>>> completed_process.args
'python --version'
>>> completed_process.returncode
0

la Capture de la sortie

Si vous voulez capturer la sortie, vous pouvez passer subprocess.PIPE approprié stderr ou stdout :

>>> cp = subprocess.run('python --version', 
                        stderr=subprocess.PIPE, 
                        stdout=subprocess.PIPE)
>>> cp.stderr
b'Python 3.6.1 :: Anaconda 4.4.0 (64-bit)\r\n'
>>> cp.stdout
b''

(je trouve intéressant et légèrement contre-intuitif que la version info soit mise à stderr au lieu de stdout.)

passer une liste de commande

on peut facilement passer de la fourniture manuelle d'une chaîne de commande (comme le suggère la question) à la fourniture d'une chaîne construite par programmation. ne construisez pas de chaînes par programmation. il s'agit d'un problème de sécurité potentiel. Il est préférable de supposer que vous ne faites pas confiance entrée.

>>> import textwrap
>>> args = ['python', textwrap.__file__]
>>> cp = subprocess.run(args, stdout=subprocess.PIPE)
>>> cp.stdout
b'Hello there.\r\n  This is indented.\r\n'

Note, seulement args doit être passé en position.

Signature Complète

Voici la signature réelle dans la source et comme indiqué par help(run) :

def run(*popenargs, input=None, timeout=None, check=False, **kwargs):

les popenargs et kwargs sont donnés au constructeur Popen . input peut être une chaîne d'octets (ou unicode, si spécifier le codage ou universal_newlines=True ) qui sera acheminé par canalisation au stdin du sous-procédé.

la documentation décrit timeout= et check=True mieux que je ne pourrais:

l'argument timeout est passé à Popen.communiquer.)( Si le délai d'attente expire, le processus de l'enfant sera tué, et attendit. Le TimeoutExpired exception sera relancé après le processus de l'enfant a résilié.

si le contrôle est vrai, et le processus de sortie avec un code de sortie non nul, a L'exception appelée processerror sera soulevée. Les attributs de cette exception hold les arguments, le code de sortie, et stdout et stderr si ils ont été capturés.

et cet exemple pour check=True est meilleur que celui que j'ai pu trouver:

>>> subprocess.run("exit 1", shell=True, check=True)
Traceback (most recent call last):
  ...
subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1
"1519440920 Étendue" Signature

Voici une signature étendue, comme indiqué dans le documentation:

subprocess.run(args, *, stdin=None, input=None, stdout=None, stderr=None, 
shell=False, cwd=None, timeout=None, check=False, encoding=None, 
errors=None)

Notez que cette option indique que seuls les arguments de la liste doit être passé en position. Passez donc les arguments restants comme des arguments de mots-clés.

Popen

quand utiliser Popen à la place? Je me battrais pour trouver un cas d'utilisation basé sur les seuls arguments. L'utilisation directe de Popen vous donnerait cependant accès à ses méthodes, y compris poll , 'send_signal", de "mettre fin", et "d'attendre".

Voici la signature Popen comme indiqué dans la source . Je pense que c'est l'encapsulation la plus précise de l'information (par opposition à help(Popen) ):

def __init__(self, args, bufsize=-1, executable=None,
             stdin=None, stdout=None, stderr=None,
             preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
             shell=False, cwd=None, env=None, universal_newlines=False,
             startupinfo=None, creationflags=0,
             restore_signals=True, start_new_session=False,
             pass_fds=(), *, encoding=None, errors=None):

mais plus instructif est le Popen documentation :

subprocess.Popen(args, bufsize=-1, executable=None, stdin=None,
                 stdout=None, stderr=None, preexec_fn=None, close_fds=True,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0, restore_signals=True,
                 start_new_session=False, pass_fds=(), *, encoding=None, errors=None)

Exécuter un programme enfant dans un nouveau processus. Sur POSIX, la classe utilise OS.execvp () - comme comportement pour exécuter le programme enfant. Sur Windows, la classe utilise la fonction Windows CreateProcess (). Les arguments pour Les Popen sont les suivants.

comprendre la documentation restante sur Popen sera laissé comme un exercice pour le lecteur.

18
répondu Aaron Hall 2017-10-18 16:37:52

subprocess.check_call est pratique si vous ne voulez pas tester les valeurs de retour. Il jette une exception sur toute erreur.

16
répondu cdunn2001 2011-01-18 19:21:44

os.system ne vous permet pas de stocker des résultats, donc si vous voulez stocker des résultats dans une liste ou quelque chose subprocess.call fonctionne.

15
répondu Saurabh Bangad 2012-06-11 22:45:35

j'ai tendance à utiliser sous-processus avec shlex (pour traiter échapper des chaînes entre guillemets):

>>> import subprocess, shlex
>>> command = 'ls -l "/your/path/with spaces/"'
>>> call_params = shlex.split(command)
>>> print call_params
["ls", "-l", "/your/path/with spaces/"]
>>> subprocess.call(call_params)
15
répondu Emil Stenström 2014-04-30 14:37:04

plug honteux, j'ai écrit une bibliothèque pour ceci :P https://github.com/houqp/shell.py

c'est essentiellement un emballage pour popen et shlex pour le moment. Il supporte également les commandes piping pour vous permettre d'enchaîner plus facilement les commandes en Python. Donc vous pouvez faire des choses comme:

ex('echo hello shell.py') | "awk '{print }'"
13
répondu houqp 2014-05-01 20:49:01

vous pouvez utiliser Popen, puis vous pouvez vérifier le statut de la procédure:

from subprocess import Popen

proc = Popen(['ls', '-l'])
if proc.poll() is None:
    proc.kill()

Check out subprocess.Popen .

13
répondu admire 2017-05-28 23:01:49

j'aime bien shell_command pour sa simplicité. Il est construit sur le module de sous-processus.

voici un exemple tiré du docs:

>>> from shell_command import shell_call
>>> shell_call("ls *.py")
setup.py  shell_command.py  test_shell_command.py
0
>>> shell_call("ls -l *.py")
-rw-r--r-- 1 ncoghlan ncoghlan  391 2011-12-11 12:07 setup.py
-rw-r--r-- 1 ncoghlan ncoghlan 7855 2011-12-11 16:16 shell_command.py
-rwxr-xr-x 1 ncoghlan ncoghlan 8463 2011-12-11 16:17 test_shell_command.py
0
13
répondu mdwhatcott 2017-10-24 19:29:34

pour récupérer l'identifiant du réseau à partir du neutron openstack:

#!/usr/bin/python
import os
netid= "nova net-list | awk '/ External / { print  }'"
temp=os.popen(netid).read()  /* here temp also contains new line (\n) */
networkId=temp.rstrip()
print(networkId)

la Sortie de nouvelle net-liste

+--------------------------------------+------------+------+
| ID                                   | Label      | CIDR |
+--------------------------------------+------------+------+
| 431c9014-5b5d-4b51-a357-66020ffbb123 | test1      | None |
| 27a74fcd-37c0-4789-9414-9531b7e3f126 | External   | None |
| 5a2712e9-70dc-4b0e-9281-17e02f4684c9 | management | None |
| 7aa697f5-0e60-4c15-b4cc-9cb659698512 | Internal   | None |
+--------------------------------------+------------+------+

sortie de print (networkId)

27a74fcd-37c0-4789-9414-9531b7e3f126
12
répondu IRSHAD 2016-07-20 09:50:01

sous Linux, au cas où vous souhaiteriez appeler une commande externe qui s'exécutera indépendamment (continuera à courir après la fin du script python), vous pouvez utiliser une file d'attente simple comme task spooler ou la à commande

Un exemple de la tâche spouleur:

import os
os.system('ts <your-command>')

Notes sur la tâche de spouleur ( ts ):

  1. nombre de processus concurrents à exécuter ("slots") avec:

    ts -S <number-of-slots>

  2. installer ts ne nécessite pas de privilèges admin. Vous pouvez télécharger et compiler à partir des sources avec un simple make , l'ajouter à votre chemin et vous avez terminé.

12
répondu Yuval Atzmon 2016-11-27 00:15:34