如何在PHP exec()中使用*路径通配符执行ls或cp命令?
PHP exec/shell_exec在Windows下无法解析*通配符的解决办法
问题概述
在Windows系统(CLI脚本、Terminal或git-bash环境结果一致)中,调用PHP的exec()或shell_exec()执行带*通配符的命令时遇到异常:
- 执行
echo exec('ls C:\temp\*')提示文件不存在 - 指定具体文件名
echo exec('ls C:\temp\example.png')可正常返回结果
这说明*被当作字面量文件名处理,尝试多种转义、引号包裹方式均无效。虽已通过glob()循环结合copy()实现需求,但仍希望解决通配符的直接调用问题。
原因分析
- 路径分隔符冲突:Windows系统中反斜杠
\既是路径分隔符,也是命令行的转义字符。当PHP将C:\temp\*传递给shell时,反斜杠会被优先解析,导致*无法被识别为通配符,而是被当作文件名的一部分。 - shell通配符处理逻辑:Windows原生
cmd默认不会为外部命令(如git-bash提供的ls)解析通配符,而正斜杠/在Windows多数命令行工具中可被识别为路径分隔符,且不会触发转义冲突,因此能让*被正确识别。
解决方案
方案1:使用正斜杠作为路径分隔符
直接将路径中的反斜杠替换为正斜杠,*通配符即可被正常解析:
echo exec('ls C:/temp/*');
该方法简洁有效,适用于大多数Windows命令行环境(包括git-bash)。
方案2:适配Windows原生shell(可选)
如果需要使用反斜杠,可通过cmd /c调用原生dir命令(cmd会自行解析通配符):
echo exec('cmd /c dir C:\\temp\\*.png');
若使用git-bash环境,也可通过显式调用bash来处理通配符:
echo exec('bash -c "ls C:\\temp\\*"');
后续环境变化说明
升级至Win11 22H2后,原反斜杠代码echo exec('ls C:\temp\*')不再报错,但返回空字符串。这是因为系统路径解析逻辑有调整,但仍未正确识别*通配符,因此仍建议优先使用正斜杠方案。
内容的提问来源于stack exchange,提问作者Rick Kukiela
相关产品推荐
相关产品推荐

