使用 Ruby 调用 shell 脚本退出代码总是 returns 为 0
Using Ruby to call a shell script exit code always returns as 0
我正在使用 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 [ "" -ne 0 ] ; then
echo " failed. INSTALLATION FAILED! Exiting.";
exit 1;
fi
}
{
function 1
function 2..
function ..20
} | tee -a logFile.log
所以脚本运行的最后一件事总是这个日志文件,这意味着我永远不会得到真正的退出代码。
Echo 是 True;而是检查你的最后一个过程
怎么了
您当前的代码几乎总是将其 if 语句评估为真,因为 /bin/echo
或 shell 内置 echo
return 成功,除非标准输出已关闭或某些发生其他错误。考虑以下 Bash 片段:
echo `false`; echo $? # 0
echo >&-; echo $? # 1
此外,在您当前的代码中,exitCode 是一个字符串,而不是一个整数。它被分配为 echo 命令的标准输出,因此在尝试进行有效比较之前,您必须对其调用 Kernel#Integer or String#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
我正在使用 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 [ "" -ne 0 ] ; then
echo " failed. INSTALLATION FAILED! Exiting.";
exit 1;
fi
}
{
function 1
function 2..
function ..20
} | tee -a logFile.log
所以脚本运行的最后一件事总是这个日志文件,这意味着我永远不会得到真正的退出代码。
Echo 是 True;而是检查你的最后一个过程
怎么了
您当前的代码几乎总是将其 if 语句评估为真,因为 /bin/echo
或 shell 内置 echo
return 成功,除非标准输出已关闭或某些发生其他错误。考虑以下 Bash 片段:
echo `false`; echo $? # 0
echo >&-; echo $? # 1
此外,在您当前的代码中,exitCode 是一个字符串,而不是一个整数。它被分配为 echo 命令的标准输出,因此在尝试进行有效比较之前,您必须对其调用 Kernel#Integer or String#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