bashshellpython-2.7subprocessmencoder

python: calling shell command with subprocess


I am calling mencoder from a python (2.7.3) function with subprocess.call (I am using ipython), but it doesn't work, whereas when I copy and paste the command on the terminal shell it does. I think I am making some stupid mistake with strings. I am very confused because I am running this python function on two distinct computing clusters, with same python version, but different version of mencoder, and this command works on one cluster but not on the other.

this is the python script

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)

and this is the error message:

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...

On the other cluster the command from within the python function works. If, on the same cluster, I try to launch the command from terminal, it also works

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

On cluster A, where the python function fails, I have bash 4.2.25. On cluster B, where the python function works, I am running tcsh 6.17.00


I have tested the same command with wildcards (like * and ?) and it works from within the python function. The problem is with the braces {}. The funny thing is that on cluster B, that is running tcsh, the wildcards do not work, but the braces do work!

Can anybody suggest how to overcome this limitation with braces? because I want to control the order of dirs2 from within the python function, so using the * will not do what I want.


Solution

  • the problem was the same as in Curly Braces in python Popen , and the solution is to use

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

    because otherwise shell=True runs /bin/sh