aalosious
aalosious

Reputation: 588

Otherwise functioning shell script behaves abnormally when put inside a function

for the sake of learning, I tried to modify a shell script that took workspace as argument to prompt the user if no argument is given. I came up with this:

getWorkspaceFromUser() {
    while true; do
        read -e -p "Is current directory your workspace? (y/n): " input_yn
        case $input_yn in
            [Yy]* )
                workspace="."
                break
                ;;
            [Nn]* )
                while true; do
                    read -e -p "Please enter the path to your workspace (use tabs)? " input_ws
                    if [ -d $input_ws ]; then
                        workspace=$input_ws
                        break
                    fi
                    echo "Please enter a valid directory. "
                done
                break
                ;;
            * ) echo "Please answer yes or no."
                ;;
        esac
    done
    echo $workspace
}

# check if a valid workspace was provided. Otherwise, get it from user.
if [ $# -gt 0 ] && [ -d $1 ]; then
    workspace=$1
else
    workspace=$(getWorkspaceFromUser)
fi

#...... rest of the
#...... processing follows

I can see the abnormal behavior if I input a character other than y/n for the first prompt, or if I input an invalid path for the second prompt. For example:

Is current directory your workspace? (y/n): k
Is current directory your workspace? (y/n): k
Is current directory your workspace? (y/n): k
Is current directory your workspace? (y/n): y
Please answer yes or no. Please answer yes or no. Please answer yes or no. .

Is current directory your workspace? (y/n): n
Please enter the path to your workspace (use tabs)? gggg
Please enter the path to your workspace (use tabs)? gggg
Please enter the path to your workspace (use tabs)? gggg
Please enter the path to your workspace (use tabs)? /home
Please enter a valid directory. Please enter a valid directory. Please enter a valid directory. /home

What's puzzling is that if I save the contents of getWorkspaceFromUser() as a shell script and run it, it works as expected. Does anyone know what's going on here? Thanks.

Upvotes: 1

Views: 52

Answers (1)

that other guy
that other guy

Reputation: 123470

You are basically doing both:

echo "Please answer yes or no."
echo $workspace

and assuming that bash will figure out which is intended for the user and which is intended for capture.

Instead, you should write all status messages to stderr:

echo >&2 "Please answer yes or no."
...
echo >&2 "Please enter a valid directory. "

That way they'll end up on screen instead of in your workspace variable.

Upvotes: 2

Related Questions