1

I have a bash script where I need to prompt for a password. I'm using whiptail to capture the password. I need to be able to differentiate between an empty password and the "Cancel" button being selected. Cancel normally returns an error code of 1.

Why does the following code not detect the user selecting the "Cancel" button?

#!/bin/bash

function get_password() {
    local password=`whiptail --clear \
        --title "Password" \
        --passwordbox "Enter your login password:" \
        8 68 \
        2>&1 >/dev/tty`
    local err=$?
    if [ "$err" -ne 0 ]; then
        >&2 echo "Cancelled"
        return 1
    fi
    if [ -z "$password" ]; then
        >&2 echo "No password entered"
        return 1
    fi

    echo "Password entered: $password"
}

get_password

I figured out that I can make it work by changing local password to password, effectively storing it in a global variable rather than a local variable. I'd like to avoid doing that, but I can't figure out how to make it work. Is there a proper way of doing this with local variables?

2
  • What is not working here? cancel detection ? Commented Apr 21, 2019 at 17:23
  • @Anubis, the code as shown above will never have err set to 1 if the user cancels it. If I remove the local keyword (making password a global variable), the code will properly detect the cancel button being selected. Commented Apr 21, 2019 at 17:24

2 Answers 2

2

local is a command, so $? is the status of local, which succeeds independent of the status of the command substitution.

If you want the variable to be local, first declare it and then use it:

local password
password=`whiptail --clear \
    --title "Password" \
    --passwordbox "Enter your login password:" \
    8 68 \
    2>&1 >/dev/tty`
Sign up to request clarification or add additional context in comments.

Comments

1

Exit code of local password=$(...) is the status of the local command (which should ideally be 0). local is treated as a command and the return code of $(...) is overridden by that.

To avoid that, create the local variable first and then do the assignment.

i.e.

local password    # return code of this is always 0
password=`whiptail --clear \
    --title "Password" \
    --passwordbox "Enter your login password:" \
    8 68 \
    2>&1 >/dev/tty`
local err=$?    

1 Comment

Doh. Thanks, this makes sense. Somehow I did not infer this from any bash documentation I've come across.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.