使用Ruby调用shell脚本退出代码始终返回0

时间:2017-08-15 19:17:33

标签: ruby linux shell exit-code

我使用Ruby通过以下方式调用shell脚本:

%x[ /root/script.sh -k -m -l -w -p]
exitCode = %x[echo $?]

if exitCode != 0
  do something
else
  do something else
end

我的问题是,即使我强制脚本失败,退出代码也总是等于0。如何正确获取脚本的退出代码?

编辑: 好的,今天早上来了,并开始挖掘脚本,因为我无法得到除0以外的任何错误代码。脚本看起来像这样......

failed() {
      if [ "$1" -ne 0 ] ; then
          echo "$2 failed. INSTALLATION FAILED! Exiting.";
      exit 1;
    fi
}

{

function 1
function 2..
function ..20

} | tee -a logFile.log 

所以脚本运行的最后一件事总是这个日志文件意味着我永远不会得到真正的退出代码。

1 个答案:

答案 0 :(得分:2)

Echo 是真的;检查你的上一个过程

错误

您当前的代码几乎总是将其if语句评估为true,因为/bin/echo或shell builtin echo返回成功,除非标准输出已关闭或发生其他错误。请考虑以下Bash片段:

echo `false`; echo $? # 0
echo >&-; echo $?     # 1

此外,在您当前的代码中, exitCode 是String,而不是Integer。它被分配了echo命令的标准输出,因此在尝试进行有效比较之前,您必须在其上调用Kernel#IntegerString#to_i来转换变量。例如,考虑以下Ruby:

`echo $?`.class #=> String
"0" == 0        #=> false
"0".to_i == 0   #=> true

如何修复常规案例

您需要直接测试exit status,或检查捕获的输出。例如,在Ruby中,您可以使用以下命令测试 / bin / false 命令的最后状态:

captured_output = `/bin/false`
$?.exitstatus
#=> 1

修复您的具体示例

如果您对上述内容一无所知,只需删除所有非必需品即可修复您的代码。根据您的示例,您不需要临时变量,也不需要存储标准输出。除非您正在评估特定的非零退出状态,否则您甚至不需要直接检查流程状态,甚至不需要使用相等的声明。

遵循KISS原则,只评估Kernel#system电话的真实性。例如:

# Just call system if you don't care about the output.
# The result will be true, false, or nil.
if system('/root/script.sh -k -m -l -w -p')
  'clean exit'
else
  "non-zero exit: #{$?}"
end