【问题标题】:Bash exit status not working in scriptBash退出状态在脚本中不起作用
【发布时间】:2018-02-22 15:43:43
【问题描述】:

我编写了一个脚本,用于启动、停止和发送 Apache 的状态,消息取决于命令的输出。

我的大部分内容都是正确的,但我的错误没有正确打印出来。换句话说,即使我没有加载 Apache,“停止”它仍然会显示成功消息。

我需要帮助,以便在必要时打印我的错误消息。

#!/bin/bash

echo -e "\e[1;30mApache Web Server Control Script\e[0m"
echo
echo "Enter the operation number to perform (1-4): "
echo " 1 - Start the httpd server"
echo " 2 - Restart the httpd server"
echo " 3 - Stop the httpd server"
echo " 4 - Check httpd server status"
echo
echo -n "===> "
read NUMBER

EXITSTATUS=$?
echo
if [ $NUMBER -eq "1" ]; then
    systemctl start httpd
    if [ $EXITSTATUS -eq "0" ]; then
        echo -e "\e[1;32mThe return value of the command 'systemctl 
        start httpd' was 0.\e[0m"
        echo -e "\e[1;32mThe Apache web server was successfully 
        started.\e[0m"
    else
        echo -e "\e[1;31mThe return value of the command 'systemctl 
        start httpd' was 5.\e[0m"
    echo -e "\e[1;31mThe Apache web server was not successfully 
    started.\e[0m"
    fi  
fi 

if [ $NUMBER -eq "2" ]; then
    systemctl restart httpd
    if [ $EXITSTATUS -eq "0" ]; then
        echo -e "\e[1;32mThe return value of the command 'systemctl 
        restart httpd' was 0.\e[0m"
        echo -e "\e[1;32mThe Apache web server was successfully 
        restarted.\e[0m"
    else
        echo -e "\e[1;31mThe return value of the command 'systemctl 
        restart httpd' was 5.\e[0m"
        echo -e "\e[1;31mThe Apache web server was not successfully 
        restarted.\e[0m"
    fi  
fi

if [ $NUMBER -eq "3" ]; then
    systemctl stop httpd
    if [ $EXITSTATUS -eq "0" ]; then
        echo -e "\e[1;32mThe return value of the command 'systemctl 
        stop httpd' was 0.\e[0m"
        echo -e "\e[1;32mThe Apache web server was successfully 
        stopped\e[0m."
    else
        echo -e "\e[1;31mThe return value of the command 'systemctl 
        stop httpd' was 5.\e[0m"
        echo -e "\e[0;31mThe Apache web server was successfully 
        stopped.\e[0m"
    fi  
fi

if [ $NUMBER -eq "4" ]; then
    systemctl status httpd
    if [ $EXITSTATUS -eq "0" ]; then
        msg=$(systemctl status httpd)
    else
        echo -e "\e[1;31mThe Apache web server is not currently 
        running.\e[0m"
        echo $(msg)
    fi  
fi

if [[ $NUMBER != [1-4] ]]; then
    echo -e "\e[1;31mPlease select a valid choice: Exiting.\e[0m"
fi
exit 0

【问题讨论】:

  • 在这里尝试猜测您的意图...您在代码中编写EXITSTATUS=$?,然后在您应该使用$? 的地方使用$EXITSTATUS 的方式让我认为您的意思是EXITSTATUS作为$? 的别名,因此您可以使用$EXITSTATUS 作为$? 的替代品。这不是它是如何工作的(正如你所发现的那样)。相反,您只是创建了一个变量 EXITSTATUS,并为其分配了 $? 的当前值,即 0(read 命令成功)。随着代码的进行,$? 的值在每个命令之后都会发生变化,但 EXITSTATUS 的值不会发生变化。这不是别名!

标签: linux bash command-line error-handling


【解决方案1】:

变量EXITSTATUS 不包含systemctl 调用的退出代码,而是read 命令的退出代码。您可以将其重写为

systemctl start httpd
EXITSTATUS=$?
if [ $EXITSTATUS -eq 0 ]; then
[...]

或者更简单的

systemctl start httpd
if [ $? -eq 0 ]; then
[...]

仅当您想在其他地方使用它(例如,作为您自己脚本的退出代码)或必须在对值进行分支之前进行其他调用时,才需要将 $? 的值存储在变量中。

【讨论】:

  • 在这种情况下完全没有必要使用$?。要查看命令cmd 是否成功,请直接使用if cmd
  • 可能是这样,但我更喜欢这个是为了可读性(考虑带有许多开关的较长命令),并想提出它作为替代方案。
  • 我知道这里的错误退出状态是5,我认为这就是我们应该学习的;如何针对特定错误返回特定消息。即使删除apache然后运行脚本,它仍然显示成功。
  • @Hebruiser 如果您认为这是一个重要信息,那么您应该将其合并到您的问题文本中。但是,我看不出这与您的问题或我的回答有什么关系。
  • @Murphy 谢谢。只需使用“$?”就可以完美地工作。
【解决方案2】:

您没有在运行命令后设置变量$EXITSTATUS,因此它保持其原始值(read NUMBER 的退出状态)。

由于您只关心命令是否成功,因此最好避免完全使用它并将条件更改为例如:

if systemctl restart httpd; then
  # it was successful ($? would be 0)
fi

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-16
    • 2010-11-21
    • 2014-12-03
    • 1970-01-01
    • 2012-10-16
    • 2011-03-02
    相关资源
    最近更新 更多