使用不带shell=false且来自数组的变量的子进程时出现Python错误
我有一个代码片段,它与shell=True一起工作,这是不安全的,当我试图删除shell=True并包含shell=False时,程序会出错 代码如下:使用不带shell=false且来自数组的变量的子进程时出现Python错误,python,arrays,python-3.x,list,subprocess,Python,Arrays,Python 3.x,List,Subprocess,我有一个代码片段,它与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))
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()
命令将作为字符串传递给
subprocess.Popen
。这在使用shell=True
时有效,因为shell可以将命令作为单个字符串接受。但是当shell=False
时,Popen希望命令是参数列表,第一个参数是要运行的程序的完整路径。(这是假设您在POSIX机器上,而不是Windows上。)
基本上,代码是“运行一个名为git clone的程序https://github.com/laramies/theHarvester.git
不带参数”而不是“运行git
带参数clone
和https://github.com/laramies/theHarvester.git
”
&
也应该被删除,因为这是一个shell特性,如果shell=False
,它将作为它无法理解的参数传递给git。不过,您不需要它,因为该进程无论如何都将在后台运行
像这样的方法应该会奏效:
subprocess.Popen(["/usr/bin/git", "clone", "https://github.com/{}".format(item)])
此处的更多信息:将命令组件替换为字符串,然后在空格上拆分,这本身就是不安全的。即使您不使用shell,如果传递给您的不是username/reponame
表单中包含的内容,例如,username/reponame/etc/foobar
,那么如果代码由具有相关权限的用户运行,您将创建/etc/foobar
。也就是说,修复方法是停止替换为字符串,这些字符串将被解析为具有语法意义的空格。(使用shell=True
更糟糕,因为$foo
、$(foo)
、>foo
,以及许多其他东西也是语法)