Question

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

Était-ce utile?

La solution

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

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

L'avantage du sous-processus par rapport au système est qu'il est plus flexible (vous pouvez obtenir le stdout, stderr, le & "real &" ; code de statut, meilleure gestion des erreurs, etc ...).

La documentation officielle recommande le sous-processus . > module sur l'alternative os.system ():

  

Le module sous-processus fournit des fonctionnalités plus puissantes pour la création 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 " Remplacement de fonctions plus anciennes avec le module de sous-processus & Quot; La section de la documentation du sous-processus peut contenir des recettes utiles.

Les anciennes versions de Python utilisent l'appel:

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

Autres conseils

Voici un résumé des méthodes permettant d’appeler des programmes externes, ainsi que des avantages et inconvénients de chacun:

  1. os.system("some_command with args") transmet la commande et les arguments au shell de votre système. C'est bien parce que vous pouvez réellement exécuter plusieurs commandes à la fois de cette manière et configurer des canaux et une redirection entrée / sortie. Par exemple:

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

    Cependant, bien que cela soit pratique, vous devez gérer manuellement l'échappement de caractères shell tels que des espaces, etc. Cela vous permet également d'exécuter des commandes qui sont simplement des commandes shell et non des programmes externes. Voir la documentation .

  2. stream = os.popen("some_command with args") fera la même chose que os.system sauf qu'il vous donne un objet de type fichier que vous pouvez utiliser pour accéder aux entrées / sorties standard de ce processus. Il existe 3 autres variantes de popen qui traitent toutes légèrement les entrées / sorties. Si vous transmettez tout en chaîne, votre commande est transmise au shell; si vous les transmettez sous forme de liste, vous n'avez pas à vous soucier d'échapper à rien. Voir la documentation .

  3. La Popen classe du module subprocess. Ceci est destiné à remplacer os.popen mais présente l'inconvénient d'être un peu plus compliqué en raison de son exhaustivité. 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 bon d’avoir toutes les options dans une classe unifiée au lieu de 4 fonctions popen différentes. Voir la documentation .

  4. La call fonction du module subprocess.run. Ceci est fondamentalement juste comme la classe CompletedProcess et prend tous les mêmes arguments, mais attend simplement que la commande se termine et vous donne le code de retour. Par exemple:

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

    Voir la documentation .

  5. Si vous utilisez Python 3.5 ou une version ultérieure, vous pouvez utiliser le nouveau <=> , qui ressemble beaucoup à ce qui précède mais est encore plus flexible et renvoie une <=> après la fin de l'exécution de la commande.

  6. Le module os possède également toutes les fonctions fork / exec / spawn que vous auriez dans un programme C, mais je ne recommande pas de les utiliser directement.

Le module <=> devrait probablement correspondre à ce que vous utilisez.

Enfin, sachez que pour toutes les méthodes dans lesquelles vous passez la commande finale à exécuter par le shell sous forme de chaîne, vous êtes responsable de son échappement. Il y a de graves conséquences pour la sécurité si une partie de la chaîne que vous transmettez ne peut être entièrement approuvée. Par exemple, si un utilisateur entre une partie ou n’importe quelle partie de la chaîne. Si vous n'êtes pas sûr, utilisez uniquement ces méthodes avec des constantes. Pour vous donner une idée des implications, considérons ce code:

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

et imaginez que l'utilisateur entre quelque chose & "; ma mère ne m'aime pas & amp; & amp; rm -rf / " ce qui pourrait effacer tout le système de fichiers.

J'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 stdout données du canal. En fait, vous pouvez simplement omettre ces paramètres (stdout= et stderr=) et ils se comporteront comme os.system().

Quelques astuces sur la séparation du processus enfant du processus appelant (démarrage du processus enfant en arrière-plan).

Supposons que vous souhaitiez lancer une longue tâche à partir d'un script CGI, c'est-à-dire que le processus enfant doit vivre plus longtemps que le processus d'exécution du script CGI.

L'exemple classique tiré de la documentation du module de sous-processus est le suivant:

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 'appelez-sous-processus' jusqu'à ce que le fichier longtask.py soit terminé. Mais il n’est pas clair ce qui se passe après la ligne "un peu plus de code ici" de l’exemple.

Ma plate-forme cible était FreeBSD, mais le développement se faisait sous Windows. J'ai donc d'abord rencontré le problème sous Windows.

