logo Debian Debian Debian-France Debian-Facile Debian-fr.org Forum-Debian.fr Debian ? Communautés logo inclusivité

Debian-facile

Bienvenue sur Debian-Facile, site d'aide pour les nouveaux utilisateurs de Debian.

Vous n'êtes pas identifié(e).


L'icône rouge permet de télécharger chaque page du wiki visitée au format PDF et la grise au format ODT → ODT PDF Export

Ceci est une ancienne révision du document !


Table des matières

Fonctions bash : demander choix parmi liste

Introduction

Collections de fonctions bash pour demande à l'utilisateur de faire un choix parmis une liste et rendre vos scripts plus interactif!

Liste de choix formaté en colonnes avec choix par défaut (nombre de colonne et choix par défaut optionnel)

questionWithDefault "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" -d 8 -c 6
 arg1     arg2     arg3     arg4     arg5     arg6     
 arg7     arg8     [arg9]   arg10    arg11    arg12    
 arg13    arg14                                        
Votre choix? [arg9] : 
arg9

Liste de choix énumérée et choix par défaut (optionnel)

numberedMenu "Votre choix?" "arg1 arg2 arg3 arg4 arg5" 2
     1) arg1
     2) arg2
     3) arg3
     4) arg4
     5) arg5

Votre choix? [2] : 
arg2

Question oui/non et choix par défaut

askYesNo "Voulez vous continuer ?" true
Voulez vous continuer ? [O/n] o
true

hs : tri des arguments en fonction de leur type supposé (positional(arg), named (-n arg), option (-o)) et les stocke dans 3 variables différentes.

A defaut, un groupe `-n arg` est considéré comme named et non comme un option + positional

Par exemple:

  1. `–named arguement_1 argument_2` ⇒ `–named arguement_1` est supposé comme groupe named, `argument_2` est supposé positional
  2. `–option –named argument` ⇒ `–option` est considéré comme option, `–named argument`, comme un groupe named

tri sommaire des arguments (! peu robuste!)

split_args -n named_1 pos_1 -p_1 --named_long named pos_2
positional arguemnts :  pos_2
named arguements :  -n named_1 --named_long named
parameter arguments:  -p_1

Fonctions

askyesno.sh
#!/bin/bash
 
# Yes/No question with default
askYesNo () {
        QUESTION=$1
        DEFAULT=$2
        if [ "$DEFAULT" = true ]; then
                OPTIONS="[O/n]"
                DEFAULT="o"
            else
                OPTIONS="[o/N]"
                DEFAULT="n"
        fi
        read -p "$QUESTION $OPTIONS " -n 1 -s  -r INPUT
        INPUT=${INPUT:-${DEFAULT}}
        echo ${INPUT}
        if [[ "$INPUT" =~ ^[yYoO]$ ]]; then
            ANSWER=true
        else
            ANSWER=false
        fi
}
split_arguments.sh
#!/bin/bash
 
