1 shell=True
shell=True
参数会让subprocess.check_call
接受字符串类型的变量作为命令,并调用shell去执行这个字符串。
import subprocess
cmdline = "ls -l; ls -l"
subprocess.check_call(cmdline, shell=True)
"""
执行结果:
[root@Chasing-Dreams test]# python test.py
total 4
-rw-r--r-- 1 root root 129 May 23 10:50 test.py
total 4
-rw-r--r-- 1 root root 129 May 23 10:50 test.py
"""
2 shell=False
shell=False
参数subprocess.check_call
只接受数组变量作为命令,并将数组的第一个元素作为命令,剩下的全部作为该命令的参数。也就是说shell=False
参数时subprocess.check_call
只接收一条命令。
import subprocess
import shlex
cmdline = "ls -l; ls -l"
cmd = shlex.split(cmdline)
subprocess.check_call(cmdline, shell=True)
"""
执行结果:
[root@Chasing-Dreams test]# python test.py
ls: invalid option -- ';'
Try 'ls --help' for more information.
Traceback (most recent call last):
File "/root/test/test.py", line 8, in <module>
subprocess.check_call(cmd, shell=False)
File "/opt/anaconda3/lib/python3.9/subprocess.py", line 373, in check_call
raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['ls', '-l;', 'ls', '-l']' returned non-zero exit status 2.
"""
其实如果cmdline = "ls -l;"
,执行结果也会报错,因为-l;
并不是ls
的参数,-l
才是ls
的参数。
3 安全性
【1】当命令是通过用户从前端页面输入获得的,shell=True是不安全的,shell=False相对安全的,都有shell注入风险。
【2】当命令是程序员自己写的并不是通过用户从前端页面输入获得的,shell=True 与 shell=False都是安全的,不存在shell注入。除非程序员自己写的命令有问题。
3.1 为什么说shell=True不安全
比如要执行cat
命令,需要用户输入cat
的参数文件名,正常情况用户输入file.txt
user_input = "file.txt"
cmdline = "cat " + user_input
subprocess.check_call(cmdline, shell=True)
异常情况用户输入file.txt; rm -rf /
,此时代码后将会删除根目录,导致服务器宕机
user_input = "file.txt; rm -rf /"
cmdline = "cat " + user_input
subprocess.check_call(cmdline, shell=True)
3.2 为什么说shell=False相对安全
比如要执行cat
命令,需要用户输入cat
的参数文件名,正常情况用户输入file.txt
user_input = "file.txt"
cmdline = "cat " + user_input
cmd = shlex.split(cmdline)
subprocess.check_call(cmd, shell=False)
异常情况用户输入file.txt; rm -rf /
,代码将不会正常执行,执行代码会报错,因为cat
参数为"file.txt;“、“rm”、”-rf"、“/”,
"file.txt;"是cat
的异常参数。
user_input = "file.txt; rm -rf /"
cmdline = "cat " + user_input
cmd = shlex.split(cmdline)
subprocess.check_call(cmd, shell=False)
既然说相对安全,那肯定也有不安全的情况
当整条命令都是通过用户从前端页面输入获取到的时候也会存在shell命令注入问题,比如
user_input = "rm -rf /"
cmdline = user_input
cmd = shelex.split(cmdline)
subprocess.check_call(cmd, shell=False)
以上命令也可以正常执行,会删掉根目录,导致服务器宕机。