Sous Windows (Win XP), le processus parent ne sera pas terminé tant que le fichier longtask.py n’aura pas 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 les mêmes.

La solution consiste à passer DETACHED_PROCESS Indicateur de création de processus sur la fonction CreateProcess sous-jacente dans Win API. Si vous avez installé pywin32, vous pouvez importer l’indicateur à partir 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 indique que l'indicateur sémantiquement correct est CREATE_NEW_CONSOLE (0x00000010) * /

Sous freebsd, nous avons un autre problème: lorsque le processus parent est terminé, il termine également les processus enfants. Et ce n’est pas ce que vous voulez dans CGI-script non plus. Certaines expériences ont montré que le problème semblait être de partager sys.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 plates-formes et je ne connais pas les raisons du comportement de FreeBSD. Si quelqu'un le sait, partagez vos idées, s'il vous plaît. Googler lors du démarrage de processus en arrière-plan en Python n’éclaire pas encore.

Je vous recommanderais d'utiliser le module de sous-processus au lieu de os.system, car le shell vous échappe et est donc beaucoup plus sûr: http://docs.python.org/library/subprocess.html

subprocess.call(['ping', 'localhost'])
import os
cmd = 'ls -al'
os.system(cmd)

Si vous souhaitez renvoyer les résultats de la commande, vous pouvez utiliser os.popen . Cependant, il est déconseillé depuis la version 2.6 d'utiliser le module de sous-processus , quelles autres réponses ont bien couvert.

import os
os.system("your command")

Notez que ceci est dangereux car la commande n'est pas nettoyée. Je vous laisse le soin de rechercher sur Google la documentation pertinente sur les modules «os» et «sys». Il y a un tas de fonctions (exec * et spawn *) qui feront des choses similaires.

Il existe de nombreuses bibliothèques différentes qui vous permettent d’appeler des commandes externes avec Python. Pour chaque bibliothèque, j'ai donné une description et un exemple d'appel d'une commande externe. La commande que j'ai utilisée comme exemple est ls -l (liste tous les fichiers). Si vous souhaitez en savoir plus sur l’une des bibliothèques que j’ai énumérées et reliée à la documentation de chacune d’elles.

  

Sources:

  
    
      

Ce sont toutes les bibliothèques:

    
  

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

  

sous-processus

Le sous-processus vous permet d'appeler des commandes externes et de les connecter à leurs canaux d'entrée / sortie / d'erreur (stdin, stdout et stderr). Le sous-processus est le choix par défaut pour l'exécution 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 & "; fonctionnalité dépendante du système d'exploitation &"; Il peut également être utilisé pour appeler des commandes externes avec os.system et os.popen (Remarque: il existe également un sous-processus.popen). os exécutera toujours le shell et constitue une alternative simple pour les personnes qui n'en ont pas besoin ou qui 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 pour & "script-like &"; Programmes Python. Vous pouvez appeler des programmes tels que des fonctions comme dans sh. Plumbum est utile si vous souhaitez exécuter un pipeline sans le shell.

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

pexpect

pexpect vous permet de créer des applications enfants, de les contrôler et de rechercher des modèles dans leur sortie. C'est une meilleure alternative au sous-processus pour les commandes qui attendent un tty sous 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

fabric 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 appelé & "sous-processus pour les humains &"; Il est utilisé comme un wrapper de commodité autour du subprocess module.

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

commandes

commands contient des fonctions d'encapsulation pour <=>, mais il a été supprimé de Python 3, car <=> constitue une meilleure alternative.

La modification est basée sur le commentaire de J.F. Sebastian.

J'utilise toujours fabric pour ce type de choses, par exemple:

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

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

Regardez un exemple:

from sh import vgdisplay
print vgdisplay()
print vgdisplay('-v')
print vgdisplay(v=True)

Vérifiez le " pexpect " La bibliothèque Python aussi.

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

child = pexpect.spawn('ftp 192.168.0.24')

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

child.sendline('anonymous')

child.expect('(?i)password')

Si vous avez besoin du résultat de la commande que vous appelez, vous pouvez alors utiliser subprocess.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'

Notez également le paramètre shell .

  

