使用 subprocess.popen 在我的脚本中调用外部程序。如果没有 shell=True,我无法让它工作,并且添加了一个断言语句来降低危险(我认为)。
相关代码行:
import subprocess
import re
import argparse
parser = argparse.ArgumentParser(description="options")
parser.add_argument("-p", "--prefix", help="prefix for output files")
args = parser.parse_args()
assert re.match("^[a-zA-Z0-9_]+$", args.prefix), "non-alphanumeric characters found"
command = "my_external_program -t type -f %s -m 1 -M 1 -N 0 -H -p 16" % args.prefix
external_stacks_call = subprocess.Popen(command, shell=True, stdout=open(args.prefix + ".log.txt", "a"), stderr=open(args.prefix + ".log.txt", "a"))
external_stacks_call.wait()
问题如下:
- 断言语句是否足够安全,可以避免其他人造成的恶作剧/问题或其他意外问题?
- 例如有人输入前缀“stuff && rm -rf/”
- 在没有 shell=True 选项的情况下不调用同一字符串的最佳方法是什么?
我已经在此处和其他地方查看了有关 shell=True 选项的危险和 shell=True 的危险的几页,但我还没有找到如何避免将其用于外部程序的良好来源
最佳答案
shell=True
将转义空格,但是您也可以为命令行提供参数列表
command = ["my_external_program", "-t", "type", "-f", str(args.prefix),
"-m", "1", "-M", "1", "-N", "0", "-H", "-p", "16"]
这将使模块能够正确、更安全地与 shell 交互
如果没有 shell=True
特殊字符将被转义,因此与原始命令等效的是
$ my_external_program\ -t\ type\ -f
等等
这是一个优点,因为 shell 可以以相同的方式转义各种特殊字符
关于python 在没有 shell 的情况下使用 popen,或使用断言来提高安全性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27427208/