PHP exec()和路径中的空格

PHP exec()和路径中的空格,php,path,exec,Php,Path,Exec,我正在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]; 问题是:我可以控制$so

我正在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];
问题是:我可以控制
$source
,但不能控制
$output\u dir
,这是一个遗留的Windows文件系统,路径中有空格。例如
$output\u dir

/home/vol1/district id/store id/this_is_the_file.html
在将输出字符串插入
exec()
函数时,我尝试了以下两种方法:

addslashes($output\u dir)
“.$output\u dir.”“
以转义整个输出字符串。在第一种情况下,路径连接到:

/home/vol1/district这是文件.html

。。。删除第一个空格和文件名之间的所有内容。在第二种情况下,
exec()
似乎抛出了一个问题,无法正确执行-不幸的是,错误消息在机器中丢失了-如果绝对必要,我可以提供它,但我也受到时间限制,无法找到解决方案

这里的解决方案是什么?我是否需要
sprintf()
执行()的整个字符串?我很困惑为什么
addslashes
不能正确地跳出空格,我认为这与exec()的消毒有关,但我找不到任何文档来支持它

更新:我尝试了escapeshellarg()和preg_replace()但没有成功。再进一步想一想,我需要双倍逃离这条路吗?还是逃离路径和命令?如果路径在执行命令之前被exec()取消了一次scape,被PHP取消了一次scape,那么我需要解释这两个转义是否合理?或者这不是它的工作原理吗?

根据

返回在数据库查询等中需要引用的字符之前带有反斜杠的字符串。这些字符是单引号(')、双引号(“)、反斜杠()和NUL(空字节)

看来你得自己准备替换空间了

编辑:

尽管这是另一个讨论的主题,但如果性能是一个问题,那么在进一步研究之后,似乎
str\u replace
实际上比
preg\u replace
快很多:

标记为“str_replace()”的测试失败 速度快了0.9053秒(花了 10.3%的时间。)

第一次测试耗时1.0093秒。(
preg\u replace

第二次测试耗时0.104秒。(
str\u replace

来自PHP文档()

返回在数据库查询等中需要引用的字符之前带有反斜杠的字符串。这些字符是单引号(')、双引号(“)、反斜杠()和NUL(空字节)

这对空间没有任何影响。您需要做的是使用
str_replace()
添加斜杠,如下所示:


$new\u string=str\u replace(“,“\\”,$old\u string)

我不相信
addslashes()
对空格有任何作用<代码>escapeshellarg()可能是您想要的

我以前在Windows和Linux主机上使用过带空格的路径,在这两种情况下引用路径对我来说都非常有效

也就是说,如果您无法控制shell参数的安全性,请始终首先通过
escapeshellarg()
运行它

您可以很好地使用shell引号,因为这是所有exec命令的运行方式:

exec("php bin/createjob.php '$source' '$output_dir'", $output);
顺便说一句,它不仅适用于参数,也适用于命令本身:

exec('"/bin/echo" "one parameter"');

无论如何都要使用escapeshellcmd()。

当我将exec()与soffice(LibreOffice)一起使用时,这对我很有效:


只是为了检查我的RegExp-fu的缺乏,这是正确的吗<代码>预替换(“/\s/”、“\\”、$this->output\u dir);为了提高速度,或者只是为了与众不同,可以使用
str_replace()
?当我尝试这样做时,字符串在第一个空格处仍然被截断,createjob.php失败。地狱的钟声-我想我需要加倍逃离这个!或者转义整个命令…我尝试对$output_dir字符串使用escapeshellarg(),但该字符串在遇到的第一个空格处仍然被截断。
$file_name = "Some, file name.xlsx";
exec('/usr/bin/soffice --headless --convert-to pdf '."'".$file_name."'".' 2>&1', $output, $r);