1

我正在尝试通过 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;

运行此结果:

  • $stdout:克隆到 'abc'...
  • $标准错误:空

从命令行直接运行 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 实现中实际捕获的要多。

怎么了?

4

1 回答 1

3

好消息是您的代码是正确的。令人困惑的部分是 git 根据标准错误是否连接到终端来更改其输出。

要从 shell 重现 Perl 程序的输出,请在 bash 提示符下运行以下命令。

$ git clone http://my.gitserver.com/scm/tst2/abc.git |& cat
克隆成'abc'...

重定向将|&git 的标准错误(预期的进度输出所在的位置)和标准输出连接到管道而不是终端。

要查看通常的输出,您必须将 git 的标准错误连接到伪终端,也称为ptyIPC::Run支持伪终端,在其文档的伪终端部分中进行了描述。不要使用 重定向标准错误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";

产生类似于

成功=[1]
标准输出=[]
stderr=[正在克隆到 'abc'...
远程:计数对象:2818,完成。
远程:压缩对象:100% (1965/1965),完成。
远程:总计 2818(增量 1200),重复使用 770(增量 287)
接收对象:100% (2818/2818), 2.19 MiB | 1.19 MiB/s,完成。
解决增量:100% (1200/1200),完成。
检查连接...完成。
]
于 2016-07-21T15:21:25.270 回答