Php 如何通过passthru绘制进度条(例如w/scp)?

Php 如何通过passthru绘制进度条(例如w/scp)?,php,bash,scp,Php,Bash,Scp,我正在使用运行scp。通常,scp会输出一个进度条,但当我使用passthru时,不会绘制进度条。我想估计一下转学需要多长时间。有没有办法强制它显示?大多数与libc链接的程序在决定对输出着色之前,都会使用函数isatty检查stdout是否为终端。因此,要确保ANSI终端转义序列不会阻塞管道或被重定向到文件中passthru()不会在终端中运行该命令 在PHP中,您可以使用proc_open()打开一个进程,并将其显示为stdout的终端。以手册中的这个例子为例,我对手册进行了修改,将stdo

我正在使用运行
scp
。通常,scp会输出一个进度条,但当我使用
passthru
时,不会绘制进度条。我想估计一下转学需要多长时间。有没有办法强制它显示?

大多数与libc链接的程序在决定对输出着色之前,都会使用函数
isatty
检查stdout是否为终端。因此,要确保ANSI终端转义序列不会阻塞管道或被重定向到文件中
passthru()
不会在终端中运行该命令

在PHP中,您可以使用
proc_open()
打开一个进程,并将其显示为stdout的终端。以手册中的这个例子为例,我对手册进行了修改,将
stdout
stderr
使用
pty
而不是
pipe

$descriptorspec = array(
   0 => array("pipe", "r"), // stdin is a pipe that the child will read from
   1 => array("pty", "w"),  // stdout is a pty that the child will write to
   2 => array("pty", "w")   // stderr is a pty that the child will write to
);

$cwd = '/tmp';
$env = array('some_option' => 'aeiou');

$process = proc_open('command', $descriptorspec, $pipes, $cwd, $env);

if (is_resource($process)) {
    // $pipes now looks like this:
    // 0 => writeable handle connected to child stdin
    // 1 => readable handle connected to child stdout
    // Any error output will be appended to /tmp/error-output.txt

    fwrite($pipes[0], '<?php print_r($_ENV); ?>');
    fclose($pipes[0]);

    echo stream_get_contents($pipes[1]);
    fclose($pipes[1]);
    echo stream_get_contents($pipes[2]);
    fclose($pipes[2]);

    // It is important that you close any pipes before calling
    // proc_close in order to avoid a deadlock
    $return_value = proc_close($process);

    echo "command returned $return_value\n";
}
$descriptorspec=数组(
0=>array(“pipe”,“r”),//stdin是子级将从中读取的管道
1=>array(“pty”,“w”),//stdout是子级将写入的pty
2=>array(“pty”,“w”)//stderr是子级将写入的pty
);
$cwd='/tmp';
$env=array('some_option'=>'aeiou');
$process=proc_open('command',$descriptorspec,$pipes,$cwd,$env);
如果(是_资源($process)){
//$pipes现在看起来如下所示:
//0=>连接到子标准的可写句柄
//1=>连接到子标准输出的可读句柄
//任何错误输出都将附加到/tmp/error-output.txt
fwrite($pipes[0],'');
fclose($pipes[0]);
回波流获取内容($pipes[1]);
fclose($pipes[1]);
回波流获取内容($pipes[2]);
fclose($pipes[2]);
//在呼叫之前关闭所有管道非常重要
//程序关闭以避免死锁
$return\u value=proc\u close($process);
echo“命令返回$return\u值\n”;
}


但是,您也可以在启动进程时使用
LD_PRELOAD
,并以它认为stdout是终端的方式欺骗程序。(有点刻薄,但有时是最后的手段)。我在这里已经描述过:

我确信
scp
检测到它的输出不是PTY。你应该有更好的运气,期待: