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

Posted

技术标签:

【中文标题】即使命令失败,退出状态也会返回“0”【英文标题】:exit status returns '0' even with command failure 【发布时间】:2021-09-24 07:17:41 【问题描述】:

我想使用以下代码将我的命令输出(标准输出和标准错误)重定向到 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 $result\n";
     exit;
   
   return $result;

输出:-

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

运行系统命令后,我期望退出状态应该是非零并且它必须进入 if 块。但它显示退出状态为0,尽管命令失败。

谢谢。

【问题讨论】:

【参考方案1】:

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

pipefail shell 选项(在 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 重定向等。

【讨论】:

我正在使用 tcsh。成功了,谢谢! @RAMA,回复“我正在使用 tcsh。”,不,你不是。 system 使用 /bin/sh

以上是关于即使命令失败,退出状态也会返回“0”的主要内容,如果未能解决你的问题,请参考以下文章

QProcess.start 不返回退出状态或退出代码

即使提取成功,unzip 也会返回退出代码 1

shell编程基础:逻辑运算

exit命令

linux 用户退出怎么命令

linux 用户退出怎么命令