如何在perl脚本中忽略shell命令的退出状态

Posted

技术标签:

【中文标题】如何在perl脚本中忽略shell命令的退出状态【英文标题】:how to ignore exit status from shell command in perl script 【发布时间】:2012-09-03 06:21:08 【问题描述】:

我有以下代码,其中我使用了一个命令,该命令用作文件打开的输入。

当我的命令 $cmd 给出非零退出状态时,我的脚本退出。我希望它仍然继续并完成脚本中的其余事情

$cmd = 'ps -u psharma';
open( my $fh, "-|",$cmd ) || die( "$cmd failed: $!" );
my @lines = <$fh>;
close($fh) || die $! ? "Close for $cmd failed: $!" : "Exit status $? from command $cmd";

【问题讨论】:

你最后的 die 声明非常模棱两可。它看起来要么检查die $! 的返回值,要么选择一个字符串作为参数来死。无论哪种方式,如果关闭失败,脚本仍然会死掉。你怎么期望它不会呢? 我实际上想检查一下,错误是否是由 $cmd 或 Close() 文件处理程序的非零退出状态引发的。这样做的目的是确保脚本的其余部分即使 $cmd 的退出状态非零也能执行。 【参考方案1】:

不要使用 die,而是尝试使用 Carp 警告您它没有成功退出。它仍然会继续执行脚本。

carp ("Did not exit command successfully!\n") if (! close ($fh) );

【讨论】:

【参考方案2】:

如果这是整个脚本,那么如果 cmd 的执行返回非零,它将在最后一行终止。 如果你想在这段代码之外继续执行,那么你不应该在最后一行删除 die 吗?

【讨论】:

【参考方案3】:
close($fh) || die $! ? "Close for $cmd failed: $!" : "Exit status $? from command $cmd";

此代码已检查 $!/$? (errno/$cmd 退出状态)。所以你可以将die 移动得更深:

close($fh) || $! 
    ? die "Close for $cmd failed: $!" 
    : warn "Exit status $? from command $cmd";

但是,我认为明确的if 在这里可能更具可读性。

【讨论】:

【参考方案4】:

You can wrap everything in an eval block and check the "magic variable" $@,像这样:

use strict; #always
use warnings; #always

my $cmd = 'ps -u psharma';

my $fh; #defining outside the scope of the eval block
my @lines; #ditto

eval 
    open $fh, "-|", $cmd 
        or die "$cmd failed: $!";

    @lines = <$fh>;
    close $fh
        or die $!
               ? "Close for $cmd failed: $!"
               : "Exit status $? from command $cmd";


if($@) 

    warn "Something bad happened: $@\n";

#If you made it here with no warning, then everything's okay.

您还可以查看Try::Tiny,它允许基本的try/catch/finally 块。

【讨论】:

以上是关于如何在perl脚本中忽略shell命令的退出状态的主要内容,如果未能解决你的问题,请参考以下文章

在 Perl 中从 STDIN 捕获退出状态

shell 脚本 ssh 命令退出状态

Shell命令的退出状态及错误检查

忽略 CalledProcessError

exit命令

在c ++中捕获shell脚本退出状态[重复]