2014-04-24 49 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命令返回非零退出狀態時拋出異常。