oct 21 2009

Variables variables en Bash

Tag: Bash, Debian GNU/Linux, Développement, Langages, SystèmeSylvain @ 21:29

Il peut parfois être pratique d’avoir des noms de variables qui soient variables. C’est-à-dire un nom de variable qui est affecté et utilisé dynamiquement. En bash, il suffit de d’utiliser la construction « ${!variable} » pour déréférencer la variable ayant son nom contenu dans $variable. Voici un exemple d’utilisation concret :

#!/bin/bash

BACKUP_DAY=10
BACKUP_WEEK=4

LIST=( DAY WEEK )
for i in ${LIST[@]}; do
    i="BACKUP_$i"
    echo "$i : ${!i}"
done

Affichera :

BACKUP_DAY : 10
BACKUP_WEEK : 4

À lire :


oct 21 2009

Équivalents de dirname & basename en Bash

Tag: Bash, Debian GNU/Linux, Développement, Langages, SystèmeSylvain @ 18:16

Les programmes dirname et basename sont très pratiques lors de l’écriture de scripts bash mais impliquent une exécution externe ce que les puristes aiment bien éviter. Voici, pour les intéressés, leurs équivalents en bash accompagnés d’une batterie de tests pour valider leur fonctionnement par rapport aux programmes de base :

#!/bin/bash

function basename(){
    echo ${1##*/}
}

function dirname(){
    local file=$1
    case $file in
        /*) ;;
        ./*) ;;
        *) file=./$file ;;
    esac
    file=${file%/*}
    echo ${file:-/}
}

PROGS=( dirname basename )
LIST_FILES=( /test.txt /tmp/test.txt /tmp/plop/test.txt ./test.txt ./tmp/test.txt ./tmp/plop/test.txt test.txt )

for prog in ${PROGS[@]}; do
    echo "--> $prog <--"
    for file in ${LIST_FILES[@]}; do
        SYSTEM=$(bash -c "$prog $file")
        MINE=$($prog $file)
        [[ $SYSTEM != $MINE ]] && echo -e "$file\nSystème : $SYSTEM\nLe mien : $MINE"
    done
done

Une petite comparaison rapide entre les deux solutions montre des performances supérieures de 75% en faveur de la solution bash. En pratique, la différence sera bien évidemment insignifiante sauf si vous vous amusez à itérer un grand nombre de fois sur ces fonctions. ;-)

Note : les options –help, –version ainsi que le paramètre permettant d’indiquer un suffixe pour basename ne sont pas pris en compte.

À lire :