maximusdooku
maximusdooku

Reputation: 5542

Why does subprocess.call(['python', argsStr]) fail both with or without shell=True?

So, I have a legacy script ts, that I need to call in a loop using several string arguments:

#User supplied
ts = '/d1/user/script.py'
adir = '/d1/user/adir'
mfile = '/d1/user/script.nc'
outdir = '/d1/user/park/'

metens = glob.glob(adir + '/*.nc')  #reads all files

for count, value in enumerate(metens):
    runcom = [ts, mfile, metens[count], outdir + os.path.basename(metens[count])]   
    runcom = " ".join(runcom) #This creates a string of CL arguments
    subprocess.call(['python2.7', runcom], shell=True) 

Now, when I run it, it calls python2.7 and opens the Python shell instead of running it as python2.7 runcom.

How can I make it run as a script instead of opening the shell?

Upvotes: 0

Views: 55

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295989

How To Fix It

args = ['script.py', 'first argument', 'second argument']
subprocess.call(['python2.7'] + args)
  • Don't use shell=True
  • Pass each argument as a separate list item; don't concatenate them into a string.

Why It Fails (with shell=True)

Let's take a simple case:

args = [ 'script.py', 'first argument' 'second argument' ]
args_str = ' '.join(args)
subprocess.call(['python2.7', args_str], shell=True)

What does this actually do?

# the above is the same as running this at a shell
sh -c python2.7 'script.py first argument second argument'

And what does that actually do? It runs python2.7 with no arguments at all (as the argument list is interpreted as $0 to the sh -c instance, but the script passed in the first element of the list contains only the string python2.7 and doesn't look at its $0 at all).


Why It Fails (without shell=True)

Let's take a simple case:

args = [ 'script.py', 'first argument' 'second argument' ]
args_str = ' '.join(args)
subprocess.call(['python2.7', args_str])

What does this actually do?

# the above is the same as running this at a shell
python2.7 'script.py first argument second argument'

...and what does that do, even if you have a script.py in your current directory?

python2.7: can't open file 'script.py first argument second argument': [Errno 2] No such file or directory

Why did that happen? Because you made your arguments part of the script's filename, and no filename with those argument values as part of its name exists.

Upvotes: 1

maximusdooku
maximusdooku

Reputation: 5542

The linked answer doesn't directly answer my question

for count, value in enumerate(metens):
    subprocess.call(['python2.7', ts, mfile, metens[count], outdir + os.path.basename(metens[count]]) 

The runcom, if constructed inside the subprocess, works. But if I construct it outside, I get a no file error.

Upvotes: 0

Related Questions