Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
informatique:outils:bash [2024/07/24 12:04] – [Array] bn8informatique:outils:bash [2025/08/21 12:47] (Version actuelle) – [Barre de progression] bn8
Ligne 7: Ligne 7:
     * Pour chercher explicitement **à la fin** du contenu de la variable : ''${parameter/%search_pattern/replacement}''     * Pour chercher explicitement **à la fin** du contenu de la variable : ''${parameter/%search_pattern/replacement}''
     * Pour remplacer **toutes les occurences** : ''%%${parameter//search_pattern/replacement}%%''     * Pour remplacer **toutes les occurences** : ''%%${parameter//search_pattern/replacement}%%''
-  * Mise en **majuscule** : ''${variable^}'' => mise en majuscule du première caractère du contenu de la variable ''variable''+  * Mise en **majuscule** (upper case) : ''${variable^}'' => mise en majuscule du première caractère du contenu de la variable ''variable''
     * Pour mettre **tout en majuscule** : ''${variable^^}''     * Pour mettre **tout en majuscule** : ''${variable^^}''
-  * Mise en **minuscule** : ''${variable,}'' => mise en minuscule du première caractère du contenu de la variable ''variable''+  * Mise en **minuscule** (lower case) : ''${variable,}'' => mise en minuscule du première caractère du contenu de la variable ''variable''
     * Pour mettre **tout en minuscule** : ''${variable,,}''     * Pour mettre **tout en minuscule** : ''${variable,,}''
  
Ligne 25: Ligne 25:
     * avec un retour à la ligne : ''%%mapfile -t myarray <<< "$ALL"%%''     * avec un retour à la ligne : ''%%mapfile -t myarray <<< "$ALL"%%''
     * avec un espace (ou autre caractère unique et "simple) : ''%%IFS=" " read -ra myarray <<< "$ALL"%%''     * avec un espace (ou autre caractère unique et "simple) : ''%%IFS=" " read -ra myarray <<< "$ALL"%%''
 +    * ajouter des valeurs à un tableau existant : ''%%mapfile -t -O "${#myarray[@)}" myarray <<< "$ALL"%%''
 +    * ajouter depuis un fichier : ''%%mapfile -t myarray < /path/to/file%%''
 +    * ajouter depuis la sortie d'une commande : ''%%mapfile -t myarray < <( grep -vE '^#' /path/to/file | grep -vE '^\s*$' )%%''
     * Note : voir la fonction ''explode'' pour une version générique     * Note : voir la fonction ''explode'' pour une version générique
  
 ==== Fonctions utiles ==== ==== Fonctions utiles ====
- 
  
 === in_array === === in_array ===
Ligne 99: Ligne 101:
 function array_intersect() { function array_intersect() {
     local result_var=$1     local result_var=$1
-    declare -"$result_var=()"+    declare -ga "$result_var=()"
     shift     shift
     local array1=()     local array1=()
Ligne 118: Ligne 120:
         for j in "${array2[@]}"; do         for j in "${array2[@]}"; do
               if [[ $i == $j ]]; then               if [[ $i == $j ]]; then
-                    declare -"$result_var+=( \"$i\" )"+                    declare -ga "$result_var+=( \"$i\" )"
                     break                     break
               fi               fi
Ligne 130: Ligne 132:
 a=(a b c d e) a=(a b c d e)
 b=(c d) b=(c d)
-array_filter c ${a[@]} -- ${b[@]} +array_intersect "${a[@]}-- "${b[@]}" 
-echo ${c[@]}+echo "${c[@]}"
 # Result: # Result:
 c d c d
Ligne 183: Ligne 185:
 # Output: # Output:
 # declare -a myarray=([0]="1" [1]="2" [2]="3") # declare -a myarray=([0]="1" [1]="2" [2]="3")
 +</code>
 +
 +=== check_regex ===
 +
 +<code bash>
 +function check_regex() {
 +  [[ $(grep -Ec "$2" <<< "$1") -eq 1 ]] && return 0
 +  return 1
 +
 +</code>
 +
 +=== check_int ===
 +
 +**Pré-requis :** [[#check_regex]]
 +
 +<code bash>
 +function check_int() {
 +    check_regex "$1" '^-?[0-9]+$' || return 1
 +    [[ -n "$2" ]] && [[ $1 -lt $2 ]] && return 1
 +    [[ -n "$3" ]] && [[ $1 -gt $3 ]] && return 1
 +    return 0
 +}
 </code> </code>
  
Ligne 196: Ligne 220:
     [[ $d -gt 0 ]] && printf '%d days and ' $d     [[ $d -gt 0 ]] && printf '%d days and ' $d
     printf '%02d:%02d:%02d' $h $m $s     printf '%02d:%02d:%02d' $h $m $s
 +}
 +</code>
 +
 +=== format_size ===
 +
 +**Pré-requis :** [[#check_int]]
 +
 +<code bash>
 +declare -ra _FORMAT_SIZE_UNITS=( tb gb mb kb b )
 +declare -rA _FORMAT_SIZE_UNITS_FACTOR=(
 +    ["tb"]=1099511627776 ["gb"]=1073741824 ["mb"]=1048576 ["kb"]=1024 ["b"]=1 )
 +function format_size() {
 +    local size="" unit=kb allow_zero=0 negative=0 opt
 +    for opt in "$@"; do
 +        opt="${opt,,}"
 +        if [[ ${#opt} -gt 2 ]] && \
 +            [[ "${_FORMAT_SIZE_UNITS_FACTOR[${opt:2}]:-null}" != "null" ]]; then
 +            unit=${opt:2}
 +        elif [[ ${#opt} -gt 1 ]] && \
 +            [[ "${_FORMAT_SIZE_UNITS_FACTOR[${opt:1}]:-null}" != "null" ]]; then
 +            unit=${opt:1}
 +        elif [[ "$opt" == "--allow-zero" ]] || [[ "$opt" == "-z" ]]; then
 +            allow_zero=1
 +        elif [[ -z "$size" ]]; then
 +            size=$opt
 +            [[ "$size" == "null" ]] && echo -n null && return
 +            check_int "$size" || { echo -n "format_size: invalid value '$size'"; return 1; }
 +        else
 +            echo -n "format_size: invalid parameter '$opt'"
 +            return 1
 +        fi
 +    done
 +    if [[ $size -eq 0 ]]; then
 +        [[ $allow_zero -eq 0 ]] && return
 +        echo -n "0${_FORMAT_SIZE_UNITS[${#_FORMAT_SIZE_UNITS[@]} - 1]}"
 +    elif [[ $size -lt 0 ]]; then
 +        (( size=size*-1 ))
 +        negative=1
 +    fi
 +
 +    (( size=size*${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ))
 +    for unit in "${_FORMAT_SIZE_UNITS[@]}"; do
 +        [[ $size -lt ${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ]] && continue
 +        if [[ $size -eq ${_FORMAT_SIZE_UNITS_FACTOR[$unit]} ]]; then
 +            size=1
 +        else
 +            size=$( echo "scale=1; $size/${_FORMAT_SIZE_UNITS_FACTOR[$unit]}"|bc|sed 's/\.0$//' )
 +        fi
 +        [[ $negative -eq 1 ]] && size=$( echo "$size*-1"|bc )
 +        echo -n "${size}${unit^^}"
 +        return
 +    done
 } }
 </code> </code>
Ligne 224: Ligne 300:
 <code bash>declare -p variableName</code> <code bash>declare -p variableName</code>
  
 +=== sprint ===
 +
 +**Pré-requis :** [[#implode]]
 +
 +<code bash>
 +#
 +# Styled text printing helper
 +#
 +declare -rA COLORS=(
 +    [black]=30 [red]=31 [green]=32 [brown]=33 [blue]=34 [purple]=35 [cyan]=36 [light_grey]=37
 +    [default]=39 [dark_grey]=90 [light_red]=91 [light_green]=92 [yellow]=93 [light_blue]=94
 +    [light_purple]=95 [light_cyan]=96 [white]=97
 +)
 +declare -rA BACKGROUND_COLORS=(
 +    [black]=40 [red]=41 [green]=42 [brown]=43 [blue]=44 [purple]=45 [cyan]=46 [ligth_grey]=47
 +    [default]=49 [dark_grey]=100 [light_red]=101 [light_green]=102 [yellow]=103 [light_blue]=104
 +    [light_purple]=105 [light_cyan]=106 [white]=107
 +)
 +declare -rA TEXT_STYLES=(
 +    [normal]=0 [bold]=1 [dim]=2 [italic]=3 [underline]=4 [blink]=5 [inverted_colors]=7 [hidden]=8
 +    [strikethrough]=9
 +)
 +declare -rA RESET_STYLES=(
 +    [all]=0 [bold]=21 [dim]=22 [underline]=24 [blink]=25 [inverted_colors]=27 [hidden]=28
 +)
 +
 +function sprint() {
 +    local idx=1 opt value no_newline=0 output=""
 +    local -a styles=() text=()
 +
 +    __sprint() {
 +        [[ -n "$output" ]] && output+=" "
 +        [[ "${#styles}" -gt 0 ]] && \
 +            output+="\e[$(implode ';' "${styles[@]}")m" && \
 +            styles=()
 +        output+="${text[*]}"
 +        text=()
 +    }
 +    while [[ $idx -le $# ]]; do
 +        opt=${!idx}
 +        case $opt in
 +            -c|--color)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${COLORS[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid color '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${COLORS[$value]}" )
 +                ;;
 +            -b|--bg)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${BACKGROUND_COLORS[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid background color '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${BACKGROUND_COLORS[$value]}" )
 +                ;;
 +            -s|--style)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${TEXT_STYLES[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid text style '${!idx}'"
 +                    return 1
 +                fi
 +                styles+=( "${TEXT_STYLES[$value]}" )
 +                ;;
 +            -r|--reset)
 +                [[ "${#text}" -gt 0 ]] && __sprint
 +                ((idx++))
 +                value="${!idx,,}"
 +                if [[ "${RESET_STYLES[$value]:-null}" == "null" ]]; then
 +                    echo -n "sprint: invalid reset option '${!idx}'"
 +                    return 1
 +                fi
 +                output+="\e[${RESET_STYLES[$value]}m"
 +                ;;
 +            -n)
 +                no_newline=1
 +                ;;
 +            -h|--help)
 +                echo "usage: sprint [-n] [-c color] [-b color] [-s style] [words] [-r what] [...]"
 +                echo "  -c / --color [color]   Colored text. Available colors:"
 +                implode ", " "${!COLORS[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -b / --bg [color]      Text background color. Available colors:"
 +                implode ", " "${!BACKGROUND_COLORS[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -s / --style [style]   Text style. Available styles:"
 +                implode ", " "${!TEXT_STYLES[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -r / --reset [what]    Reset some previously specified styles. Available reset clauses:"
 +                implode ", " "${!RESET_STYLES[@]}" | \
 +                    fold -w 53 -s | sed "s/^/                         /g"
 +                echo
 +                echo "  -n                     Do not add new line"
 +                echo "  [words]                Words that compose the text"
 +                ;;
 +            *)
 +                text+=( "$opt" )
 +        esac
 +        ((idx++))
 +    done
 +    __sprint
 +    output+="\e[${RESET_STYLES[all]}m"
 +    if [[ "$no_newline" -eq 1 ]]; then
 +        echo -en "$output"
 +    else
 +        echo -e "$output"
 +    fi
 +}
 +</code>
 +
 +**Exemple :**
 +<code bash>
 +sprint -c red '[' -s blink ERROR -r blink ']' -r all Really bad error occurred -s dim -s italic '(see log for details)'
 +</code>
 +
 +Résultat : 
 +
 +{{:informatique:outils:sprint.svg?500|}}
 ===== Gestion des paramètres ===== ===== Gestion des paramètres =====
  
Ligne 287: Ligne 491:
 <code bash> <code bash>
 declare -A PBARS declare -A PBARS
-declare PBID 
  
 # Create a progress bar # Create a progress bar
Ligne 294: Ligne 497:
 # - total count (default: 100) # - total count (default: 100)
 # - bar size (default: use all the width of the terminal with a minimum of 5 caracters) # - bar size (default: use all the width of the terminal with a minimum of 5 caracters)
-# - the name of the variable use to store the progress bar ID (default: PBID)+# - the name of the variable use to store the progress bar ID (default: PBAR)
 function pbar_create() { function pbar_create() {
-    # Define the name of the variable that will store the progress bar ID +    local id=${4:-PBAR}
-    [ -n "$4" ] && PBAR_ID_VAR="$4" || PBAR_ID_VAR=PBID +
-    declare -n ID="$PBAR_ID_VAR" +
-    # Generate the progress bar ID +
-    ID=$( tr -dc A-Za-z0-9 </dev/urandom | head -c 3 )+
     # Initialize progress bar information     # Initialize progress bar information
-    PBARS["${ID}_START_TIME"]="$( date +%s )" +    PBARS["${id}_START_TIME"]="$( date +%s )" 
-    [ -n "$1" ] && PBARS["${ID}_TITLE"]="$1" || PBARS["${ID}_TITLE"]="Progress" +    [ -n "$1" ] && PBARS["${id}_TITLE"]="$1" || PBARS["${id}_TITLE"]="Progress" 
-    [ -n "$2" ] && PBARS["${ID}_TOTAL"]="$2" || PBARS["${ID}_TOTAL"]=100 +    [ -n "$2" ] && PBARS["${id}_TOTAL"]="$2" || PBARS["${id}_TOTAL"]=100 
-    [ -n "$3" ] && PBARS["${ID}_SIZE"]="$3" || PBARS["${ID}_SIZE"]=0 +    [ -n "$3" ] && PBARS["${id}_SIZE"]="$3" || PBARS["${id}_SIZE"]=0 
-    PBARS["${ID}_CURRENT"]=0 +    PBARS["${id}_CURRENT"]=0 
-    PBARS["${ID}_LAST_UPDATE"]=0+    PBARS["${id}_LAST_UPDATE"]=0 
 +    PBARS["${id}_END_TIME"]=0
     # Draw the progress bar for a first time     # Draw the progress bar for a first time
-    pbar_draw $ID+    pbar_draw "$id"
 } }
  
 # Finish a progress bar # Finish a progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the ID of the progress bar (default: PBAR)
 function pbar_finish() { function pbar_finish() {
-    -"$1" ] && ID=$1 || ID=$PBID +    local id=${1:-PBAR} 
-    unset 'PBARS[${ID}_START_TIME]' + 
-    unset 'PBARS[${ID}_TITLE]' +    # Force a last update of the progess bar 
-    unset 'PBARS[${ID}_TOTAL]' +    PBARS["${id}_END_TIME"]="$( date +%s )" 
-    unset 'PBARS[${ID}_CURRENT]' +    pbar_draw "$@" 
-    unset 'PBARS[${ID}_LAST_UPDATE]'+ 
 +    # Unset progress bar info 
 +    unset 'PBARS[${id}_START_TIME]' 
 +    unset 'PBARS[${id}_TITLE]' 
 +    unset 'PBARS[${id}_TOTAL]' 
 +    unset 'PBARS[${id}_CURRENT]' 
 +    unset 'PBARS[${id}_LAST_UPDATE]' 
 +    unset 'PBARS[${id}_END_TIME]'
     echo     echo
 } }
Ligne 327: Ligne 534:
 # Draw the progress bar # Draw the progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the ID of the progress bar (default: PBAR)
 # - extra message to display in the progress bar (before the ETA, optional) # - extra message to display in the progress bar (before the ETA, optional)
 +# - all extra arguments will be use to compute the extra message using printf
 function pbar_draw() { function pbar_draw() {
-    [ -n "$1" ] && ID=$1 || ID=$PBID+    local id=${1:-PBAR} 
 + 
 +    # Compute extra message 
 +    local extra=${2:-} 
 +    # shellcheck disable=SC2059 
 +    [[ -n "$extra]] && [[ $# -gt 2 ]] && extra=$( printf "$extra" "${@:3}" )
  
     # Only update progress bar one time by second     # Only update progress bar one time by second
-    NOW=$(date +%s) +    local now; now=$(date +%s) 
-    [ $NOW -eq ${PBARS[${ID}_LAST_UPDATE]} ] && return+    [[ "${PBARS[${id}_END_TIME]}" -eq 0 ]] && [[ $now -eq ${PBARS[${id}_LAST_UPDATE]} ]] && return
  
     # Compute progress percentage     # Compute progress percentage
-    let PERC=${PBARS[${ID}_CURRENT]}*100/${PBARS[${ID}_TOTAL]} +    local perc 
- +    (( perc=${PBARS[${id}_CURRENT]}*100/${PBARS[${id}_TOTAL]} ))
-    # Compute duration, total duration, ETA & speed +
-    let DURATION=NOW-${PBARS[${ID}_START_TIME]} +
-    if [ ${PBARS[${ID}_CURRENT]} -gt 0 ] +
-    then +
-        let TOTAL_DURATION=DURATION*${PBARS[${ID}_TOTAL]}/${PBARS[${ID}_CURRENT]} +
-        SPEED=$( echo "scale=1; ${PBARS[${ID}_CURRENT]}/$DURATION"|bc ) +
-    else +
-        TOTAL_DURATION=0 +
-        SPEED="?" +
-    fi +
-    let ETA=TOTAL_DURATION-DURATION+
  
     # Compute line without the progress bar     # Compute line without the progress bar
-    LINE=( +    local line line_items line_pad size line_length term_height term_width bar_done bar_pad 
-        "${PBARS[${ID}_TITLE]}"+    line_items=( 
 +        "${PBARS[${id}_TITLE]}"
         "[]"         "[]"
-        "${PBARS[${ID}_CURRENT]}/${PBARS[${ID}_TOTAL]} (${PERC}%)" +        "${PBARS[${id}_CURRENT]}/${PBARS[${id}_TOTAL]} (${perc}%)"
-    ) +
-    [ -n "$2" ] && LINE+=( "- $2" ) +
-    LINE+=( +
-        "- ETA: $(format_duration $ETA)" +
-        "- $( printf "(%s / %s, %s/s)" "$(format_duration $DURATION)" "$(format_duration $TOTAL_DURATION)" $SPEED )"+
     )     )
 +    [ -n "$extra" ] && line_items+=( "- $extra" )
 +
 +    # Add ETA (or total duration if finish)
 +    if [[ "${PBARS[${id}_END_TIME]}" -eq 0 ]]; then
 +        # Compute duration, total duration, ETA & speed
 +        local duration total_duration speed eta
 +        (( duration=now-${PBARS[${id}_START_TIME]} ))
 +        if [[ "${PBARS[${id}_CURRENT]}" -gt 0 ]]; then
 +            (( total_duration=duration*${PBARS[${id}_TOTAL]}/${PBARS[${id}_CURRENT]} ))
 +            speed=$( bc <<< "scale=1; ${PBARS[${id}_CURRENT]}/$duration" )
 +        else
 +            total_duration=0
 +            speed="?"
 +        fi
 +        (( eta=total_duration-duration ))
 +
 +        line_items+=(
 +            "- ETA: $(format_duration $eta)"
 +            "- $( printf "(%s / %s, %s/s)" "$(format_duration $duration)" "$(format_duration $total_duration)" "$speed" )"
 +        )
 +    else
 +        local total_duration
 +        (( total_duration=${PBARS[${id}_END_TIME]}-${PBARS[${id}_START_TIME]} ))
 +        line_items+=( "- Total duration: $(format_duration $total_duration)" )
 +    fi
  
     # Compute progress bar length (if not configured)     # Compute progress bar length (if not configured)
-    read -r TERM_HEIGHT TERM_WIDTH < <(stty size) +    # shellcheck disable=SC2034 
-    SIZE=${PBARS[${ID}_SIZE]} +    read -r term_height term_width < <(stty size) 
-    if [ $SIZE -eq 0 ] +    size=${PBARS[${id}_SIZE]} 
-    then +    if [[ "$size" -eq 0 ]]; then 
-        LINE_LENGTH=$( echo "${LINE[*]}"|wc -c +        line_length=$( wc -c <<< "${line_items[*]}" ) 
-        SIZE=$[ $TERM_WIDTH $LINE_LENGTH ] +        (( size=term_width-line_length )) 
-        [ $SIZE -lt 5 ] && SIZE=5+        [[ $size -lt 5 ]] && size=5
     fi     fi
  
     # Set progress bar text     # Set progress bar text
-    let DONE=$PERC*$SIZE/100 +    (( bar_done=perc*size/100 )) 
-    let LEFT=$SIZE-$DONE +    (( bar_pad=size-bar_done )) 
-    LINE[1]="[$(printf "%${DONE}s"|tr ' ' '#')$(printf "%${LEFT}s"|tr ' ' '-')]"+    line_items[1]="[$(printf "%${bar_done}s"|tr ' ' '#')$(printf "%${bar_pad}s"|tr ' ' '-')]"
  
     # Add line padding (if need)     # Add line padding (if need)
-    let LINE_PAD=TERM_WIDTH-${#LINE+    (( line_pad=term_width-${#line_items)) 
-    [ $LINE_PAD -gt 0 ] && LINE+=( "$(printf "%${LINE_PAD}s")" )+    [[ $line_pad -gt 0 ]] && line_items+=( "$(printf "%${line_pad}s")" )
  
     # Compute & display line (strip the terminal width)     # Compute & display line (strip the terminal width)
-    LINE="${LINE[*]}" +    line="${line_items[*]}" 
-    echo -en "\r${LINE:0:$TERM_WIDTH}"+    echo -en "\r${line:0:$term_width}"
  
     # Update last progress bar update time     # Update last progress bar update time
-    PBARS[${ID}_LAST_UPDATE]=$NOW+    PBARS[${id}_LAST_UPDATE]=$now
 } }
  
 # Increment the progress bar # Increment the progress bar
 # Arguments: # Arguments:
-# - the ID of the progress bar (default: $PBID)+# - the step (default: 1) 
 +# - the ID of the progress bar (default: PBAR)
 # - extra message to display in the progress bar (before the ETA, optional) # - extra message to display in the progress bar (before the ETA, optional)
 # - all extra arguments will be use to compute the extra message using printf # - all extra arguments will be use to compute the extra message using printf
 function pbar_increment() { function pbar_increment() {
-    [ -n "$1" ] && ID=$1 || ID=$PBID +    local step=${1:-1} id=${2:-PBAR}
-    # Compute extra message +
-    if [ -n "$2"+
-    then +
-        EXTRA="$2+
-        shift 2 +
-        [ $# -gt 0 ] && EXTRA=$( printf "$EXTRA" "$@"+
-    else +
-        EXTRA="" +
-    fi+
     # Increment the progress bar state     # Increment the progress bar state
-    ((PBARS[${ID}_CURRENT]++))+    ((PBARS[${id}_CURRENT]+=step))
     # Draw the progress bar     # Draw the progress bar
-    pbar_draw $ID "$EXTRA"+    pbar_draw "${@:2}"
 } }
 </code> </code>
Ligne 416: Ligne 631:
 <code bash> <code bash>
 pbar_create "Test" 20 pbar_create "Test" 20
-for i in $( seq 1 20 ) +for i in $( seq 1 20 )do
-do+
     pbar_increment     pbar_increment
     sleep 0.1     sleep 0.1
 done done
 pbar_finish pbar_finish
 +</code>
 +
 +**Ajout d'info avant l'ETA :**
 +<code bash>
 +pbar_create "Test" 20
 +for i in $( seq 1 20 ); do
 +    pbar_increment "" "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))
 +    sleep 0.1
 +done
 +pbar_finish "" "" "%d iteration(s) - %d found(s)" $i $(( i/2 ))
 </code> </code>
  
 <note warning>La fonction [[#format_duration]] est nécessaire.</note> <note warning>La fonction [[#format_duration]] est nécessaire.</note>