You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda中Node.js包装PHP调用Python脚本遇OSError错误求助

解决AWS Lambda中PHP调用Python脚本执行ffprobe时的"OSError: No such file or directory"问题

我之前在Lambda环境里做跨语言调用的时候也踩过类似的路径和依赖坑,给你几个关键的排查方向和解决办法:

1. 先确认所有文件的实际路径是否正确

Lambda的执行环境目录结构和本地完全不一样,别想当然用本地的路径:

  • 先在PHP里加一行调试代码,打印出__DIR__的实际值:
    error_log("PHP script directory: " . __DIR__);
    
    然后去Lambda的CloudWatch日志里看这个路径,确认ffprobe_hosts.py确实在这个目录下。
  • 关于ffprobe:Lambda默认的运行时(不管是Node.js还是PHP的基础镜像)都不带ffmpeg/ffprobe工具!你要么把ffprobe二进制文件打包到你的部署包里,要么用Lambda层来挂载这个工具。如果是打包到部署包,那Python里的路径不能写/usr/bin/ffprobe,得换成你实际放置的路径,比如os.path.join(os.path.dirname(__file__), 'ffprobe')。

2. 修复Python中subprocess的调用方式

你现在的命令拼接方式容易出问题,尤其是当src_video是带特殊字符的URL时,而且路径如果有空格也会报错。建议改成参数列表的方式,同时对URL做转义:

import subprocess
import shlex
import os

# 先确认ffprobe的实际路径,比如和脚本同目录的话
ffprobe_path = os.path.join(os.path.dirname(__file__), "ffprobe")
# 转义视频URL,避免特殊字符破坏命令结构
escaped_video = shlex.quote(src_video)
cmd = [
    ffprobe_path,
    "-show_frames",
    "-of",
    "compact=p=0",
    "-f",
    "lavfi",
    f"movie={escaped_video},select=gt(scene,{str(threshold)})"
]
# 执行命令
scene_ps = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

3. 检查文件权限和Python解释器路径

  • 确保你的ffprobe_hosts.py和ffprobe都有可执行权限:在本地打包前,执行chmod +x ffprobe_hosts.py和chmod +x ffprobe,再打包成zip上传到Lambda。
  • 如果你在PHP里直接调用Python脚本(没指定解释器),那脚本开头的shebang行必须正确,比如#!/usr/bin/env python3(Lambda里的Python3路径一般是这个)。或者你可以在PHP的shell_exec里明确指定Python解释器路径:
    $output = shell_exec('/usr/bin/python3 ' . escapeshellarg(__DIR__ . "/ffprobe_hosts.py") . ' ' . escapeshellarg($video_url) . " 2>&1");
    
    这里顺便用escapeshellarg()转义了$video_url,避免URL里的特殊字符破坏shell命令。

4. 用日志定位具体错误

Lambda的日志是排查问题的关键,建议把所有输出都记录下来:

  • 在PHP里,把shell_exec的标准错误也捕获到:
    $command = '/usr/bin/python3 ' . escapeshellarg(__DIR__ . "/ffprobe_hosts.py") . ' ' . escapeshellarg($video_url);
    $output = shell_exec($command . " 2>&1");
    error_log("Command output: " . $output);
    
  • 在Python脚本开头加调试代码,确认路径和文件存在:
    import os
    print(f"Python script path: {__file__}")
    ffprobe_path = os.path.join(os.path.dirname(__file__), "ffprobe")
    print(f"ffprobe exists: {os.path.exists(ffprobe_path)}")
    print(f"ffprobe is executable: {os.access(ffprobe_path, os.X_OK)}")
    
    这些信息会出现在CloudWatch日志里,能帮你快速定位是找不到脚本、找不到ffprobe,还是其他权限问题。

内容的提问来源于stack exchange,提问作者Nithin C

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:05:15