如何使用subprocess执行shell命令,在Flask中调用youtube-dl提取MP3
问题解决方法
核心错误:subprocess参数传递格式错误
你使用subprocess.call时错误将所有命令参数拼接成了单个字符串传入列表,当用列表形式传递参数时,每一个独立的命令参数都需要作为单独的列表元素存在,否则youtube-dl会收到一个非法的超长参数,导致命令无法正常执行。
修复后的代码
@app.route('/audios', methods=['POST', 'GET']) def audios(): if request.method == 'POST': subprocess.call([ 'youtube-dl', 'https://www.youtube.com/watch?v=BaW_jenozKc', '--extract-audio', '--audio-format', 'mp3', '-o', '/var/www/html/ytrip/audio/%(id)s.%(ext)s' ]) return render_template("audios.html")
其他可能的异常场景排查
- 权限问题:你在终端执行命令时用的是个人用户,而Flask进程的运行用户(通常为
www-data等低权限用户)可能没有/var/www/html/ytrip/audio目录的写入权限,会导致文件生成失败,可先给目标目录开放对应写入权限测试。 - 命令找不到问题:Flask进程的
PATH环境变量可能和终端不一致,导致找不到youtube-dl命令,可先在终端执行which youtube-dl获取命令的绝对路径(例如/usr/local/bin/youtube-dl),替换代码中的youtube-dl为绝对路径。 - 错误排查方法:你可以通过捕获命令执行的输出来定位具体问题,示例代码如下:
result = subprocess.run([ '/usr/local/bin/youtube-dl', # 替换为实际的youtube-dl绝对路径 'https://www.youtube.com/watch?v=BaW_jenozKc', '--extract-audio', '--audio-format', 'mp3', '-o', '/var/www/html/ytrip/audio/%(id)s.%(ext)s' ], capture_output=True, text=True) # 以下内容可输出到日志或者接口返回中排查问题 print("命令返回码:", result.returncode) # 返回码为0代表执行成功,非0代表失败 print("错误输出:", result.stderr) print("标准输出:", result.stdout)
内容的提问来源于stack exchange,提问作者Alaksandar Jesus Gene
相关产品推荐
相关产品推荐

