2015-03-26 5 views
0

Я звоню mencoder из функции python (2.7.3) с subprocess.call (я использую ipython), но он не работает, а когда я скопировать и вставить команду на терминале оболочка это делает. Кажется, я делаю какую-то глупую ошибку со струнами. Я очень смущен, потому что я запускаю эту функцию python на двух разных вычислительных кластерах, с той же версией python, но с другой версией mencoder, и эта команда работает на одном кластере, но не на другом.питон: вызов команды оболочки с подпроцессом

это python скрипт

base = r'/home/afylot/pics/' 
var = r'b2component' 
os.chdir(base) 
listdir = [x[0] for x in os.walk('.')][1:-1] 
listdir.reverse() 
dirs = ','.join(listdir) 
dirs2=dirs.replace(r"./z",r"") 
def cmd2(x): return r"mencoder mf://z{"+dirs2+"}/"+x+r".png -mf fps=1 -ovc lavc -o "+x+r"_mpeg4.avi" 
def cmd3(x): return r"mencoder -speed 1/4 "+x+r"_mpeg4.avi -ovc copy -nosound -o "+x+r"_smpeg4.avi" 
res2=subprocess.call([cmd2(var)],shell=True) 
res3=subprocess.call([cmd3(var)],shell=True) 

и это сообщение об ошибке:

MEncoder SVN-r37381-4.6 (C) 2000-2015 MPlayer Team 
success: format: 16 data: 0x0 - 0x0 
MF file format detected. 
[mf] filelist: z{5.056,4.996,4.936,4.877,4.819,4.762,4.705,4.648,4.592,4.537,4.482,4.428,4.374,4.321,4.268,4.216,4.164,4.113,4.063,4.012,3.963,3.914,3.865,3.817,3.769,3.722,3.675,3.629,3.583,3.538,3.493,3.448,3.404,3.361,3.317,3.275,3.232,3.190,3.149,3.108,3.067,3.027,2.987,2.909,2.870,2.832,2.794,2.756,2.719,2.682,2.646,2.609,2.574,2.538,2.503,2.469,2.434,2.400,2.367,2.333,2.300,2.268,2.235,2.203,2.171,2.140,2.109,2.078,2.048}/b2component.png 
[mf] number of files: 0 
Segmentation fault (core dumped) 
MEncoder SVN-r37381-4.6 (C) 2000-2015 MPlayer Team 
File not found: 'b2component_mpeg4.avi' 
Failed to open b2component_mpeg4.avi. 
Cannot open file/device. 

Exiting... 

С другой кластер команда из функции python работает. Если на том же кластере, я пытаюсь запустить команду из терминала, он также работает

mencoder mf://z{5.056,4.996,4.936,4.877,4.819,4.762,4.705,4.648,4.592,4.537,4.482,4.428,4.374,4.321,4.268,4.216,4.164,4.113,4.063,4.012,3.963,3.914,3.865,3.817,3.769,3.722,3.675,3.629,3.583,3.538,3.493,3.448,3.404,3.361,3.317,3.275,3.232,3.190,3.149,3.108,3.067,3.027,2.987,2.909,2.870,2.832,2.794,2.756,2.719,2.682,2.646,2.609,2.574,2.538,2.503,2.469,2.434,2.400,2.367,2.333,2.300,2.268,2.235,2.203,2.171,2.140,2.109,2.078,2.048}/b2component.png -mf fps=1 -ovc lavc -o b2component_mpeg4.avi 

На кластере А, где функция python терпит неудачу, я bash 4.2.25. На кластере B, где функция python работает, я бег tcsh 6.17.00


Я испытал ту же команду с групповыми символами (например, * и ?), и она работает из функции питона. Проблема заключается в фигурных скобках {}. Самое забавное, что на кластере B, который работает tcsh, подстановочные знаки не работают, но скобки работают!

Может ли кто-нибудь предложить, как преодолеть это ограничение с помощью брекетов? потому что я хочу контролировать порядок dirs2 из функции python, поэтому использование * не будет делать то, что я хочу.

+0

ли '/ дома/afylot/фото/каталог' существует на обоих хосты? –

+0

Да, также потому, что, как вы можете видеть из сообщения об ошибке, dirs2 построен правильно – simona

+0

Ах, правда. Проверить разрешения на этот каталог на отказоустойчивом хосте? –

ответ

0

проблема была такой же, как и в Curly Braces in python Popen , и решение заключается в использовании

subprocess.call(cmd2(v), shell=True, executable='/bin/bash') 

, потому что в противном случае shell=True работает /bin/sh

+1

Я бы избегал 'shell = True' и вместо аргументов передавал вместо этого:' call (["mencoder"] + ["mf: // {path}/{x} {r} .png" .format (* * vars()) для пути в listdir] + ["-mf", "fps = 1", "-ovc", "lavc", "-o", x + r + "_ mpeg4.avi"]) ' – jfs