昨天调试其他同学的代码时,发现对于subprocess模块所传的args变量,与shell变量存在关联,传值不当会有各种问题。比较有趣,就记录一下。
根据subprocess模块的args定义如下:
args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names).
If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.
对于args,可传string,也可传list,但当传string时,shell的值必须设为True。
当shell为True时
If shell is True, the specified command will be executed through the shell. This can be useful if you are using Python primarily for the enhanced control flow it offers over most system shells and still want convenient access to other shell features such as shell pipes, filename wildcards, environment variable expansion, and expansion of ~ to a user’s home directory.
就是调用了系统的 sh 来执行命令(args的string),这样会导致一些猥琐的安全问题,类似于SQL Injection攻击:
from subprocess import call
What file would you like to display?
non_existent; rm -rf / #
call("cat " + filename, shell=True) # Uh-oh. This will end badly...
所以,安心用shell=False吧,记得args传list。