2015-09-10 64 views
2

在Python中,我也行:巴貝爾蟒蛇check_output錯誤非零退出狀態2

check_output(['babel', 'www/scripts6/lib/data.js', '>', 'www/scripts/lib/data.js']) 

它給我的錯誤:

subprocess.CalledProcessError: Command '['babel', 'www/scripts6/lib/data.js', '>', 'www/scripts/lib/data.js']' returned non-zero exit status 2 

我難倒。該命令在shell中正常工作。爲什麼Python抱怨?

編輯:使用

print(check_output(['babel', './www/scripts6/lib/data.js', '>', './www/scripts/lib/data.js'], shell=True)) 

代替產生在終端中輸出

b'"use strict";\n\n' 

。這表明,巴貝爾現在正在工作,但巴貝爾正在輸入任何東西,並輸出到終端。

回答

2

您應該通過shell命令作爲一個字符串check_output 。關於這個函數的documentation實際上給出了一個這樣做的例子。在你的情況下,它應該是這樣的:

check_output('path/to/babel ./www/scripts6/lib/data.js > ' 
      './www/scripts/lib/data.js', shell=True) 

documentation上POPEN指出:

On POSIX with shell=True , the shell defaults to /bin/sh . If args is a string, the string specifies the command to execute through the shell. This means that the string must be formatted exactly as it would be when typed at the shell prompt. This includes, for example, quoting or backslash escaping filenames with spaces in them. If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...]) 

check_outputshell=True解釋它的參數相同的方式如上所述。

如果您只使用重定向的外殼,我會建議,而不是這樣做:

check_output(['path/to/babel', './www/scripts6/lib/data.js', 
       '--out-file', './www/scripts/lib/data.js']) 

這將節省您想要的文件的輸出,而不需要產生一個殼。

+0

你輸入的是兩個字符串,而不是單個字符串。這裏:''path/to/babel ./www/scripts6/lib/data.js>' './www/scripts/lib/data.js'' – mareoraft

+1

@mareoraft在Python中,兩個沒有任何順序的字符串干預運算符由解釋器自動連接到單個字符串。 ''a''b''完全等同於''ab''。 (請參閱[此處](https://docs.python.org/2/reference/lexical_analysis.html#string-literal-concatenation)。) – Louis

+0

您提供的第二種解決方案僅適用於babel的完整路徑。如果我的一個開發者將他們的babel存儲在別處,這可能是一個可移植性問題。 – mareoraft

1

我懷疑你需要輸入babel,而不是僅僅babel的完整路徑,但你可以嘗試以下,看看它是否有差別:

check_output(['babel', 'www/scripts6/lib/data.js', '>', 'www/scripts/lib/data.js'], shell=True) 

編輯:關於你編輯,而是採用check_output,讓我們使用subprocess.Popen()

import shlex 
from subprocess import Popen 

with open('./www/scripts/lib/data.js', 'w') as outfile: 
    command = "babel ./www/scripts6/lib/data.js" 
    command_args = shlex.split(command) 
    process = Popen(command_args, stdout=outfile, shell=True) 
    output, err = process.communicate() 
    if err: 
     print err 
+0

我們離得更近了一步。現在只是一個輸入輸出問題。請參閱我的編輯。謝謝! – mareoraft

+0

修復了OUTPUT問題,但不修復INPUT問題。即使通過'command_args = shlex使用完整路徑。split(「babel」+「」+「/ Users/Matthew/programming/prove-math /」+ in_path)',我得到了與輸入空白文件相同的babel輸出。 – mareoraft

0

如前所述,你需要使用shell =真,傳遞一個字符串,使你的代碼的工作,一個簡單的解決方案是使用check_call,傳遞一個文件對象到stdout:

from subprocess import check_call 

with open('./www/scripts/lib/data.js',"w") as f:  
    check_call(['babel', './www/scripts6/lib/data.js'],stdout=f) 

如果你只是擔心重定向輸出,那麼我不認爲需要check_output或任何其他方式來存儲任何輸出,你可能想要嘗試包裝代碼/除了捕獲任何非零退出狀態。您還可以設置cwd

from subprocess import check_call, CalledProcessError 

def babel_sub(cmds, out_f, cwd="."): 
    with open(out_f, "w") as f: 
     try: 
      check_call(cmds, stdout=f, cwd=cwd) 
     except CalledProcessError as e: 
      print(e)