我使用subprocess
模块调用不同的进程。然而,我有一个问题。
在以下代码中:
callProcess = subprocess.Popen(['ls', '-l'], shell=True)
和
callProcess = subprocess.Popen(['ls', '-l']) # without shell
这两种方法都有效。在阅读文档后,我开始了解到shell=True
意味着通过shell执行代码。因此,这意味着在不存在的情况下,该过程直接启动。
那么对于我的情况,我应该更喜欢什么--我需要运行一个进程并获得它的输出。在shell内或shell外调用它有什么好处?
发布于 2015-03-13 09:36:26
这里显示了一个Shell=True可能出错的示例
>>> from subprocess import call
>>> filename = input("What file would you like to display?\n")
What file would you like to display?
non_existent; rm -rf / # THIS WILL DELETE EVERYTHING IN ROOT PARTITION!!!
>>> call("cat " + filename, shell=True) # Uh-oh. This will end badly...
请在此处查看文档:subprocess.call()
发布于 2010-07-04 03:50:19
通过shell执行程序意味着根据所调用的shell的语法和语义规则解释传递给程序的所有用户输入。充其量,这只会给用户带来不便,因为用户必须遵守这些规则。例如,包含特殊shell字符(如引号或空格)的路径必须转义。在最坏的情况下,它会导致安全泄漏,因为用户可以执行任意程序。
shell=True
有时可以方便地使用特定的shell特性,如拆分单词或扩展参数。但是,如果需要这样的功能,请使用提供给您的其他模块(例如,用于参数扩展的os.path.expandvars()
或用于分词的shlex
)。这意味着更多的工作,但避免了其他问题。
简而言之:一定要避免使用shell=True
。
发布于 2020-12-11 06:28:55
假设您正在使用shell=False,并以列表的形式提供命令。一些恶意用户试图插入“rm”命令。您将看到,'rm‘将被解释为参数,实际上'ls’将尝试查找名为'rm‘的文件
>>> subprocess.run(['ls','-ld','/home','rm','/etc/passwd'])
ls: rm: No such file or directory
-rw-r--r-- 1 root root 1172 May 28 2020 /etc/passwd
drwxr-xr-x 2 root root 4096 May 29 2020 /home
CompletedProcess(args=['ls', '-ld', '/home', 'rm', '/etc/passwd'], returncode=1)
默认情况下,如果您没有正确控制输入,shell=False就不是安全的。您仍然可以执行危险的命令。
>>> subprocess.run(['rm','-rf','/home'])
CompletedProcess(args=['rm', '-rf', '/home'], returncode=0)
>>> subprocess.run(['ls','-ld','/home'])
ls: /home: No such file or directory
CompletedProcess(args=['ls', '-ld', '/home'], returncode=1)
>>>
我的大多数应用程序都是在容器环境中编写的,我知道要调用的是哪个shell,并且我不会接受任何用户输入。
所以在我的用例中,我看不到任何安全风险。而且创建长的命令字符串要容易得多。希望我没记错。
https://stackoverflow.com/questions/3172470
复制相似问题