我在Windows上使用PHP的exec()函数运行命令时遇到了问题。根据{{3}}上的PHP网站发表评论:
在Windows中,exec()发出对“cmd / c your_command”的内部调用。
我的命令如下:
"path\to\program.exe" -flag1 attribute1 -flag2 attribute2 -flag3 "attribute3 attribute4"
在我的本地命令提示符中定期执行此命令,没有/ c标志,该命令运行正常。但是,随着/ c标志的引入,命令提示符告诉我“系统找不到指定的路径。”
我认为命令提示符将双引号参数解释为另一个文件的路径,但这是我遇到此问题最远的。
有没有人对如何解决这个问题有任何想法?谢谢!
答案 0 :(得分:2)
我也遇到过这个问题,其原因确实是内部使用" cmd / c"正如你自己的回答所述。
我做了一些调查,发现这已在PHP 5.3中得到解决,这就是为什么有些评论者无法重现它。
在以下提交中已修复:
对于仍然需要支持PHP 5.2的任何人来说,在您自己的代码中复制修复程序相当容易。而不是:
$cmd = "...any shell command, maybe with multiple quotes...";
exec($cmd);
使用
$cmd = "...any shell command, maybe with multiple quotes...";
if (strtoupper(substr(php_uname('s'), 0, 3)) == "WIN"
&& version_compare(PHP_VERSION, "5.3", "<"))
{
$cmd = '"' . $cmd . '"';
}
exec($cmd);
这复制了PHP 5.3及更高版本的行为,其方式与上面链接的提交相同。
请注意,这适用于所有shell命令,而不仅仅是我的示例中使用的exec()。
答案 1 :(得分:1)
我自己想出了答案......
仔细阅读cmd.exe之后的?并试图破译,我注意到一个重要的部分:
如果满足以下所有条件,则会保留命令行中的引号字符:
- 否/ S开关(带状引号)
- 正好两个引号字符
- 两个引号字符之间没有特殊字符,其中special是以下之一:&amp; &LT; &gt;()@ ^ |
- 两个引号字符之间有一个或多个空格字符
- 两个引号字符之间的字符串是可执行文件的名称。
- 醇>
否则,旧行为是查看第一个字符是否为引号字符,如果是,则删除前导字符并删除命令行中的最后一个引号字符,保留最后一个引号字符后面的任何文本。要取消此行为,请在命令行的开头和结尾使用一组双引号。
似乎在任何时候如果有多对引号,引号将从第二对引号中剥离并打开。
一个相关问题:How do I deal with quote characters when using cmd.exe但并不完全相关,因为PHP不会允许你通过在其调用上放置一个/ S标志来修改其exec()命令(这肯定会容易得多)。 / p>
我设法解决了这个问题,直接用chdir()将目录更改为.exe所在的文件夹,然后chdir()返回到我原来的工作目录。这是一个非常hacky的解决方案,考虑到我很幸运,我只有一组使用双引号的参数。如果有人使用双引号有多个参数,我不知道如何解决...
答案 2 :(得分:0)
只是一个猜测(我不熟悉Windows上的PHP):可能会因为"
成为""
而忽略引号?
"path\to\program.exe" -flag1 attribute1 -flag2 attribute2 -flag3 ""attribute3 attribute4""
无论解决方案是什么,请确保当某种形式的用户输入作为您使用escapeshellarg和/或escapeshellcmd的参数传递给此命令时。
答案 3 :(得分:0)