PHP exec()和路径中的空格

时间:2011-03-30 17:06:16

标签: 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];

问题在于:我可以控制$source,但不能控制$output_dir,这是一个传统的Windows文件系统,并且路径中有空格。示例$output_dir是:

/home/vol1/district id/store id/this_is_the_file.html

将输出字符串插入exec()函数时,我尝试了两种方法:

addslashes($output_dir)'"' . $output_dir . '"'以转义整个输出字符串。在第一种情况下,路径连接到:

/home/vol1/districtthis_is_the_file.html

...第一个空格和文件名之间的所有内容都被删除了。在第二种情况下,exec()似乎扔鞋并且没有正确执行 - 不幸的是,错误信息在机器中丢失 - 我可以提供它,如果它是绝对必要的,但我也在时间找到解决方案的约束。

这是什么解决方案?我sprintf()的整个字符串是exec()吗?我很困惑为什么addslashes无法正常工作以逃避空间,我认为它与使用exec()进行清理有关,但我找不到任何文档来备份它

更新:我尝试过escapeshellarg()和preg_replace()但没有成功。进一步思考这个问题,我是否需要双重逃避这条道路?还是逃避路径和命令?如果路径被exec()取消一次,并且在执行命令之前由PHP取消一次,那么我是否需要考虑这两个转义?或者这不是它的工作方式吗?

6 个答案:

答案 0 :(得分:8)

我不相信addslashes()对空格做任何事情。 escapeshellarg()可能是你想要的。 Docs on escapeshellarg

答案 1 :(得分:7)

根据PHP docs

  

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

看起来你必须自己preg_replace空间。

修改

即使这是另一个讨论的主题,如果性能是一个问题,那么在进一步研究之后,str_replace 似乎实际上要快得多preg_replace

  

标记为“str_replace()”的测试是   更快0.9053秒(花了   10.3%的时间。)

     

第一次测试耗时1.0093秒。 (preg_replace

     

第二次测试耗时0.104秒。 (str_replace

Benchmark found here.

答案 2 :(得分:7)

来自PHP文档(here),

  

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

这对空格无效。您需要做的是使用str_replace()添加斜杠,如下所示:

$new_string = str_replace(" ", "\\ ", $old_string);

答案 3 :(得分:3)

我在Windows和Linux主机上使用过exec()之前带空格的路径,在这两种情况下引用路径对我来说都很完美。

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

答案 4 :(得分:2)

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

exec("php bin/createjob.php '$source' '$output_dir'", $output);

btw不仅可以用于参数,还可以用于命令本身:

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

无论如何都要使用escapeshellcmd()

答案 5 :(得分:0)

当使用exec()和soffice(LibreOffice)时,这对我有用:

$file_name = "Some, file name.xlsx";
exec('/usr/bin/soffice --headless --convert-to pdf '."'".$file_name."'".' 2>&1', $output, $r);