为什么我需要shell = True才能使Python的subprocess.check_output工作?

时间:2016-04-07 13:23:43

标签: python shell python-3.x terminal subprocess

我有一个python脚本,它是在建立PPP连接时由Linux上 ppp 程序调用的 if-up 脚本运行的。 python脚本基本上调用命令行程序,解析结果并返回它:

import subprocess

result = subprocess.check_output(["fw_printenv", "serialnr"])
result = # some operation 
return result

虽然当我从命令行手动运行python脚本(例如python script.py)时,这段代码工作正常100%,但当它从if-up运行时,它根本不起作用。调用subprocess.check_output时会引发异常:[Errno 2] No such file or directory: 'fw_printenv'

如果我将代码更改为:

,我只能让它工作
result = subprocess.check_output("fw_printenv serialnr", shell=True)

为什么?

2 个答案:

答案 0 :(得分:3)

使用绝对路径:

result = subprocess.check_output(["/full/path/to/fw_printenv", "serialnr"])

您通过cron和Web服务器运行的内容也是如此。

shell=True显然会打开一个shell,但不太明显,它还会设置所有环境变量(例如PATH) - 就像您在终端中手动运行脚本一样。删除shell=True并使用绝对路径可能是最好/最安全的选择,如果它有效(我认为它会)。

答案 1 :(得分:3)

来自subprocess documentation

  

如果shell为True,则将通过shell执行指定的命令。如果您主要使用Python来提供它在大多数系统shell上提供的增强控制流,并且仍然希望方便地访问其他shell功能,例如shell管道,文件名通配符,环境变量扩展,那么这非常有用。 〜扩展到用户的主目录。但是,请注意Python本身提供了许多类似shell的功能的实现(特别是glob,fnmatch,os.walk(),os.path.expandvars(),os.path.expanduser()和shutil)。

环境变量是获取二进制文件的路径所必需的(不是PATH,包含可能的路径,包括unix系统下的/usr/bin/。 否则,fw_printenv可能是accessed by absolute path