Si shell est True, la commande spécifiée sera exécutée via le shell. Cela peut être utile si vous utilisez principalement Python pour le flux de contrôle amélioré proposé par la plupart des interpréteurs de commandes système, tout en souhaitant un accès pratique à d’autres fonctionnalités de l’interpréteur de commandes, telles que les pipes shell, les jokers de nom de fichier, le développement de variables d’environnement et le développement de ~ vers un utilisateur < !> # 8217; répertoire personnel de. 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(), shutil et <=>).

Avec la bibliothèque standard

Le Utilisez le module de sous-processus (Python 3):

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

C’est la méthode standard recommandée. Cependant, des tâches plus complexes (pipes, sortie, entrée, etc.) peuvent être fastidieuses à construire et à écrire.

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

Conseils: shlex.split peut vous aider. vous devez analyser la commande pour run, call et d’autres subprocess fonctions si 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 les dépendances externes ne vous dérangent pas, utilisez plumbum :

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

C’est le meilleur pip install plumbum wrapper. Il est multi-plateforme, c’est-à-dire qu’il fonctionne à la fois sous Windows et sous Unix. Installer par sh.

Une autre bibliothèque populaire est sh :

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

Cependant, pip install sh abandonné le support Windows, il n'est donc plus aussi génial qu'avant. Installer par <=>.

C’est ainsi que j’exécute mes commandes. Ce code contient 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()

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. Il est plus cohérent et offre une facilité d'utilisation similaire à celle d'Envoy. (La tuyauterie n’est cependant pas aussi simple. Voir cette question pour savoir comment .)

Voici quelques exemples tirés de les documents .

Exécuter un processus:

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

Relancer en cas d'é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 . Il s'agit d'un wrapper pour le sous-processus, qui vise à remplacer les anciens modules et fonctions. . Envoy est un sous-processus pour les humains.

Exemple d'utilisation de le fichier Lisez-moi :

>>> 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
''

Diffusez aussi des trucs:

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

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

>>> r.history
[<Response 'uptime'>]

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")

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

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

import os
os.system('cat testfile')

Il existe également des 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

os.system est OK, mais daté. Ce n'est pas très sécurisé non plus. Au lieu de cela, essayez subprocess. <=> n'appelle pas sh directement et est donc plus sécurisé que <=>.

Obtenir plus d'informations ici .

  

Appel d'une commande externe en Python

Simple, utilisez 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?

A partir de Python 3.5, la documentation recommande subprocess.run :

  

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

Voici un exemple d'utilisation la plus simple possible - et il répond exactement à la demande:

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

run attend la fin de la commande, puis renvoie un objet TimeoutExpired. Il peut au lieu de cela soulever timeout= (si vous lui donnez un argument CalledProcessError) ou check=True (s'il échoue et que vous passez subprocess.PIPE).

Comme vous pouvez le déduire de l'exemple ci-dessus, stdout et stderr sont redirigés vers votre propre stdout et stderr par défaut.

Nous pouvons inspecter l'objet renvoyé et voir la commande qui a été donnée et le code de retour:

>>> 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''

Capture de la sortie

Si vous voulez capturer la sortie, vous pouvez passer stderr au stdout ou args:

approprié
>>> 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'

(Je trouve intéressant et légèrement contre-intuitif que les informations de version soient placées dans stderr au lieu de stdout.)

Passer une liste de commandes

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 générée par programme. Ne créez pas de chaînes par programmation. Il s'agit d'un problème de sécurité potentiel. Il vaut mieux supposer que vous ne faites pas confiance à l'entrée.

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

Notez que seul help(run) doit être transmis positionnellement.

Signature complète

Voici la signature réelle dans la source et comme indiqué par popenargs:

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

Les kwargs et Popen sont donnés au constructeur input. universal_newlines=True peut être une chaîne d'octets (ou unicode, si un codage spécifié ou poll) sera acheminée vers le stdin du sous-processus.

La documentation décrit help(Popen) et <=> mieux que moi:

  

L'argument de délai d'attente est passé à Popen.communicate (). Si le délai d'attente   expire, le processus enfant sera tué et attendu. le   L'exception TimeoutExpired sera à nouveau déclenchée une fois le processus enfant terminé.   terminé.

     

Si check est vrai et que le processus se termine avec un code de sortie non nul, un   L'exception CalledProcessError sera déclenchée. Attributs de cela   exception contient les arguments, le code de sortie et stdout et stderr si   ils ont été capturés.

et cet exemple pour <=> est meilleur que celui que je pourrais trouver:

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

Signature développée

Voici une signature étendue, indiquée dans la documentation:

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):

