PHP exec() 和路径中的空格
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5489613/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP exec() and spaces in paths
提问by b. e. hollenbeck
I'm executing the following in a PHP application:
我在 PHP 应用程序中执行以下操作:
$source = '/home/user/file.ext';
$output_dir = $this->setOutputString();
chdir('/home/ben/xc/phplib/bgwatcher-2011a/a01/');
exec('php bin/createjob.php $source $output_dir', $output);
return $output[0];
The problem is this: I have control over $source
, but not $output_dir
, which is a legacy Windows filesystem, and there are spaces in the path. An example $output_dir
is:
问题是这样的:我可以控制$source
,但不能控制$output_dir
,这是一个旧的 Windows 文件系统,并且路径中有空格。一个例子$output_dir
是:
/home/vol1/district id/store id/this_is_the_file.html
When inserting the output string into the exec()
function, I have tried both:
将输出字符串插入exec()
函数时,我都尝试过:
addslashes($output_dir)
and '"' . $output_dir . '"'
to escape the entire output string. In the first case, the path gets concatenated to:
addslashes($output_dir)
并'"' . $output_dir . '"'
转义整个输出字符串。在第一种情况下,路径连接到:
/home/vol1/districtthis_is_the_file.html
/home/vol1/districtthis_is_the_file.html
... where everything between the first space and the filename gets dropped. In the second case, exec()
appears to throw a shoe and doesn't execute properly - unfortunately, the error message is getting lost in the machinery - I can provide it if it's absolutely necessary, but I'm also under time constraints to find a solution.
...其中第一个空格和文件名之间的所有内容都被删除。在第二种情况下,exec()
似乎抛出了一只鞋子并且没有正确执行 - 不幸的是,错误消息在机器中丢失 - 如果绝对必要,我可以提供它,但我也有时间限制来找到解决方案.
What's the solution, here? Do I sprintf()
the entire string for exec()
? I'm very confused as to why addslashes
isn't working correctly to escape the spaces, and I assume it has something to do with sanitization with exec(), but I can't find any documentation to back it up.
这里有什么解决办法?我是否sprintf()
将整个字符串用于exec()
?我很困惑为什么addslashes
不能正常工作以逃避空格,我认为这与使用 exec() 进行消毒有关,但我找不到任何文档来支持它。
Update:I've tried escapeshellarg() and preg_replace() without success. Thinking about this further, do I need to double-escape the path? Or escape the path and the command? If the path is being unescaped once by exec(), and once by PHP before it executes the command, does it stand to reason that I need to account for both escapes? Or is that not how it works?
更新:我尝试过 escapeshellarg() 和 preg_replace() 没有成功。进一步考虑这一点,我是否需要双重逃避路径?或者逃避路径和命令?如果路径在执行命令之前被 exec() 转义一次,并且被 PHP 转义一次,那么我需要考虑这两个转义是否合理?或者这不是它的工作原理?
采纳答案by Demian Brecht
According to the PHP docs,
根据PHP 文档,
Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash () and NUL (the NULL byte).
在需要在数据库查询等中引用的字符之前返回一个带有反斜杠的字符串。这些字符是单引号 (')、双引号 (")、反斜杠 () 和 NUL(空字节)。
Looks like you'll have to preg_replace the spaces yourself.
看起来您必须自己 preg_replace 空格。
Edit:
编辑:
Even though this is the topic of another discussion, if performance is an issue, then after looking into it a little more, it seems that str_replace
isactually quite a bit faster than preg_replace
:
虽然这是另外一个讨论的话题,如果性能是一个问题,然后寻找到了一点多后,似乎str_replace
是其实很有点快于preg_replace
:
The test labeled "str_replace()" was the faster by 0.9053 seconds (it took 10.3% the time.)
The first test took 1.0093 seconds. (
preg_replace
)The second test took 0.104 seconds. (
str_replace
)
标记为“str_replace()”的测试快了 0.9053 秒(花费了 10.3% 的时间。)
第一次测试耗时 1.0093 秒。(
preg_replace
)第二次测试耗时 0.104 秒。(
str_replace
)
回答by Michael Berkowski
I don't believe addslashes()
does anything with spaces. escapeshellarg()
might be what you want instead. Docs on escapeshellarg
我不相信addslashes()
对空间做任何事情。 escapeshellarg()
可能是你想要的。escapeshellarg 上的文档
回答by Bojangles
From the PHP doc (here),
从 PHP 文档(这里),
Returns a string with backslashes before characters that need to be quoted in database queries etc. These characters are single quote ('), double quote ("), backslash () and NUL (the NULL byte).
返回一个在需要在数据库查询等中引用的字符之前带有反斜杠的字符串。这些字符是单引号 (')、双引号 (")、反斜杠 () 和 NUL(空字节)。
This won't do anything to the spaces. What you will need to do is use str_replace()
to add slashes, like this:
这不会对空间做任何事情。您需要做的是使用str_replace()
添加斜杠,如下所示:
$new_string = str_replace(" ", "\\ ", $old_string);
$new_string = str_replace(" ", "\\ ", $old_string);
回答by Kromey
I've used exec()
with paths with spaces before, on both Windows and Linux hosts, and in both cases quoting the path worked perfectly for me.
我exec()
之前在 Windows 和 Linux 主机上都使用过带空格的路径,在这两种情况下,引用路径对我来说都非常有效。
That said, if you have no control over the safety of a shell argument, alwaysrun it through escapeshellarg()
first!
也就是说,如果您无法控制 shell 参数的安全性,请始终先运行它escapeshellarg()
!
回答by mario
You can very well use shellquotes, since that is what all exec commands run through:
您可以很好地使用shell引号,因为这是所有 exec 命令运行的内容:
exec("php bin/createjob.php '$source' '$output_dir'", $output);
It btw works not just for arguments, but also for the command itself:
顺便说一句,它不仅适用于参数,还适用于命令本身:
exec('"/bin/echo" "one parameter"');
Use escapeshellcmd()
anyway.
使用escapeshellcmd()
反正。
回答by Goce Ribeski
this works for me when using exec() with soffice(LibreOffice):
当将 exec() 与 soffice(LibreOffice) 一起使用时,这对我有用:
$file_name = "Some, file name.xlsx";
exec('/usr/bin/soffice --headless --convert-to pdf '."'".$file_name."'".' 2>&1', $output, $r);