Pregunta

Tengo que arreglar este pequeño insecto. En primer lugar, vamos a hablar de un pequeño hecho: En CLI en Windows, no se puede ejecutar un programa con un espacio en su camino, a menos escapado:

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:\>

Estoy usando proc_open ... proc_close en PHP para ejecutar un proceso (programa), ejemplo:

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

Ejemplo 1

  • Resultado: 1
  • STDERR: 'C: \ a' no se reconoce como un comando interno o externo, programa o por lotes operable archivo.
  • STDOUT:

Ejemplo 2

  • Resultado: 1
  • STDERR: 'C: \ a' no se reconoce como un comando interno o externo, programa o por lotes operable archivo.
  • STDOUT:

Ejemplo 3

  • Resultado: 1
  • STDERR:. El nombre de archivo, nombre de directorio o etiqueta de volumen sintaxis es incorrecta
  • STDOUT:

Así que ya ves, cualquiera de los casos (comillas dobles o no) el código de falla. ¿Soy yo o me estoy perdiendo algo?

¿Fue útil?

Solución

Lo más lamentable, la solución no funciona como se espera, sin embargo primera sugerencia de Pekka me dio una idea:

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

Esta es la plataforma específica, y espero no tener que solucionar este problema Linux más también. Hasta ahora funciona bien!

Otros consejos

Otra manera de resolver esto es poniendo comillas dobles adicionales al inicio y al final del comando.

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

He encontrado esta solución en https://bugs.php.net/bug. php? id = 49139
Parece raro, pero bueno - es de Windows ...: D

Este es strage.

Ideas de solución no probados:

  • Usar una variable de entorno temporal:

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

    (ni idea de si esto funcionará para proc_open)

  • El uso del nombre de archivo 8.3 si eso puede ser de algún modo exagerado en PHP - sin duda sería factible utilizando otro exec()

  • proc_open() tiene una opción para cmd.exe de derivación - podría valer la pena probar si el sistema de archivos de alguna manera se encarga de las cotizaciones de manera diferente

  • Trate de escapar de las cotizaciones \"

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top