【问题标题】:Why does subprocess.call(['python', argsStr]) fail both with or without shell=True?为什么 subprocess.call(['python', argsStr]) 在有或没有 shell=True 的情况下都会失败?
【发布时间】:2018-02-21 08:04:40
【问题描述】:

所以,我有一个旧脚本 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?

【问题讨论】:

  • ts 代码还是文件路径?
  • @JorgeLeitão 我添加了更多信息。 ts 是一个文件。
  • 删除参数shell=True?如果我运行python -c "import subprocess; subprocess.call(['python2.7', 'test.py'])",它会告诉我该文件不存在并退出 1。如果我创建该文件并再次运行,它将运行脚本。
  • 我删除了shell=True,我得到了`[Errno 2] No such file or directory`。即使所有必要的文件都存在。如果我只是直接将 python2.7 runco​​m 复制粘贴到命令行,它就可以工作。所以程序没有问题..

标签: python subprocess


【解决方案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 根本没有参数(因为参数列表被解释为$0sh -c 实例,但在列表的第一个元素中传递的脚本仅包含字符串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.pythat 会做什么?

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

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

【讨论】:

    【解决方案2】:

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

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

    runco​​m,如果在子进程中构建,就可以工作。但是如果我在外面构建它,我会得到一个无文件错误。

    【讨论】:

    • 这是在尝试回答问题吗?
    • 是的,这给了我想要的文件。虽然我确信有更好的方法来做到这一点。我只是把它留在里面,直到出现更好的东西。
    • 不——没有比这更好的了。应该这样做。
    • (嗯——你可以在外面构造它;你需要避免的是把它压缩成一个字符串,而不是把它保存为一个列表)。
    • 谢谢。我不知道这是什么工作。但我现在明白了。
    猜你喜欢
    • 2020-03-29
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多