Question

Je dois corriger ce petit bug. Tout d'abord, nous allons parler d'un petit fait: Dans CLI sous Windows, vous ne pouvez pas exécuter un programme avec un espace dans son chemin, à moins échappé:

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

J'utilise proc_open ... proc_close en PHP pour exécuter un processus (programme), par exemple:

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

Exemple 1

  • : 1
  • STDERR: 'C: \ a' est pas reconnu comme une commande interne ou externe, fichier de programme ou d'un lot utilisable.
  • STDOUT:

Exemple 2

  • : 1
  • STDERR: 'C: \ a' est pas reconnu comme une commande interne ou externe, fichier de programme ou d'un lot utilisable.
  • STDOUT:

Exemple 3

  • : 1
  • STDERR:. Le nom de fichier, nom de répertoire ou la syntaxe étiquette de volume est incorrect
  • STDOUT:

Donc, vous voyez, que ce soit le cas (guillemets doubles ou non) le code échoue. Est-ce moi ou suis-je manque quelque chose?

Était-ce utile?

La solution

La plupart malheureusement, le correctif ne fonctionne pas comme prévu, mais la première suggestion de Pekka m'a donné une idée:

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

Ceci est la plate-forme spécifique, et j'espère ne pas avoir à résoudre ce problème sur Linux. Jusqu'à présent, il fonctionne bien!

Autres conseils

Une autre façon de résoudre c'est en mettant des guillemets doubles supplémentaires au début et à la fin de la commande.

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

J'ai trouvé cette solution sur https://bugs.php.net/bug. php? id = 49139
Il fait un peu bizarre, mais bon - il est de Windows ...: D

Ceci est strage.

Idées de contournement non testées:

  • Utilisez une variable d'environnement temporaire:

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

    (aucune idée si cela fonctionnera pour proc_open)

  • Utilisez le nom de fichier 8.3 si cela peut en quelque sorte tiré par les cheveux en PHP - serait certainement faisable d'utiliser un autre exec()

  • proc_open() a une option pour contourner cmd.exe - peut-être la peine d'essayer dans le cas où le système de fichiers gère en quelque sorte les citations différemment

  • Essayez d'échapper aux citations \"

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top