即使命令失败,退出状态也会返回“0”

我想使用以下代码将我的命令输出(标准输出和标准错误)重定向到 test.log 文件。

我试图通过提供一些无效的选项(-force)来检查我的命令的退出状态ls

use strict;
use warnings;

#system("ls 2>&1 | tee logfile");
#system("ls > lllog ");'
my $cmd = &exec_cmd("cd reg_folder && ls -force 2>&1 | tee test.log");

sub exec_cmd{
   system(@_);
   my $result = $?;
   print "===result $result===n";
   if(($result) != 0) {
     print "status $resultn";
     exit;
   }
   return $result;
}

输出:-

ls: invalid option -- 'e'
Try `ls --help' for more information.
===result 0===

运行 system command 后,我期望退出状态应该是非零,并且它必须进入if块。但它显示退出状态就0好像命令失败一样。

谢谢。

回答

问题是因为您将输出通过管道传输到tee test.log. 管道的退出状态是管道中最后一个命令的退出状态,并且tee正在成功退出。

pipefail外壳选项(可在bash,但不是在传统Bourne shell)中修改此行为:

管道的返回状态是最后一个命令的退出状态,除非pipefail 启用该选项。如果pipefail启用,管道的返回状态是以非零状态退出的最后一个(最右边)命令的值,如果所有命令都成功退出,则为零。(来自bash(1)手册页)

所以如果你要写...

my $cmd = &exec_cmd("set -o pipefail; cd reg_folder && ls -force 2>&1 | tee test.log");

...你会得到你期望的退出代码。


或者,您可以在 Perl 中处理更多机制,而不是依赖 shell 进行 i/o 重定向等。


以上是即使命令失败,退出状态也会返回“0”的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>