升级Lambda Python 3.11运行时遇ClamAV报错,求解决方案
ld命令的问题 问题场景
我们使用的基于ClamAV的Lambda杀毒函数在Python 3.7运行时可正常工作,但升级至Python 3.8/3.9/3.10/3.11运行时出现如下错误:
[ERROR] FileNotFoundError: [Errno 2] No such file or directory: 'ld'
Traceback (most recent call last):
File "/var/task/update.py", line 43, in lambda_handler
clamav.update_defs_from_freshclam(AV_DEFINITION_PATH, CLAMAVLIB_PATH)
File "/var/task/clamav.py", line 100, in update_defs_from_freshclam
fc_env["LD_LIBRARY_PATH"] = "%s:%s" % (":".join(current_library_search_path()), CLAMAVLIB_PATH)
错误根源是current_library_search_path函数执行ld --verbose时找不到ld命令:
def current_library_search_path(): ld_verbose = check_output(["ld", "--verbose"]).decode("utf-8") rd_ld = re.compile("SEARCH_DIR\(\"([A-z0-9/-]*)\"\)") return rd_ld.findall(ld_verbose)
由于Python 3.7即将终止生命周期,需要升级至AWS推荐的Python 3.11运行时,以下是可行的解决方法:
解决方法
方法1:使用ld的绝对路径调用
AWS Lambda Python 3.8+运行时中,ld命令的绝对路径是/usr/bin/ld,修改函数代码为:
def current_library_search_path(): ld_verbose = check_output(["/usr/bin/ld", "--verbose"]).decode("utf-8") rd_ld = re.compile("SEARCH_DIR\(\"([A-z0-9/-]*)\"\)") return rd_ld.findall(ld_verbose)
方法2:直接预定义Lambda运行时的标准库路径
Lambda运行时的系统库搜索路径是固定的,无需调用ld命令获取,直接返回固定路径列表:
def current_library_search_path(): # Lambda Python 3.8+运行时的标准系统库路径 return ["/lib64", "/usr/lib64"]
方法3:从环境变量获取库路径
直接读取环境变量LD_LIBRARY_PATH并拆分,避免调用外部命令:
import os from subprocess import check_output def current_library_search_path(): ld_path = os.environ.get("LD_LIBRARY_PATH", "") # 过滤空路径 return [path for path in ld_path.split(":") if path.strip()]
原因说明
AWS Lambda在Python 3.8及以上运行时调整了默认环境变量PATH的配置,ld命令所在目录不再包含在默认PATH中,导致代码无法找到该命令;而Python 3.7运行时的PATH包含了该目录,因此之前的代码可以正常工作。
内容的提问来源于stack exchange,提问作者vinay jha

