2014-04-24 37 views
1

我遇到了一个奇怪的问题与subprocess.call()函数。我正在尝试使用subprocess.call()来执行Java的'jar'命令。代码如下:subprocess.call()在Mac和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() 

我在Windows和Linux(Oracle Enterprise Linux)上都使用Python v2.7.3。 在Windows 7上,我看到正在显示的war文件的内容。在Linux上,但是,我看到了“没有这样的文件或目录”错误:

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

我试着命令“/usr/local/tools/jdk1.7.0_15/bin/jar TVF jackrabbit- webapp-2.6.5.war'从命令提示符,它工作正常。所以,这个命令没什么问题。 我已经尝试了subprocess.call()的各种组合 - 传递一个字符串,传递一个列表等。他们都没有工作。任何帮助都将不胜感激。

+0

通过使用shell = True解决tdelaney建议。我可以发誓我使用了这种方法,但失败了。一定是操作员错误。再次感谢。 –

回答

1

将shell = True添加到调用中。在Windows上,CreateProcess命令执行字符串解析来分离命令及其各种参数。在linux上,如果你明确告诉子进程调用shell,你只能得到字符串处理。否则,它把你交给你的整个字符串作为命令处理,你不会走得太远。

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

或者,传入参数列表。将各部分合并为一个空格分隔的字符串,然后调用shell再次将其分开,这种毫无意义的做法是毫无意义的。 – tripleee

0

使用列表(序列)的说法,而不是字符串为the docs say

ARGS所需的所有来电,应该是一个字符串,或者程序参数的顺序 。 提供一系列参数通常是 首选,因为它允许模块负责转义和引用参数(例如,允许在文件 名称中的空格)任何所需的 。 如果传递单个字符串,则任何一个shell必须为真(请参见下面的 ),否则字符串必须简单地命名要执行的程序 而不指定任何参数。

例子:

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

我用check_call命令返回非零退出状态时抛出异常。