Domanda

I'm running into a weird issue with subprocess.call() function. I am trying to execute Java's 'jar' command using subprocess.call(). Here's the code:

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

I'm using Python v2.7.3 on both Windows and Linux (Oracle Enterprise Linux). On Windows 7, I see the contents of the war file being displayed. On Linux, however, I see a 'no such file or directory' error.:

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

I've tried the command '/usr/local/tools/jdk1.7.0_15/bin/jar tvf jackrabbit-webapp-2.6.5.war' from command prompt and it works fine. So, nothing's wrong with the command. I've tried various combinations of subprocess.call() - passing a string, passing a list etc. None of them worked. Any help at all would be appreciated.

È stato utile?

Soluzione

Add shell=True to the call. On windows, the CreateProcess command does string parsing to separate the command and its various arguments. On linux, you only get string processing if you specifically tell subprocess to call the shell. Otherwise, it treats that entire string you handed in as the command and you don't get very far.

subprocess.call(jar_cmd, shell=True)

Altri suggerimenti

Use a list (sequence) argument instead of a string as the docs say:

args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.

Example:

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

I've used check_call to raise an exception if the command returns non-zero exit status.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top