大小写不敏感的Shell命令在PHP Exec中无法运行
解决PHP exec执行ls命令无法生成文件的问题
我来帮你分析下这个问题,你遇到的情况很典型,主要是权限问题和Shell解析差异导致的,下面给你一步步的解决方案:
1. 先排查Apache用户的权限问题
在Shell里你用自己的用户执行命令没问题,但PHP是通过Apache的默认用户www-data来运行的,这个用户可能没有/var/www/dropbox目录的读写权限:
- 先检查目录权限:
看输出的权限信息,确保ls -ld /var/www/dropboxwww-data用户有读取目录(查找文件)和写入目录(生成temp.lst)的权限。 - 如果权限不足,修改目录所属用户:
或者调整目录权限(相对开放,建议优先用sudo chown -R www-data:www-data /var/www/dropboxchown方案):sudo chmod -R 775 /var/www/dropbox
2. 解决Shell通配符解析的问题
PHP的exec()默认使用sh而非你Shell里的bash,sh对*.[Cc][Ee][Ll]这种大小写通配符的解析支持有限,所以需要明确调用bash来执行命令:
修改你的PHP代码为:
$str = 'bash -c "ls -1 /var/www/dropbox/*.[Cc][Ee][Ll] > /var/www/dropbox/temp.lst"'; exec($str);
让bash来解析通配符,就能正确匹配.cel和.CEL后缀的文件了。
3. 更安全可靠的替代方案:用PHP原生函数实现
其实没必要依赖系统的ls命令,PHP本身就有文件遍历的原生函数,更安全也能避免Shell相关的问题,比如用glob():
// 匹配所有.cel/.CEL后缀的文件 $files = glob('/var/www/dropbox/*.[Cc][Ee][Ll]'); // 将文件列表写入目标文件 file_put_contents('/var/www/dropbox/temp.lst', implode("\n", $files));
这个方法不需要调用外部命令,权限检查和文件操作都在PHP层面处理,稳定性更高。
你可以先尝试权限排查,再调整命令执行方式,第三种方案是更推荐的最优解哦。
内容的提问来源于stack exchange,提问作者OtagoHarbour
相关产品推荐
相关产品推荐

