You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用subprocess执行命令触发FileNotFoundError:脚本失败但交互式正常

解决Python脚本调用trivy提示「No such file or directory」的问题

我之前也碰到过类似的情况,明明终端里能跑的命令,放到Python脚本里就找不到工具了,咱们来一步步理清楚问题在哪,怎么解决。

首先,你遇到的核心问题是脚本运行时的环境变量PATH和交互模式下不一样。当你在Python交互解释器里执行命令时,它是继承了你当前终端shell的完整环境——包括你通过~/.bashrc~/.zshrc这类配置文件添加的自定义PATH路径(比如trivy可能安装在你的用户目录~/.local/bin下,这个路径在交互shell里会被加到PATH里)。但当你直接运行Python脚本时,脚本进程的PATH可能只包含系统默认的路径(比如/usr/bin/bin),找不到trivy的位置,所以才会报错「No such file or directory」。

接下来给你几个靠谱的解决方案,你可以根据自己的情况选:

方案1:直接用trivy的绝对路径(最稳妥,无安全风险)

先在终端里执行which trivy,拿到trivy的完整路径(比如/home/your-username/.local/bin/trivy),然后把脚本里的trivy替换成这个绝对路径就行:

import subprocess
image_name = "alpine:3.10"
# 替换成你用which trivy查到的绝对路径
trivy_full_path = "/home/your-username/.local/bin/trivy"
scan_command = f"{trivy_full_path} -q image -f json {image_name}"
scan_result = subprocess.check_output(scan_command.split()).decode('utf-8')

方案2:让subprocess用shell执行(简单但要注意安全)

如果你的脚本里image_name是固定的、不会来自不可信输入,可以让subprocess调用用户的shell来执行命令,这样就能继承完整的PATH环境:

import subprocess
image_name = "alpine:3.10"
scan_command = f"trivy -q image -f json {image_name}"
# 添加shell=True参数,用当前用户的shell执行命令
scan_result = subprocess.check_output(scan_command, shell=True).decode('utf-8')

⚠️ 注意:如果image_name是外部用户输入的内容,绝对不能用这个方案,会有命令注入的安全风险!

方案3:手动给脚本添加PATH(灵活且安全)

你可以在脚本里手动把trivy所在的目录加到环境变量PATH中,同时建议用列表形式传递命令参数(比split()更稳定,避免文件名带空格的问题):

import subprocess
import os

image_name = "alpine:3.10"
# 复制当前环境变量,避免修改全局环境
custom_env = os.environ.copy()
# 把trivy所在的目录加到PATH最前面,替换成你自己的路径
custom_env['PATH'] = "/home/your-username/.local/bin:" + custom_env['PATH']
# 用列表形式传递命令参数,更安全可靠
scan_command = ["trivy", "-q", "image", "-f", "json", image_name]
scan_result = subprocess.check_output(scan_command, env=custom_env).decode('utf-8')

总结一下,交互模式和脚本模式的核心差异就是环境变量的加载逻辑,只要让脚本能找到trivy的执行路径,问题就能解决啦。

内容的提问来源于stack exchange,提问作者Mehdi Khlifi

火山引擎 最新活动