2014-04-24 3 views
1

Je rencontre un problème étrange avec la fonction subprocess.call(). Je suis en train d'exécuter la commande 'jar' de Java en utilisant subprocess.call(). Voici le code:subprocess.call() échoue sous Mac et Linux

import os 
import subprocess 
def read_war(): 
    war_file_path = "jackrabbit-webapp-2.6.5.war" 
    java_home = os.environ['JAVA_HOME'] 
    jar_path = os.path.join(java_home, 'bin', 'jar') 
    jar_cmd = jar_path + ' tvf ' + war_file_path 
    print "command to be executed is : " + jar_cmd 
    subprocess.call(jar_cmd) 
read_war() 

J'utilise Python v2.7.3 sur Windows et Linux (Oracle Enterprise Linux). Sur Windows 7, je vois le contenu du fichier war affiché. Sous Linux, cependant, je vois un « tel fichier ou répertoire » erreur .:

$ python example.py 
command to be executed is : /usr/local/tools/jdk1.7.0_15/bin/jar tvf jackrabbit-webapp-2.6.5.war 
Traceback (most recent call last): 
    File "example.py", line 24, in <module> 
    read_war() 
    File "example.py", line 23, in read_war 
    subprocess.call(jar_cmd) 
    File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 493, in call 
    return Popen(*popenargs, **kwargs).wait() 
    File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 679, in __init__ 
    errread, errwrite) 
    File "/usr/local/tools/Python-2.7.3/Lib/subprocess.py", line 1249, in _execute_child 
    raise child_exception 
OSError: [Errno 2] No such file or directory 
$ 

J'ai essayé la commande « /usr/local/tools/jdk1.7.0_15/bin/jar TVF jackrabbit- webapp-2.6.5.war 'à partir de l'invite de commande et cela fonctionne très bien. Donc, rien ne va pas avec la commande. J'ai essayé différentes combinaisons de subprocess.call() - en passant une chaîne de caractères, en passant une liste etc. Aucun d'eux n'a fonctionné. Toute aide serait appréciée.

+0

Résolu en utilisant shell = True comme suggéré par tdelaney. Je pourrais avoir juré que j'ai utilisé cette approche et il a échoué. Doit avoir été une erreur de l'opérateur. Merci encore. –

Répondre

1

Ajouter shell = True à l'appel. Sous Windows, la commande CreateProcess effectue l'analyse des chaînes pour séparer la commande et ses différents arguments. Sous linux, vous n'obtenez un traitement de chaîne que si vous spécifiez spécifiquement à subprocess d'appeler le shell. Sinon, il traite toute la chaîne que vous avez passée comme la commande et vous n'allez pas très loin.

subprocess.call(jar_cmd, shell=True) 
+2

Ou, passez une liste d'arguments à la place. C'est inutile de fusionner les parties en une seule chaîne séparée par un espace, puis d'appeler le shell pour le séparer à nouveau. – tripleee

0

Utilisez un lieu argument (séquence) liste d'une chaîne comme the docs say:

args est nécessaire pour tous les appels et doivent être une chaîne, ou une séquence des arguments du programme. Fournir une séquence d'arguments est généralement préféré, car il permet au module de prendre en charge toute échappée requise et de citer des arguments (par exemple, pour autoriser des espaces dans le fichier noms). Si vous passez une seule chaîne, l'une ou l'autre des coquilles doit être True (voir ci-dessous) sinon la chaîne doit simplement nommer le programme à exécuter sans spécifier d'argument.

Exemple:

import os 
import subprocess 

def read_war(): 
    war_file_path = "jackrabbit-webapp-2.6.5.war" 
    jar_path = os.path.join(os.environ['JAVA_HOME'], 'bin', 'jar') 
    jar_cmd = [jar_path, 'tvf', war_file_path] 
    print("command to be executed is: %s" % jar_cmd) 
    subprocess.check_call(jar_cmd) 

read_war() 

Je l'ai utilisé check_call pour soulever une exception si la commande retourne l'état de sortie non nul.

Questions connexes