Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP中的奇怪错误,路径和窗口中的空格_Php_Windows_Path_Command Line Interface_Space - Fatal编程技术网

PHP中的奇怪错误,路径和窗口中的空格

PHP中的奇怪错误,路径和窗口中的空格,php,windows,path,command-line-interface,space,Php,Windows,Path,Command Line Interface,Space,我得把这个小虫子修好。首先,让我们谈谈一个小事实: 在Windows上的CLI中,无法运行路径中有空格的程序,除非: 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:\> 我正在使用PHP中的proc_open…proc_close运行一个进程(程序),例如: function

我得把这个小虫子修好。首先,让我们谈谈一个小事实: 在Windows上的CLI中,无法运行路径中有空格的程序,除非:

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:\>
我正在使用PHP中的proc_open…proc_close运行一个进程(程序),例如:

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'未被识别为内部或外部命令, 可操作的程序或批处理文件
  • 标准:
示例2

  • 结果:1
  • STDERR:'C:\a'未被识别为内部或外部命令, 可操作的程序或批处理文件
  • 标准:
示例3

  • 结果:1
  • STDERR:文件名、目录名或卷标语法不正确
  • 标准:
因此,您可以看到,无论哪种情况(双引号或非双引号),代码都会失败。 是我还是我遗漏了什么?

这是strage

未经测试的解决方案:

  • 使用临时环境变量:

    exec('SET ENVPATH="C:\a b"');
    proc_open('%ENVPATH%\c.bat' ....
    
    (不知道这是否适用于proc_open)

  • 如果可以在PHP中以某种方式获取文件名,请使用8.3文件名-使用另一个
    exec()

  • proc\u open()
    有一个选项可以绕过
    cmd.exe
    ——如果文件系统以不同方式处理引号,可能值得一试

  • 尝试转义引号
    \“


最不幸的是,修复程序没有按预期工作,但是Pekka的第一个建议给了我一个想法:

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

这看起来很奇怪,但是嘿-这是Windows…:D

在黑暗中拍摄的,但是你能尝试切换引号类型吗?(
)我没有这方面的经验,但是在命令提示符中运行“a b/c.bat”,在PHP中调用“c:\a b\c.bat”,包括引号内的路径。也许调用C:\'ab\C.bat“有效吗?@Pekka,我得到的结果与示例3相同;单引号似乎不像双引号那样是容器字符。@deltreme,这也不管用。你试过最简单的吗?C:\\“AB”\\C.batth绕过cmd.exe给了我一个想法:
cmd“C:\\AB\\C.bat”
proc\u open有一个参数可以传递环境变量,更好地使用它。@Christian啊,很有趣。可能有用。也许还可以试着打电话给毒蛇好点!别介意我先前的评论。我的问题不是关于
cmd.exe
;我实际上运行的是程序而不是批处理文件(例如:C:\b\C.exe)。两者都有相同的问题(但程序当然不依赖cmd.exe)。好吧,这“起作用”,但我失去了对过程的控制,所以,还没有修复:(嗨,在我的代码中尝试使用你的解决方案,发现有一个语法错误。你有一个悬空)在第5行的末尾。我会修复它,但编辑时有一个最小字符限制。cheers@ted.strauss谢谢修复了。这是一个很好的解决方法。我看不出这在linux上会失败的任何原因。这种解决方案很奇怪,但它可以工作,而且比仅仅为了运行命令而cd'ing到目录更明智。请注意,is_可执行文件不适用于引号内的路径。如果您使用的是proc_open(如OP文章中所述),那么在Windows上使用“其他_选项”参数proc_open的值为array('bypass_shell'=>true)意味着整个命令不需要包装(但您仍然需要转义\(如\\),并引用包含空格的路径(如“C:\\Program Files\\”)。使用bypass_shell还意味着使用的cmd.exe进程少了一个(在W7上也有一个conhost.exe进程-可能在W8和W10上也有,我不知道)