Bonjour,

J'ai quelques questions sur les "variable indirection" (variables indirectes en français ??).
Ma version de bash :
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)

J'ai un script qui sert à désarchiver plusieurs fichiers qui se trouvent dans différentes archives (et à faire d'autres choses aussi).
Les fichiers à désarchiver sont à passer en argument du script.

Dans fichiers_ABCD.tar.gz, il y aura des fichiers se nommant par exemple :
fichier_ABCD_000001.xml
fichier_ABCD_000002.xml
etc...

Dans fichiers_1234.tar.gz, il y aura des fichiers se nommant par exemple :
fichier_1234_000001.xml
fichier_1234_000002.xml
etc...


Voici le script (enfin une partie) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#!/bin/bash
 
CR=0
for fic
do
    # Test important suite à l'utilisation d'eval plus bas
    ( LC_COLLATE=C; [[ $fic != fichier_[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]_[0-9][0-9][0-9][0-9][0-9][0-9].xml ]] ) && {
        echo "ERREUR - Nom de fichier incorrect ($fic)"
        CR=1
    }
    (( CR )) && continue
 
    code=${fic:8:4}
    [[ ${liste_codes[@]} != *$code* ]] && liste_codes+=("$code") # Tableau contenant la liste des codes
 
    # Ajout d'un élément dans le tableau fics_ABCD si par exemple $code == ABCD
    # Il est important d'avoir bien verifié la valeur de $code
    eval fics_$code'+=("$fic")'
done
(( CR )) && exit 1
 
rep_extract_fics=/destination/des/fichiers
 
for code in "${liste_codes[@]}"
do
    echo; echo "Désarchivage des fichiers pour $code..."
 
    nom_liste=fics_$code[@] # Ex : si $code == ABCD, alors $nom_liste vaudra fics_ABCD[@]
 
    archive=/emplacement/des/archives/${code}/fichiers_${code}.tar.gz # Emplacement de l'archive
 
    echo ">>> Extraction des fichiers depuis $archive..."
    tar xvf "$archive" -C "$rep_extract_fics" "${!nom_liste}" # "${!nom_liste}" équivaut à "${fics_ABCD[@]}" si $code == ABCD
    (($?)) && { echo "ERREUR - Echec de l'extraction des fichier_${code}_*.xml"; exit 1;}
    echo "Extraction OK"
 
    echo ">>> Mise à jour des droits des fichiers désarchivés pour $code..."
    eval 'chmod 660 "${'"$nom_liste"'/#/$rep_extract_fics/}"' # Utilisation de eval car "${!nom_liste/#/$rep_extract_fics/}" rajoute $rep_extract_fics/ seulement devant le premier element du tableau
    (($?)) && { echo "ERREUR - Echec de la mise à jour des droits des fichiers désarchivés"; exit 1;}
    echo "Mise à jour des droits OK"
done
eval fics_$code'+=("$fic")' : peut-on remplir le tableau, dont le nom n'est donc pas défini directement, sans utiliser eval ?

tar xvf "$archive" -C "$rep_extract_fics" "${!nom_liste}" : fonctionne comme je m'y attendais ; si $nom_liste == fics_ABCD[@], "${!nom_liste}" me donne bien tous les éléments, comme si j'avais utilisé directement "${fics_ABCD[@]}"

Par contre, ça "bug" pour ce genre de chose :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
$ fics_ABCD=(aa bb cc dd)
$ nom_liste=fics_ABCD[@]
$ echo "${!liste#?}"
a bb cc dd
Je m'attendais plutôt au résultat a b c d, comme si j'avais tapé echo "${fics_ABCD[@]#?}"

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
$ echo "${!liste/#/X}"
Xaa bb cc dd
Je m'attendais plutôt au résultat Xaa Xbb Xcc Xdd, comme si j'avais tapé echo "${fics_ABCD[@]/#/X}"

C'est un bug ou c'est logique ce fonctionnement ?