Странная ошибка в PHP, пробелы в путях и Windows - PullRequest
7 голосов
/ 19 ноября 2010

Я должен исправить эту маленькую ошибку. Сначала поговорим о небольшом факте: В 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 b\\c.bat -switch');
// example 2
_pipeExec('"C:\\a b\\c.bat" -switch');
// example 3 (sounds stupid but I had to try)
_pipeExec('""C:\\a b\\c.bat"" -switch');

Пример 1

  • РЕЗУЛЬТАТ: 1
  • STDERR: «C: \ a» не распознается как внутренняя или внешняя команда, работающая программа или командный файл.
  • STDOUT:

Пример 2

  • РЕЗУЛЬТАТ: 1
  • STDERR: «C: \ a» не распознается как внутренняя или внешняя команда, работающая программа или командный файл.
  • STDOUT:

Пример 3

  • РЕЗУЛЬТАТ: 1
  • STDERR: неверный синтаксис имени файла, имени каталога или метки тома.
  • STDOUT:

Итак, вы видите, что в любом случае (двойные кавычки или нет) код завершается ошибкой. Это я или я что-то упустил?

Ответы [ 3 ]

4 голосов
/ 10 декабря 2010

К сожалению, исправление не работает должным образом, однако первое предложение Пекки дало мне идею:

$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 тоже.Пока все работает хорошо!

1 голос
/ 08 апреля 2016

Другим способом решения этой проблемы является добавление дополнительных двойных кавычек в начале и конце команды.

$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

0 голосов
/ 19 ноября 2010

Это strage.

Неопробованные варианты обхода:

  • Использовать временную переменную среды:

    exec('SET ENVPATH="C:\a b"');
    proc_open('%ENVPATH%\c.bat' ....
    

    (не знаю, будет ли эторабота для proc_open)

  • Использовать имя файла 8.3, если это можно каким-то образом получить в PHP - это, безусловно, можно сделать с помощью другого exec()

  • proc_open() имеет возможность обойти cmd.exe - возможно, стоит попробовать, если файловая система каким-то образом обрабатывает кавычки

  • Попробуйте экранировать кавычки \"

...