Laravel命令类运行bash脚本报Command not found错误排查
问题原因
报错返回127退出码(命令找不到)的核心原因是Symfony\Component\Process\Process类的传参格式错误。
当以数组格式给Process构造函数传命令时,数组的每个元素必须独立拆分:第一个元素是可执行命令本身,后续元素是传给该命令的逐个参数。你当前的写法把sh命令和脚本路径拼成了一个字符串,作为单个数组元素传入,系统会把整个字符串sh /var/www/mysite/storage/app/scripts/remove-spaces.sh当成一个完整的可执行文件名去查找,自然找不到对应程序,这和报错输出里的exec: sh /var/www/.../remove-spaces.sh: not found完全对应。
你手动进入目录在终端执行脚本能正常运行,是因为终端shell会自动把你输入的sh remove-spaces.sh拆成命令sh、参数remove-spaces.sh两部分再执行,而Process类接收数组参数时不会自动做这种字符串拆分。
修复方法
把Process实例化时的命令和参数拆分为独立的数组元素即可,修改构造函数里的Process初始化代码:
public function __construct() { parent::__construct(); // 将sh命令和脚本路径拆分为两个独立数组元素 $this->removeSpaces = new Process(['sh', '/var/www/mysite/storage/app/scripts/remove-spaces.sh']); $this->lowercase = new Process(['sh', '/var/www/mysite/storage/app/scripts/lowercase.sh']); }
可选简化写法
如果你不想手动拆分命令参数,也可以调用Process的fromShellCommandline静态方法直接传入完整命令字符串,这种写法会和终端执行逻辑一致,自动解析命令内容:
$this->removeSpaces = Process::fromShellCommandline('sh /var/www/mysite/storage/app/scripts/remove-spaces.sh'); $this->lowercase = Process::fromShellCommandline('sh /var/www/mysite/storage/app/scripts/lowercase.sh');
额外注意事项
- 执行命令前请确认两个shell脚本有可读权限,运行
php artisan命令的用户(你报错环境中是http用户)同时要有/var/www/mysite/storage/app/img/目录下文件的重命名权限,否则会出现权限报错。 - 你的
remove-spaces.sh脚本中mv的目标路径没有加双引号,如果文件名包含连续空格、特殊字符时会出现执行异常,建议和lowercase.sh写法保持一致,给目标路径也包裹双引号:
for file in /var/www/mysite/storage/app/img/*; do mv "$file" "`echo $file | tr ' ' '-'`"; done
内容的提问来源于stack exchange,提问作者schel4ok
相关产品推荐
相关产品推荐

