Странная ошибка в PHP, пробелы в путях и Windows
Я должен исправить эту маленькую ошибку. Во-первых, давайте поговорим о небольшом факте: В CLI в Windows вы не можете запустить программу с пробелом в ее пути, если не экранировано:
C:>a b/c.bat
'a' is not recognized as an internal or external command,
operable program or batch file.
C:>"a b/c.bat"
C:>
Я через proc_open...proc_close в PHP для запуска процесса (программы), пример:
function _pipeExec($cmd,$input=''){
$proc=proc_open($cmd,array(0=>array('pipe','r'),
1=>array('pipe','w'),2=>array('pipe','w')),$pipes);
fwrite($pipes[0],$input);
fclose($pipes[0]);
$stdout=stream_get_contents($pipes[1]); // max execusion time exceeded ssue
fclose($pipes[1]);
$stderr=stream_get_contents($pipes[2]);
fclose($pipes[2]);
$rtn=proc_close($proc);
return array(
'stdout'=>$stdout,
'stderr'=>$stderr,
'return'=>(int)$rtn
);
}
// example 1
_pipeExec('C:a bc.bat -switch');
// example 2
_pipeExec('"C:a bc.bat" -switch');
// example 3 (sounds stupid but I had to try)
_pipeExec('""C:a bc.bat"" -switch');
Пример 1
- результат: 1
- STDERR: 'C:a' не распознается как внутренняя или внешняя команда, исполняемой программой или пакетным файл.
- STDOUT:
Пример 2
- результат: 1
- STDERR: 'C:a' не распознается как внутренняя или внешняя команда, исполняемой программой или пакетным файлом.
- STDOUT:
Пример 3
- результат: 1
- STDERR: имя файла, имя каталога или синтаксис метки тома неправильный.
- STDOUT:
Итак, вы видите, что в любом случае (двойные кавычки или нет) код терпит неудачу. Это я или я что-то упускаю?
3 ответов
к сожалению, исправление работает не так, как ожидалось, однако первое предложение Пекки дало мне идею:
$file='C:\a b\c';
$cmdl='/d /b /g';
if(strtolower(substr(PHP_OS,0,3))=='win') // if windows...
$file='cd '.escapeshellarg(dirname($file)).' && '.basename($file);
_pipeExec($file.' '.$cmdl);
это специфично для платформы, и я надеюсь, что мне не придется исправлять это над linux. Пока это работает хорошо!
другой способ решить эту проблему-поставить дополнительные двойные кавычки в начале и конце команды.
$process = 'C:\Program Files\nodejs\node.exe';
$arg1 = 'C:\Path to File\foo.js';
$cmd = sprintf('"%s" %s', $process, escapeshellarg($arg1));
if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {
$cmd = '"'.$cmd.'"';
}
_pipeExec($cmd);
Я нашел это решение на https://bugs.php.net/bug.php?id=49139
Это выглядит странно, но эй-это окна... : D
Это странное.
решение непроверенные идеи:
-
используйте временную переменную окружения:
exec('SET ENVPATH="C:\a b"'); proc_open('%ENVPATH%\c.bat' ....
(не знаю, будет ли это работать для proc_open)
используйте имя файла 8.3, если это можно каким - то образом получить в PHP-это, безусловно, будет выполнимо с помощью другого
exec()
proc_open()
имеет возможность обойтиcmd.exe
- возможно, стоит попробовать, если файловая система каким-то образом обрабатывает кавычки по-разномупопробуйте избежать кавычек
\"