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);