PHP 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 перед тем, как он выполнит эту команду, стоит ли рассуждать, что мне нужно учитывать оба escape файла? Или это не так, как это работает?

Ответ 1

В соответствии с документами PHP,

Возвращает строку с обратными косыми чертами перед символами, которые должны быть указаны в запросах базы данных и т.д. Эти символы представляют собой одинарные кавычки ('), двойную кавычку ("), обратную косую черту() и NUL (байт NULL).

Похоже, вам придется предварительно заполнить пробелы.

Edit:

Несмотря на то, что это тема другого обсуждения, если производительность является проблемой, то, посмотрев на нее немного больше, кажется, что str_replace на самом деле довольно быстро, чем preg_replace:

Тест с меткой "str_replace()" был тем быстрее на 0,9053 секунды (потребовалось 10,3% времени.)

Первый тест занял 1,0093 секунды. (preg_replace)

Второй тест занял 0.104 секунды. (str_replace)

Тест найден здесь.

Ответ 2

Из документа PHP (здесь),

Возвращает строку с обратными косыми чертами перед символами, которые должны быть указаны в запросах базы данных и т.д. Эти символы представляют собой одинарные кавычки ('), двойную кавычку ("), обратную косую черту() и NUL (байт NULL).

Это ничего не будет делать для пробелов. Вам нужно будет использовать str_replace() для добавления косых черт, например:

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

Ответ 3

Я не верю, что addslashes() делает что-либо с пробелами. escapeshellarg() может быть тем, чего вы хотите. Документы на escapeshellarg

Ответ 4

Я использовал exec() с путями с пробелами до, как на хостах Windows, так и на Linux, и в обоих случаях цитирование пути отлично сработало для меня.

Тем не менее, если у вас нет контроля над безопасностью аргумента оболочки, сначала запустите его через escapeshellarg()!

Ответ 5

Вы можете очень хорошо использовать кавычки оболочки, так как это то, что выполняются всеми командами exec:

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

Это btw работает не только для аргументов, но и для самой команды:

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

В любом случае используйте escapeshellcmd().

Ответ 6

это работает для меня при использовании exec() с soffice (LibreOffice):

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