Parsing command line argument to skip user confirmations

About writing shell scripts and making the most of your shell
Forum rules
Topics in this forum are automatically closed 6 months after creation.
Locked
West_Training_8668
Level 2
Level 2
Posts: 71
Joined: Tue Mar 29, 2016 8:41 am

Parsing command line argument to skip user confirmations

Post by West_Training_8668 »

I'm trying to pass a few arguments like ./install.sh -yq but it doesn't work and I don't know where the problem is. It asks for confirmation even when I pass the argument. This is part of a post-install-script that I'm writing for Linux Minx.

Code: Select all

# http://stackoverflow.com/questions/43364510/prompt-to-continue-if-no-argument-passed
getopt --test > /dev/null
if [[ $? != 4 ]]; then
    echo "I’m sorry, $(getopt --test) failed in this environment."
    exit 1
fi

SHORT=yq
LONG=yes,quick

# -temporarily store output to be able to check for errors
# -activate advanced mode getopt quoting e.g. via “--options”
# -pass arguments only via   -- "$@"   to separate them correctly
PARSED=$(getopt --options $SHORT --longoptions $LONG --name "$0" -- "$@")
if [[ $? != 0 ]]; then
    # e.g. $? == 1
    #  then getopt has complained about wrong arguments to stdout
    exit 2
fi
# use eval with "$PARSED" to properly handle the quoting
eval set -- "$PARSED"

h=0; q=0; v=0; autoConfirm=0
# now enjoy the options in order and nicely split until we see --
while true; do
    case "$1" in
        -h|--help)
            h=1
            shift
    exit 2 # Use a dedicated exit code to signal this condition.
            ;;
        -c|--config)
            config=1
            shift
            ;;
        -v|--verbose)
            v=1
            shift
            ;;
        -y|--yes)
            autoConfirm=1
            shift
            ;;
        --)
            shift
            break
            ;;
        *)
            echo "Invalid option.  Use -h for help"
            exit 3
            ;;
    esac
done

assertConfirmation () {
    local promptMsg=$1 autoConfirm=$2
    if (( autoConfirm )); then
        return
    else
        clear
        read  -n 1 -p "$promptMsg (yes/No) "
        printf '\n' # Output a newline, because none was appended to the user's keypress.
        echo "========================================================================"
        if [[ $REPLY =~ ^([Yy])$ ]]; then
            return
        fi
    fi
    return 1
}
Maybe the problem is in the way I source the following files.

Code: Select all

source install/essential            "${autoConfirm:?}"
Last edited by LockBot on Wed Dec 28, 2022 7:16 am, edited 1 time in total.
Reason: Topic automatically closed 6 months after creation. New replies are no longer allowed.
User avatar
xenopeek
Level 25
Level 25
Posts: 29610
Joined: Wed Jul 06, 2011 3:58 am

Re: Parsing command line argument to skip user confirmations

Post by xenopeek »

How are you calling the assertConfirmation function? In your getopt code you set a global variable "autoConfirm" and then in the function assertConfirmation you occlude that by making a local variable with the same name.
Image
West_Training_8668
Level 2
Level 2
Posts: 71
Joined: Tue Mar 29, 2016 8:41 am

Re: Parsing command line argument to skip user confirmations

Post by West_Training_8668 »

I was calling it like

Code: Select all

if assertConfirmation "Install this?" "${autoConfirm:?}"; then
    install
fi
but know I've changed the function to

Code: Select all

assertConfirmation () {
    local promptMsg=$1
    if (( autoConfirm )); then
        return
    else
        clear
        read  -n 1 -p "$promptMsg (yes/No) "
        printf '\n' # Output a newline, because none was appended to the user's keypress.
        echo "========================================================================"
        if [[ $REPLY =~ ^([Yy])$ ]]; then
            return
        fi
    fi
    return 1
}
and it works properly now calling it like

Code: Select all

if assertConfirmation "Install this?"; then
    install
fi
I guess rather than be passing the arguments to the sourced files I should use the arguments parsed at the beginning. So I shouldn't be sourcing the declarations script twice? Then should I call it like this or can't I use the variable SOURCED if it's not initialized?

Code: Select all

(( SOURCED ))  ||  { source install/essential ;  SOURCED=1 ; } 
User avatar
xenopeek
Level 25
Level 25
Posts: 29610
Joined: Wed Jul 06, 2011 3:58 am

Re: Parsing command line argument to skip user confirmations

Post by xenopeek »

You don't need SOURCED. You can just test if the function assertConfirmation already exists. Something like:
declare -f assertConfirmation &>/dev/null || source install/essential

BTW that source command will only work if your current directory is the parent directory of install. Use full paths!
Image
Locked

Return to “Scripts & Bash”