subprocess.call()在Mac和Linux上失败

时间:2014-04-24 02:21:14

标签: python linux macos subprocess

我遇到了一个与subprocess.call()函数有关的奇怪问题。我正在尝试执行Java' jar'使用subprocess.call()的命令。这是代码:

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
$

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

2 个答案:

答案 0 :(得分:1)

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

subprocess.call(jar_cmd, shell=True)

答案 1 :(得分:1)

使用列表(序列)参数而不是字符串the docs say

  

所有调用都需要args,并且应该是字符串或序列   程序参数。 通常提供一系列参数   首选,因为它允许模块处理任何所需的   转义和引用参数(例如,允许文件中的空格   名)。 如果传递单个字符串,则shell必须为True (请参阅   或者字符串必须简单地命名要执行的程序   没有指定任何参数。

示例:

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引发异常。