无法通过PHP程序执行HandBrakeCLI Shell脚本问题求助
看起来你的脚本在命令行能正常转码,但通过PHP执行时完全没输出,这种情况通常和环境变量、权限、错误捕获这几个核心问题有关,下面是具体的排查和解决步骤:
1. 给HandBrakeCLI指定绝对路径
命令行里你能直接用HandBrakeCLI是因为它在当前用户的PATH环境变量里,但PHP是通过web服务器用户(比如www-data)运行的,这个用户的PATH大概率不包含HandBrakeCLI的安装路径,导致找不到命令。
解决方法:
先在命令行里找到HandBrakeCLI的绝对路径:
which HandBrakeCLI
假设输出是/usr/bin/HandBrakeCLI,然后修改你的test.sh脚本里的对应行:
HANDBRAKE_CLI=/usr/bin/HandBrakeCLI
2. 检查目录权限
web服务器用户需要对源目录(/var/www/html/plms/video/)有读取权限,对目标目录(/var/www/html/plms/mp4files/)有写入权限,否则转码时会因为权限不足静默失败。
解决方法:
执行以下命令修改目录所有者(确保web服务器用户是www-data,如果不是请替换成你的服务器实际用户):
sudo chown -R www-data:www-data /var/www/html/plms/video/ /var/www/html/plms/mp4files/
如果不需要严格的权限控制,也可以直接设置权限位:
sudo chmod -R 755 /var/www/html/plms/video/ sudo chmod -R 775 /var/www/html/plms/mp4files/
3. 在PHP中捕获错误输出
默认情况下,PHP的exec、shell_exec等函数只捕获标准输出(stdout),而脚本执行的错误信息会输出到标准错误(stderr),导致你看不到问题到底出在哪。
解决方法:
修改PHP调用脚本的代码,把错误输出重定向到标准输出,同时捕获返回值:
<?php $output = []; $returnVar = 0; // 用绝对路径调用脚本,同时重定向错误输出 exec('/path/to/your/test.sh 2>&1', $output, $returnVar); // 打印输出和返回值,排查错误 print_r($output); echo "Return code: " . $returnVar; ?>
返回值非0通常表示脚本执行出错,$output里会包含具体的错误信息(比如权限不足、命令找不到等)。
4. 修复脚本中不安全的文件遍历逻辑
你的脚本里用for FILE in ls $SRC``来遍历文件,这种写法在遇到文件名包含空格、特殊字符时会出错,而且当目录为空时也可能引发异常。
解决方法:
把循环改成更安全的写法,同时跳过非文件条目:
for FILE in "$SRC"* do # 跳过目录或其他非文件类型 [ -f "$FILE" ] || continue filename=$(basename "$FILE") extension=${filename##*.} filename=${filename%.*} # 给所有变量加双引号,避免空格导致的参数拆分问题 "$HANDBRAKE_CLI" -i "$SRC/$FILE" -o "$DEST/$filename.$DEST_EXT" -e x264 -q 22 -r 12 -B 64 -X 480 -O done
5. 确认工作目录匹配
如果你的PHP脚本和test.sh不在同一个目录,执行时可能找不到脚本,或者脚本里的相对路径(虽然你用的是绝对路径,但还是提一下)出问题。
解决方法:
在PHP里调用脚本时务必使用绝对路径,或者在test.sh开头加上切换到脚本所在目录的代码:
# 切换到脚本所在目录,切换失败则退出 cd "$(dirname "$0")" || exit 1
按以上步骤逐一排查,应该能快速定位并解决问题。
内容的提问来源于stack exchange,提问作者Sunita Kunwar