split_args () {
    POSITIONAL_ARGS=""
    NAMED_ARGS=""
    PARAM_ARGS=""
    while [ $# -gt 0 ] ; do
 
        if [[ "$1" =~ ^- ]]; then
            if ! [[ "$2" =~ ^- ]] && [ -n "$2" ] ; then
                NAMED_ARGS="$NAMED_ARGS $1 $2"
                shift
            else
                PARAM_ARGS="$PARAM_ARGS $1"
            fi
        else
            POSITIONAL_ARGS="$POSITIONAL_ARGS $1"
        fi
        shift
    done
}
question_with_default_complete.sh
#!/bin/bash
 
questionWithDefault () {
 
    # Positional argument should strictly come before named arguments
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
    read -ra OPTIONS_SHOW <<< "$2" # Same list but highlight [default value]
 
    POS_DEFAULT=0 # position of default argument
    NB_COLUMNS=4 # nummber of element by line to display
 
    while [[ $# -gt 0 ]] ; do
        key="$1"
        case $key in
            -d|--default)
            POS_DEFAULT="$2"
            shift # past argument
            ;;
            -c|--columns)
            NB_COLUMNS="$2"
            shift
            ;;
        esac
        shift # past value
    done
 
    # Get new default option and format display
    OPTIONS_SHOW[$POS_DEFAULT]="[${OPTIONS_SHOW[$POS_DEFAULT]}]"
    DEFAULT="${OPTIONS[$POS_DEFAULT]}"
 
    # Get columns character length
    max_length=0
    for opt in ${OPTIONS[@]}; do
        opt_length=$(echo $opt | wc -c)
        if [ $opt_length -ge $max_length ]; then
            max_length=$opt_length
        fi
    done
    max_length=$(($max_length+1))
 
    # Create pattern for fstring
    FORMAT_STRING=""
    for i in $(seq $NB_COLUMNS); do 
        FORMAT_STRING="$FORMAT_STRING %-${max_length}s "
    done
    FORMAT_STRING="$FORMAT_STRING \n"
 
    # Show
    printf "$FORMAT_STRING" "${OPTIONS_SHOW[@]}"
 
    # Ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "${OPTIONS[@]}" =~ "$INPUT" ]]; then
        ANSWER=$INPUT
    else
        ANSWER=$DEFAULT
    fi
}
question_with_default_simple.sh
#!/bin/bash
 
questionWithDefaultSimple () {
 
    # Positional argument should strictly come before named arguments
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
 
    if [ -n "$3" ]; then
        DEFAULT="$3"
    else
        DEFAULT="${OPTIONS[0]}"
    fi
 
    # Create pattern for fstring
    COL_SIZE=15
    FORMAT_STRING="%-${COL_SIZE}s %-${COL_SIZE}s %-${COL_SIZE}s %-${COL_SIZE}s\n"
 
    # Show
    printf "$FORMAT_STRING" "${OPTIONS[@]}"
 
    # Ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "${OPTIONS[@]}" =~ "$INPUT" ]]; then
        ANSWER=$INPUT
    else
        ANSWER=$DEFAULT
    fi
}
numbered_menu.sh
#!/bin/bash
 
numberedMenu () {
 
    # $1 = question to ask
    # $2 = elements separted by space
    # S3 (optionnal) = index of defaut element
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
 
    if [ -n "$3" ]; then
        DEFAULT=$3
    else
        DEFAULT=1
    fi
 
    # Show 
    printf "\n"
    for i in $(seq ${#OPTIONS[@]}); do
        printf '    %3s %s\n' "$i)" "${OPTIONS[$(($i-1))]}"
    done
    printf '\n'
 
    # ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "$(seq ${#OPTIONS[@]})" =~ "$INPUT" ]]; then
        ANSWER="${OPTIONS[$(($INPUT-1))]}"
    else
        ANSWER="${OPTIONS[$(($DEFAULT-1))]}"
    fi
}

Exemples

Ce fichier réunit toutes les fonctions définies plus haut et lance une série d'exemples

toutes_les_fonctions_et_exemple.sh
#!/bin/bash
 
# Yes/No question with default
askYesNo () {
        QUESTION=$1
        DEFAULT=$2
        if [ "$DEFAULT" = true ]; then
                OPTIONS="[O/n]"
                DEFAULT="o"
            else
                OPTIONS="[o/N]"
                DEFAULT="n"
        fi
        read -p "$QUESTION $OPTIONS " -n 1 -s  -r INPUT
        INPUT=${INPUT:-${DEFAULT}}
        echo ${INPUT}
        if [[ "$INPUT" =~ ^[yYoO]$ ]]; then
            ANSWER=true
        else
            ANSWER=false
        fi
}
 
split_args () {
    POSITIONAL_ARGS=""
    NAMED_ARGS=""
    PARAM_ARGS=""
    while [ $# -gt 0 ] ; do
 
        if [[ "$1" =~ ^- ]]; then
            if ! [[ "$2" =~ ^- ]] && [ -n "$2" ] ; then
                NAMED_ARGS="$NAMED_ARGS $1 $2"
                shift
            else
                PARAM_ARGS="$PARAM_ARGS $1"
            fi
        else
            POSITIONAL_ARGS="$POSITIONAL_ARGS $1"
        fi
        shift
    done
}
 
 
questionWithDefault () {
 
    # Positional argument should strictly come before named arguments
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
    read -ra OPTIONS_SHOW <<< "$2" # Same list but highlight [default value]
 
    POS_DEFAULT=0 # position of default argument
    NB_COLUMNS=4 # nummber of element by line to display
 
    while [[ $# -gt 0 ]] ; do
        key="$1"
        case $key in
            -d|--default)
            POS_DEFAULT="$2"
            shift # past argument
            ;;
            -c|--columns)
            NB_COLUMNS="$2"
            shift
            ;;
        esac
        shift # past value
    done
 
    # Get new default option and format display
    OPTIONS_SHOW[$POS_DEFAULT]="[${OPTIONS_SHOW[$POS_DEFAULT]}]"
    DEFAULT="${OPTIONS[$POS_DEFAULT]}"
 
    # Get columns character length
    max_length=0
    for opt in ${OPTIONS[@]}; do
        opt_length=$(echo $opt | wc -c)
        if [ $opt_length -ge $max_length ]; then
            max_length=$opt_length
        fi
    done
    max_length=$(($max_length+1))
 
    # Create pattern for fstring
    FORMAT_STRING=""
    for i in $(seq $NB_COLUMNS); do 
        FORMAT_STRING="$FORMAT_STRING %-${max_length}s "
    done
    FORMAT_STRING="$FORMAT_STRING \n"
 
    # Show
    printf "$FORMAT_STRING" "${OPTIONS_SHOW[@]}"
 
    # Ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "${OPTIONS[@]}" =~ "$INPUT" ]]; then
        ANSWER=$INPUT
    else
        ANSWER=$DEFAULT
    fi
}
 
 
questionWithDefaultSimple () {
 
    # Positional argument should strictly come before named arguments
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
 
    if [ -n "$3" ]; then
        DEFAULT="$3"
    else
        DEFAULT="${OPTIONS[0]}"
    fi
 
    # Create pattern for fstring
    COL_SIZE=15
    FORMAT_STRING="%-${COL_SIZE}s %-${COL_SIZE}s %-${COL_SIZE}s %-${COL_SIZE}s\n"
 
    # Show
    printf "$FORMAT_STRING" "${OPTIONS[@]}"
 
    # Ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "${OPTIONS[@]}" =~ "$INPUT" ]]; then
        ANSWER=$INPUT
    else
        ANSWER=$DEFAULT
    fi
}
 
numberedMenu () {
 
    # $1 = question to ask
    # $2 = elements separted by space
    # S3 (optionnal) = index of defaut element
 
    QUESTION=$1
    read -ra OPTIONS  <<< "$2" # Keep options list
 
    if [ -n "$3" ]; then
        DEFAULT=$3
    else
        DEFAULT=1
    fi
 
    # Show 
    printf "\n"
    for i in $(seq ${#OPTIONS[@]}); do
        printf '    %3s %s\n' "$i)" "${OPTIONS[$(($i-1))]}"
    done
    printf '\n'
 
    # ask user
    printf "\x1b[1;32m$QUESTION\x1b[0m"
    read -p " [$DEFAULT] : " -r INPUT
    INPUT=${INPUT:-${DEFAULT}}
 
    # Collect result
    if [[ "$(seq ${#OPTIONS[@]})" =~ "$INPUT" ]]; then
        ANSWER="${OPTIONS[$(($INPUT-1))]}"
    else
        ANSWER="${OPTIONS[$(($DEFAULT-1))]}"
    fi
}
 
 
echo "execution de:"
echo 'askYesNo "Voulez vous continuer ?" true'
echo ''
askYesNo "Voulez vous continuer ?" true
echo $ANSWER
echo ""
echo '-------------'
echo ""
askYesNo "Voulez vous continuer ?" false
echo 'askYesNo "Voulez vous continuer ?" false'
echo $ANSWER
 
echo ""
echo '-------------'
echo ""
echo "execution de:"
echo 'split_args -n named_1 pos_1 -p_1 --named_long named pos_2'
echo ""
split_args -n named_1 pos_1 -p_1 --named_long named pos_2
echo "positional arguemnts : $POSITIONAL_ARGS"
echo "named arguements : $NAMED_ARGS"
echo "parameter arguments: $PARAM_ARGS"
 
echo ""
echo '-------------'
echo ""
echo "execution de:"
echo 'questionWithDefault "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14'
echo ""
questionWithDefault "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10  arg11 arg12 arg13 arg14"
echo $ANSWER
 
echo ""
echo '-------------'
echo ""
echo "execution de:"
echo 'questionWithDefault "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" -d 8 -c 6'
echo ""
questionWithDefault "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" -d 8 -c 6
echo $ANSWER
 
echo ""
echo '-------------'
echo ""
echo "execution de:"
echo 'questionWithDefaultSimple "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14' arg6
echo ""
questionWithDefaultSimple "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" arg6
echo $ANSWER
 
echo ""
echo '-------------'
echo ""
echo "execution de:"
echo 'numberedMenu "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" 2'
echo ""
numberedMenu "Votre choix?" "arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10 arg11 arg12 arg13 arg14" 2
echo $ANSWER
 
echo ""
echo '-------------'
echo ""
utilisateurs/david5647/tutos/bash-fonctions-liste-de-choix-pour-script-interactifs.1616533311.txt.gz · Dernière modification: 23/03/2021 22:01 par David5647

Pied de page des forums

Propulsé par FluxBB