我正在尝试通过IPC :: Run从perl执行git命令,该命令从perl变量中的git捕获STDOUT / STDERR-Output。
这就是我所做的:
use strict;
use warnings;
use IPC::Run;
my $stderr, $stdout, @cmd;
push @cmd, "git";
push @cmd, "clone";
push @cmd, "http://my.gitserver.com/scm/tst2/abc.git";
my $success = IPC::Run::run \@cmd, '>', \$stdout, '2>', \$stderr;
1;
运行此结果:
直接从命令行运行git命令会产生以下输出:
$ git clone http://my.gitserver.com/scm/tst2/abc.git
Cloning into 'abc'...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
正如您所看到的,git在命令行上产生的输出比我在perl实现中实际捕获的输出要多。
出了什么问题?
答案 0 :(得分:1)
好消息是你的代码是正确的。令人困惑的部分是git根据标准错误是否连接到终端来改变其输出。
要从shell重现Perl程序的输出,请从bash提示符运行以下命令。
$ git clone http://my.gitserver.com/scm/tst2/abc.git |& cat Cloning into 'abc'...
|&
重定向将git的标准错误(预期进度输出的位置)和标准输出连接到管道而不是终端。
要查看常规输出,您必须将git的标准错误连接到pseudo terminal,也称为pty。 IPC::Run
支持伪终端,在其文档的Pseudo Terminals section中有所描述。不要使用2>
重定向标准错误,而是使用2>pty>
。请注意,这会向IO::Pty
添加依赖项。
调整run
重定向并添加调试输出,如下面的代码所示
#! /usr/bin/env perl
use strict;
use warnings;
use IPC::Run;
my $cloneurl = 'http://my.gitserver.com/scm/tst2/abc.git';
my($stderr,$stdout);
my @cmd = (qw/ git clone /, $cloneurl);
my $success = IPC::Run::run \@cmd, '>', \$stdout, '2>pty>', \$stderr;
print "success=[$success]\n";
print "stdout=[$stdout]\n";
print "stderr=[$stderr]\n";
产生类似于
的输出success=[1] stdout=[] stderr=[Cloning into 'abc'... remote: Counting objects: 2818, done. remote: Compressing objects: 100% (1965/1965), done. remote: Total 2818 (delta 1200), reused 770 (delta 287) Receiving objects: 100% (2818/2818), 2.19 MiB | 1.19 MiB/s, done. Resolving deltas: 100% (1200/1200), done. Checking connectivity... done. ]