2015-09-10 3 views
2

В питоне, у меня есть строка:столпотворения питон ошибка 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 

я тупик. Команда отлично работает в оболочке. Почему питон жалуется?

EDIT: используя

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

вместо дает выход

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

в терминале. Это говорит о том, что babel теперь работает, но babel принимает НИЧЕГО как его вход и ВЫХОД НА терминал.

ответ

2

Вы должны передать команду оболочки в виде одной строки в 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_output с shell=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) 

EDIT: ссылкой на ваш редактировать, вместо того, чтобы использовать 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/prov-math /" + in_path) ', я получаю тот же вывод babel, что и для пустого ввода файла. – mareoraft

0

Как уже говорилось, вам нужно будет использовать оболочку = True, передавая одну строку, чтобы сделать ваш код работать, более простым решением было бы использовать check_call, передавая объект файла на стандартный вывод:

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 или любых других способах хранения любого результата, вы можете захотеть обернуть код в try/except while и поймать любой ненулевой статус выхода. Вы также можете установить 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) 
Смежные вопросы