【问题标题】:Running command with subprocess raises FileNotFoundError使用子进程运行命令引发 FileNotFoundError
【发布时间】:2020-12-28 02:06:49
【问题描述】:

我正在尝试在 Python 脚本中运行以下命令

import subprocess
image_name = "alpine:3.10"
scan_image = "trivy -q image -f json {}".format(image_name)
scan_result = subprocess.check_output(scan_image.split()).decode('utf-8')

如果我从 Python 脚本运行它,它会引发以下错误:[Errno 2] No such file or directory: 'trivy'

但如果我使用 python 解释器(交互模式)运行命令,它工作正常。

-bash-4.2# python3
Python 3.6.8 (default, Apr  2 2020, 13:34:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> image_name = "alpine:3.10"
>>> scan_image = "trivy -q image -f json {}".format(image_name)
>>> subprocess.check_output(scan_image.split()).decode('utf-8')
'[\n  {\n    "Target": "alpine:3.10 (alpine 3.10.5)",\n    "Type": "alpine",\n    "Vulnerabilities": null\n  }\n]'
>>> 

我可能做错了什么?我已经使用 Python2 和 Python3 解释器运行了这些命令。

【问题讨论】:

  • 如果将脚本中的trivy 替换为shell 中which trivy 的结果会怎样?
  • 使用.format() 然后.split() 是一个真的坏主意;如果名称包含空格,它会严重失败。只需将您的参数列表作为列表传递
  • (是的,直接的问题几乎可以肯定是 trivy 不在 PATH 中;但此代码与任意文件名一起使用并不安全)。
  • ...考虑一下如果有人创建了一个名为 '/uploads/ -o /etc/passwd .jpg' 的文件并且您在 /uploads 的内容上运行脚本会发生什么——因为 .split() 在在名称内部,您将获得-o/etc/passwd 作为单独的参数传递给trivy,如果由具有相关权限的用户运行,则覆盖命名文件;替换为攻击者可能想要修改的任何其他文件名。
  • @JacobIRR 如果我用 /usr/local/bin/trivy 替换 trivy 就可以了

标签: python python-3.x python-2.7 subprocess


【解决方案1】:

除了安全问题,您需要提供可执行文件的完整路径:

将脚本中的trivy 替换为shell 中which trivy 的结果

【讨论】:

  • 很好的建议,例如Linux,但是像 Windows 这样没有 which 的系统呢?
  • Windows 有where。我知道这个用户在 Unix 领域,但因为 OP -bash-4.2# python3 中的这一行
  • which 在 bash 中不合适——command -v trivy 是符合 POSIX 的 shell-builtin 方法(用于 shell=True),type trivy 是 bash 方法(用于 @ 987654330@)。 which 是一个未指定 POSIX 的外部命令,操作系统可能提供也可能不提供。 (这对于 zsh 不同,它提供了一个 which 内置函数,但那是另一个 shell)。
  • 是的 type 是我对 which 的后备
猜你喜欢
  • 2020-07-25
  • 2021-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-10
  • 2013-07-18
  • 2020-05-09
相关资源
最近更新 更多