Notez que cela indique que seule la liste des arguments doit être passée positionnellement. Passez donc les arguments restants en tant qu'arguments de mots clés.

Popen

Quand utiliser <=> à la place? J'aurais du mal à trouver un cas d'utilisation basé uniquement sur les arguments. L’utilisation directe de <=> vous donnerait toutefois accès à ses méthodes, notamment <=>, 'send_signal', 'terminate' et 'wait'.

Voici la <=> signature indiquée dans la source . Je pense que c’est l’encapsulation la plus précise de l’information (par opposition à <=>):

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)

Mais la <=> documentation est plus informative:

<*>      

Exécuter un programme enfant dans un nouveau processus. Sur POSIX, la classe utilise   comportement semblable à os.execvp () pour exécuter le programme enfant. Sous Windows,   la classe utilise la fonction Windows CreateProcess (). Les arguments pour   Popen sont comme suit.

Comprendre le reste de la documentation sur <=> sera laissécomme exercice pour le lecteur.

Utiliser:

import os

cmd = 'ls -al'

os.system(cmd)

os - Ce module constitue un moyen portable d’utiliser les fonctionnalités dépendant du système d’exploitation.

Pour les autres os fonctions, , ici , se trouve la documentation. / p>

Cela peut être aussi simple que cela:

import os
cmd = "your command"
os.system(cmd)

utiliser le module os

import os
os.system("your command")

par exemple

import os
os.system("ifconfig")

subprocess.check_call est pratique si vous ne souhaitez pas tester les valeurs de retour. Il lève une exception sur toute erreur.

J'ai tendance à utiliser le sous-processus avec shlex (pour gérer l'échappement des chaînes citées):

>>> 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)

Il y a une autre différence ici qui n'est pas mentionnée précédemment.

subprocess.Popen exécute la & commande > en tant que sous-processus. Dans mon cas, je dois exécuter le fichier & Lt; a & Gt; qui doit communiquer avec un autre programme, < b > ;.

J'ai essayé le sous-processus et l'exécution a réussi. Cependant, & Lt; b & Gt; ne pouvait pas communiquer avec < un > ;. Tout est normal quand je cours les deux à partir du terminal.

Un de plus: (REMARQUE: kwrite se comporte différemment des autres applications. Si vous essayez ce qui suit avec Firefox, les résultats ne seront pas les mêmes.)

Si vous essayez os.system("kwrite"), le flux de programme se bloque jusqu'à ce que l'utilisateur ferme kwrite. Pour surmonter cela, j'ai plutôt essayé os.system(konsole -e kwrite). Ce programme a continué de s’écouler, mais kwrite est devenu le sous-processus de la console.

N'importe qui exécute le kwrite qui n'est pas un sous-processus (c'est-à-dire qu'il doit apparaître dans le moniteur système à l'extrême gauche de l'arborescence).

os.system ne vous permet pas de stocker les résultats. Par conséquent, si vous souhaitez stocker les résultats dans une liste ou quelque chose subprocess.call qui fonctionne.

J'aime assez la shell_command pour sa simplicité. Il est construit sur le module de sous-processus.

Voici un exemple tiré de la documentation:

>>> 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

Prise sans scrupule, j'ai écrit une bibliothèque pour cela: P https://github.com/houqp/shell.py

Pour l’instant, c’est un emballage pour Popen et Shlex. Il prend également en charge les commandes de tuyauterie afin que vous puissiez les chaîner plus facilement en Python. Pour que vous puissiez faire des choses comme:

ex('echo hello shell.py') | "awk '{print $2}'"

Sous Linux, si vous souhaitez appeler une commande externe qui s'exécutera indépendamment (continuera à s'exécuter une fois le script python terminé), vous pouvez utiliser une simple file d'attente comme spouleur de tâches ou en commande

Un exemple avec le spouleur de tâches:

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

Remarques sur le spouleur de tâches (ts):

  1. Vous pouvez définir le nombre de processus simultanés à exécuter (" slots ") avec:

    ts -S <number-of-slots>

  2. L'installation make ne nécessite pas de privilèges d'administrateur. Vous pouvez le télécharger et le compiler à partir des sources avec un simple <=> ajout à la route et le tour est joué.

Vous pouvez utiliser Popen, puis vérifier l'état de la procédure:

from subprocess import Popen

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

Découvrez sous-processus.Popen .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top