Python 子进程命令作为列表而不是字符串

标签 python subprocess

我需要使用 Python 中的 subprocess 模块通过重定向标准输出来创建一些新文件。由于存在安全漏洞,我不想使用 shell=True

我写了一些测试命令来解决这个问题,我发现这行得通:

import subprocess as sp
filer = open("testFile.txt", 'w')
sp.call(["ls", "-lh"], stdout=filer)
filer.close()

但是,当我将命令作为一个长字符串而不是列表传递时,它找不到文件。所以当我写这个时:

import subprocess as sp
filer = open("testFile.txt", 'w')
sp.call("ls -lh", stdout=filer)
filer.close()

我收到这个错误:

Traceback (most recent call last):
  File "./testSubprocess.py", line 16, in <module>
    sp.call(command2, stdout=filer)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 524, in call
    return Popen(*popenargs, **kwargs).wait()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 711, in __init__
    errread, errwrite)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1308, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

为什么我将参数作为字符串或列表传递很重要?

最佳答案

这是因为调用发生的方式:

使用 shell=True 时,通过 shell 执行调用,并将命令作为一个字符串提供给 shell。

使用 shell=False 时,通过 execv() 和相关函数直接执行调用。这些函数 expet 一组参数。

如果您只传递一个字符串,它会被视为只包含可执行文件名称而没有参数的调用的缩写。但是您的系统上(可能)没有名为 ls -lh 的可执行文件。

确切地说,在 subprocess.py 的深处,发生了以下情况:

        if isinstance(args, types.StringTypes):
            args = [args]
        else:
            args = list(args)

所以每个传递的字符串都变成了一个只有一个元素的列表。

        if shell:
            args = ["/bin/sh", "-c"] + args

这个我不知道:显然,这允许将额外的参数传递给被调用的 shell。 虽然以这种方式记录,但不要使用它,因为它会造成太多困惑。

如果shell=False,我们在下面还有更远的地方

if env is None:
    os.execvp(executable, args)
else:
    os.execvpe(executable, args, env)

它只获取一个列表并将其用于调用。

关于Python 子进程命令作为列表而不是字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23520775/

相关文章:

javascript - 如果模型中不存在数据,则使用 django 保存数据,如果数据存在则更新

python - 如何将字典中的字符串值转换为 int/float 数据类型?

python - 在 Google Docs 电子表格(如 EXCEL)中创建按钮

python - 子进程权限被拒绝

python - 使用子进程运行单独的 python 程序

python - PANDAS:执行to_excel成功,但没有输出文件

python - ipython:在应用程序中启动内核和内核管理器

python - 从另一个 python 程序运行 python 程序(有一定的要求)

Python子进程文件未找到

python - 如何从 linux 中的打印输出中获取一行?