简体   繁体   中英

why my shell script does not work properly?

I'm trying to test if a script ends correctly or not. I ask to user to enter yes/no. if the answer is yes ,the script will do something, if the answer is no, the script will show an error message. And finally if the answer is something else, the script will show another different error message. When I answer yes, the script must end correctly. (exit code 0) When I answer no, the script must end incorrectly. (exit code 1) When I answer something else, the script must end incorrectly. (exit code 1). My problem is when I provoke an exit code 1, the script do not shows any error message. After the script finishes i execute $? and I see the exit code is 1, so the if-else is working well, but seems the function isn't working

#!/bin/bash
function testingexit(){
    if [ "$?" = "0" ]
        then
        echo "test ok"
    else
        echo "test error"
    fi
}
read -p "(yes/no): " answer
if [ "$answer" = "yes" ] || [ "$answer" = "YES" ]
    then
    echo "hello"
elif [ "$answer" = "no" ] || [ "$answer" = "NO" ]
    then
    echo "error1"
    exit 1
else
    echo "error2"
    exit 1
fi


#!/bin/bash
clear
function menu()
{
    echo "¿Hi what do you want to do?:"
    echo
    echo "1) opt1"
    echo "2) opt2"
    echo "2) opt3"
    echo "9) Exit"
    echo
    echo -n "Choose an option: "
}
# the function use 'return' instead of 'exit'
function get_user_input {
read -p "Do you want to start the program?: " answer        if [[ "$answer" =~ ^yes|YES$ ]] 

        then
        return 0
    elif [[ "$answer" =~ ^no|NO$ ]] 
        then
        return 1
    else
        return 2
    fi
}

# invoke
get_user_input
func_return=$?
function testingexit () {
if [ $func_return = "0" ]
    then
    echo "test ok"
else
    echo "test error"
fi
}
# default option
opt="0"

# loop  9 to exit
until [ "$opt" -eq "9" ];
do
    case $opt in
        1)
        echo "opt1"
        menu
        ;;
        2)
        echo "opt2"
        menu
        ;;
        3)
        echo "opt3"
        menu
        ;;
        *)
        menu
        ;;
    esac
read opt
done
testingexit
exit $func_return

Now I want to use this menu when i answer yes. when i answer no, menu shouldn't be shown and the script must end displaying a message "test error".

your script works fine here:

chris@druidstudio:~⟫ ~/tmp/test.sh ; echo $?
(yes/no): no
error1
1   
chris@druidstudio:~⟫ ~/tmp/test.sh ; echo $?
(yes/no): wibble
error2
1   
chris@druidstudio:~⟫ ~/tmp/test.sh ; echo $?
(yes/no): yes 
hello
0   
chris@druidstudio:~⟫ 

I don't see the point of the function, you never call it.

Your script would never work for two reasons:

  1. You never called your function testingexit()
  2. Even if you called it, it wouldn't work because you can't run anything inside the script after you called exit , since 'exit' aborts the script.

Why don't you rewrite you script as follows:

#!/bin/bash

# the function use 'return' instead of 'exit'
function get_user_input {
    read -p "(yes/no): " answer
    if [[ "$answer" =~ ^yes|YES$ ]] 
        then
        echo "hello"
        return 0
    elif [[ "$answer" =~ ^no|NO$ ]] 
        then
        echo "error1"
        return 1
    else
        echo "error2"
        return 2
    fi
}

# invoke
get_user_input
func_return=$?

if [ $func_return = "0" ]
    then
    echo "test ok"
else
    echo "test error"
fi

exit $func_return

Your function testingexit is never called, you need to use trap to make it get called when your program ends:

testingexit() {
   ...
}
trap testingexit EXIT

read -rp "(yes/no): " answer
...

You can also consider changing the if statements to a case statement:

case "$answer" in
  yes|YES)
    echo "hello";;
  no|NO)
    echo "error1"
    exit 1;;
  *)
    echo "error2"
    exit 1;;
esac

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM