如何在 Perl 中捕获输出和退出代码的同时执行外部脚本?
我正在尝试从 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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
尝试使用
$?
.egTry using
$?
.e.g.当您尝试使用 IPC::System::Simple 时会发生什么?该模块处理此类问题的大部分细节:
What happens when you try it with IPC::System::Simple? That module handles most of the details of these sorts of problems:
您确定退出代码丢失吗?当我尝试此操作时,我在
$?
中获得退出代码。Are you sure the exit code is lost? When I try this, I get the exit code in
$?
.模块 IPC::Run3 给出对输入和输出的非常细粒度的控制。
您可以将相同的变量传递给
\$out
和\$err
,它将执行您所期望的操作,合并两个流。输入是不必要的,因此您可以传递undef
(“从父进程继承”)或\undef
(“关闭文件句柄”。)IPC:: Run3::run3()
根据退出代码返回 true 或 false,并根据“perlvar”将子进程的实际退出代码保留在$?
中。在你的情况下你会跑
The module IPC::Run3 gives very fine-grained control over the input and output.
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 eitherundef
("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