web-dev-qa-db-fra.com

Utilisation d'un appel de sous-processus Python pour appeler un script Python

J'ai un script Python qui doit invoquer un autre script Python dans le même répertoire. J'ai fait ceci:

from subprocess import call
call('somescript.py')

J'obtiens l'erreur suivante:

call('somescript.py')
File "/usr/lib/python2.6/subprocess.py", line 480, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.6/subprocess.py", line 633, in __init__
errread, errwrite)
File "/usr/lib/python2.6/subprocess.py", line 1139, in _execute_child

raise child_exception
OSError: [Errno 2] No such file or directory

J'ai cependant le script somescript.py dans le même dossier. Est-ce que j'ai râté quelque chose?

29
user514946

Si 'somescript.py' n'est pas quelque chose que vous pourriez normalement exécuter directement à partir de la ligne de commande (c'est-à-dire, $: somescript.py fonctionne), vous ne pouvez pas l'appeler directement à l'aide de l'appel.

N'oubliez pas que la façon dont Popen fonctionne est que le premier argument est le programme qu'il exécute et les autres sont les arguments passés à ce programme. Dans ce cas, le programme est en fait python, pas votre script. Ainsi, les éléments suivants fonctionneront comme prévu:

subprocess.call(['python', 'somescript.py', somescript_arg1, somescript_val1,...]).

Cela appelle correctement l'interpréteur Python et lui dit d'exécuter votre script avec les arguments donnés.

Notez que ceci est différent de la suggestion ci-dessus:

subprocess.call(['python somescript.py'])

Cela va essayer d'exécuter le programme appelé python somscript.py, qui n'existe clairement pas.

call('python somescript.py', Shell=True)

Fonctionnera également, mais l'utilisation de chaînes comme entrée pour appeler n'est pas multiplateforme, est dangereuse si vous n'êtes pas celui qui construit la chaîne, et devrait généralement être évitée si possible.

37
aruisdante

Les fenêtres? Unix?

Unix aura besoin d'un attribut Shebang et exec pour fonctionner:

#!/usr/bin/env python

comme première ligne de script et:

chmod u+x script.py

en ligne de commande ou

call('python script.py'.split())

comme mentionné précédemment.

Windows devrait fonctionner si vous ajoutez le Shell = True parameter à l'appel "call".

5
Gringo Suave

subprocess.call attend les mêmes arguments que subprocess.Popen - c'est une liste de chaînes (le argv en C) plutôt qu'une seule chaîne.

Il est fort possible que votre processus enfant ait tenté d'exécuter "s" avec les paramètres "o", "m", "e", ...

3
immortal

Regarde ça.

from subprocess import call 
with open('directory_of_logfile/logfile.txt', 'w') as f:
   call(['python', 'directory_of_called_python_file/called_python_file.py'], stdout=f)
3
tanmoy

Si vous êtes sous Linux/Unix, vous pouvez éviter complètement call () et ne pas exécuter une instance entièrement nouvelle de l'exécutable Python et son environnement).

import os

cpid = os.fork()
if not cpid:
    import somescript
    os._exit(0)

os.waitpid(cpid, 0)

Pour ce que ça vaut.

2
tMC

Quel est le problème avec

import sys
from os.path import dirname, abspath

local_dir = abspath(dirname(__file__))
sys.path.append(local_dir)

import somescript

ou mieux encapsuler la fonctionnalité dans une fonction, par ex. baz, alors fais ça.

import sys
from os.path import dirname, abspath

local_dir = abspath(dirname(__file__))
sys.path.append(local_dir)

import somescript
somescript.baz()

Il semble y avoir beaucoup de scripts démarrant python processus ou forking, est-ce une exigence?

1
demented hedgehog
def main(argv):
    Host = argv[0]
    type = argv[1]
    val = argv[2]

    ping = subprocess.Popen(['python ftp.py %s %s %s'%(Host,type,val)],stdout = subprocess.PIPE,stderr = subprocess.PIPE,Shell=True)
    out = ping.communicate()[0]
    output = str(out)
    print output
0
user3489691

Tout d'abord, vérifiez si somescript.py Est exécutable et commence par quelque chose comme #!/usr/bin/python. Si cela est fait, vous pouvez utiliser subprocess.call('./somescript.py').

Ou comme le souligne une autre réponse, vous pouvez faire subprocess.call(['python', 'somescript.py']).

0
Barum Rho