如何在 Perl 中捕获输出和退出代码的同时执行外部脚本?

发布于 2024-08-20 07:51:45 字数 893 浏览 9 评论 0原文

我正在尝试从 Perl 脚本检查 SVN 标记是否存在。所以我尝试调用 svn info $url ,读取退出代码并抑制标准输出和标准错误流。然而,我很难优雅地做到这一点(可能有更好的方法向 SVN 询问标签,但这不是这里的重点):

my $output = `svn info $url/tags/$tag`;

这会在将输出放入 $output 时抑制输出。退出代码丢失。

my $output = `svn info $url/tags/$tag 2>&1`;

这会抑制 STDERR 和 STDOUT 并将它们都放入 $output 中。退出代码再次丢失。

my $exitcode = system("svn", "info", "$url/tags/$tag");

这会捕获退出代码,但实际的输出和错误流对用户是可见的。

open( STDERR, q{>}, "/dev/null" );
open my $fh, q{>}, "/dev/null";
select($fh);
if (system("svn", "info", "$url/tags/$tag") != 0) {
   select(STDOUT);
   print ("Tag doesn't exist!");
   do_something_with_exit();
}
select(STDOUT);
print "Exit code: $exitcode";

这会杀死 STDOUT 和 STDERR 并捕获退出代码,但它很丑陋,因为我必须记住将 STDOUT 切换回原始状态。

那么,有没有更优雅的解决方案呢?

I'm trying to check for an SVN tag existence from a Perl script. So I try calling svn info $url, read exit code and suppress standard output and standard error streams. However, I struggle to do this elegantly (there are probably better ways to ask SVN about a tag, but that's not the point here):

my $output = `svn info $url/tags/$tag`;

This suppresses the output while putting it into $output. Exit code is lost.

my $output = `svn info $url/tags/$tag 2>&1`;

This suppresses both STDERR and STDOUT and puts them both into $output. Exit code is again lost.

my $exitcode = system("svn", "info", "$url/tags/$tag");

This catches the exit code, but the actual output and error stream is visible to the user.

open( STDERR, q{>}, "/dev/null" );
open my $fh, q{>}, "/dev/null";
select($fh);
if (system("svn", "info", "$url/tags/$tag") != 0) {
   select(STDOUT);
   print ("Tag doesn't exist!");
   do_something_with_exit();
}
select(STDOUT);
print "Exit code: $exitcode";

This kills the STDOUT and STDERR and catches the exit code, but it's ugly because I'd have to remeber to switch the STDOUT back to original.

So, is there any more elegant solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

欲拥i 2024-08-27 07:51:45

尝试使用 $?.eg

my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;

Try using $?.e.g.

my $output = `svn info $url/tags/$tag`;
my $extcode = $?>>8;

等数载,海棠开 2024-08-27 07:51:45

当您尝试使用 IPC::System::Simple 时会发生什么?该模块处理此类问题的大部分细节:

 use IPC::System::Simple qw(capturex $EXITVAL);

 my $output = capturex( "some_command", @args );
 my $exit   = $EXITVAL;

What happens when you try it with IPC::System::Simple? That module handles most of the details of these sorts of problems:

 use IPC::System::Simple qw(capturex $EXITVAL);

 my $output = capturex( "some_command", @args );
 my $exit   = $EXITVAL;
柠檬色的秋千 2024-08-27 07:51:45
 my $output = `svn info $url/tags/$tag 2>&1`;

这会抑制 STDERR 和 STDOUT 并将它们都放入 $output 中。退出代码再次丢失

您确定退出代码丢失吗?当我尝试此操作时,我在 $? 中获得退出代码。

 my $output = `svn info $url/tags/$tag 2>&1`;

This suppresses both STDERR and STDOUT and puts them both into $output. Exit code is again lost

Are you sure the exit code is lost? When I try this, I get the exit code in $?.

怎言笑 2024-08-27 07:51:45

模块 IPC::Run3 给出对输入和输出的非常细粒度的控制。

use IPC::Run3;
run3 \@cmd, \$in, \$out, \$err;

您可以将相同的变量传递给 \$out\$err,它将执行您所期望的操作,合并两个流。输入是不必要的,因此您可以传递 undef (“从父进程继承”)或 \undef (“关闭文件句柄”。)

IPC:: Run3::run3() 根据退出代码返回 true 或 false,并根据“perlvar”将子进程的实际退出代码保留在 $? 中。

在你的情况下你会跑

use IPC::Run3

my @cmd = ('svn', 'info', "$url/tags/$tag");
my $out;
my $rv = run3(\@cmd, \undef, \$out, \$out);
if ($rv) {
    # process $out
}
else {
    die "error: $@";
}

The module IPC::Run3 gives very fine-grained control over the input and output.

use IPC::Run3;
run3 \@cmd, \$in, \$out, \$err;

You can pass the same variable to \$out and \$err and it will do what you expect, combining both streams. The input is unnecessary, and so you can pass either undef ("inherit from parent process") or \undef ("closed filehandle".)

IPC::Run3::run3() returns true or false depending on the exit code, and leaves the actual exit code of the child process in $? as per 'perlvar'.

In your case you would run

use IPC::Run3

my @cmd = ('svn', 'info', "$url/tags/$tag");
my $out;
my $rv = run3(\@cmd, \undef, \$out, \$out);
if ($rv) {
    # process $out
}
else {
    die "error: $@";
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文