使用没有shell = false的子进程和来自数组的变量的Python错误

问题描述 投票:2回答:1

我有与shell = True一起使用的代码片段,这是不安全的,当我尝试删除shell = True并包含shell = False时程序错误输出

代码如下:

cmd = "git clone https://github.com/{} &"    
#define a worker function
def worker():
    while True:
        item = q.get()
        subprocess.Popen(cmd.format(item))
        q.task_done()

我收到以下错误:

File "rapid.py", line 56, in worker
    subprocess.Popen(cmd.format(item))
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 775, in __init__
    restore_signals, start_new_session)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/subprocess.py", line 1522, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'git clone https://github.com/laramies/theHarvester.git &': 'git clone https://github.com/laramies/theHarvester.git &'

如果我将shell = True添加到子进程行,它运行得很好(见下文),但然后代码因子将其标记为不安全的代码。没有shell = true的任何方法吗?

cmd = "git clone https://github.com/{} &"    
#define a worker function
def worker():
    while True:
        item = q.get()
        subprocess.Popen(cmd.format(item), shell = True)
        q.task_done()
python arrays python-3.x list subprocess
1个回答
2
投票

该命令将作为字符串传递给subprocess.Popen。这在使用shell=True时有效,因为shell可以接受命令作为单个字符串。但是当shell=False,Popen期望命令作为参数列表时,第一个是运行程序的完整路径。 (这假设您使用的是POSIX机器,而不是Windows。)

本质上,代码说“运行一个名为git clone https://github.com/laramies/theHarvester.git而没有参数的程序”而不是“运行带有参数gitclonehttps://github.com/laramies/theHarvester.git”。

还应该删除&,因为这是一个shell特性,并且使用shell=False它将作为一个它不会理解的参数传递给git。但是你不需要它,因为无论如何这个过程都会在后台运行。

这样的事情应该有效:

subprocess.Popen(["/usr/bin/git", "clone", "https://github.com/{}".format(item)])

更多信息:https://docs.python.org/3.7/library/subprocess.html#popen-constructor

© www.soinside.com 2019 - 2024. All rights reserved.