为什么subprocess.call([' python',argsStr])无论是否有shell = True都会失败?

时间:2018-02-20 22:47:14

标签: python subprocess

所以,我有一个遗留脚本ts,我需要使用几个字符串参数在循环中调用:

#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) 

现在,当我运行它时,它调用python2.7并打开Python shell而不是将其作为python2.7 runcom运行。

如何让它作为脚本运行而不是打开shell?

2 个答案:

答案 0 :(得分:1)

如何解决

args = ['script.py', 'first argument', 'second argument']
subprocess.call(['python2.7'] + args)
  • 不要使用shell=True
  • 将每个参数作为单独的列表项传递;不要将它们连接成一个字符串。

为什么失败(使用shell=True

让我们来看一个简单的案例:

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

实际上做了什么

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

实际上做了什么?它运行python2.7完全没有参数(因为参数列表被解释为$0实例的sh -c,但是在列表的第一个元素中传递的脚本只包含字符串{ {1}}并且根本不看python2.7

为什么失败(没有$0

让我们来看一个简单的案例:

shell=True

实际上做了什么

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

... 做了什么,即使你当前目录中有# the above is the same as running this at a shell python2.7 'script.py first argument second argument'

script.py

为什么会这样?因为您将参数设置为脚本文件名的一部分,并且不存在具有这些参数值作为其名称一部分的文件名。

答案 1 :(得分:0)

链接的答案并没有直接回答我的问题

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

如果在子进程内部构造,则runco​​m可以正常工作。但如果我在外面构建它,我会得到一个无文件错误。