Forum Programmation.shell Array not found

Posté par  (site web personnel) . Licence CC By‑SA.
Étiquettes : aucune
0
11
juin
2013

Bonjour,

Je suis confronté à un problème dont je ne trouve pas la solution. Dans un script je suis amené à utiliser des tableaux pour stocker des valeurs. Sur tout mes serveurs (redhat) ça marche sauf sur un qui n'est pas la même distri (openmediavault).

J'ai reproduis le problème avec une version simplifié du script

#!/bin/bash

bash --version

declare -a myarray[0]="hello"
declare -a myarray[1]="world"

prtinf "${myarray[*]}"
printf "\n"

Cette version me donne

#sh test.sh 
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
test.sh: 5: declare: not found
test.sh: 6: declare: not found
test.sh: 8: Bad substitution

Une autre version

#!/bin/bash

bash --version

myarray[0]="hello"
myarray[1]="world"

prtinf "${myarray[*]}"
printf "\n"

qui donne

#sh test.sh 
GNU bash, version 4.1.5(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
test.sh: 5: myarray[0]=hello: not found
test.sh: 6: myarray[1]=world: not found
test.sh: 8: Bad substitution

Mes autres serveurs sont en version

GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

  • # une piste

    Posté par  . Évalué à 3.

    ici ca marche si je fais un chmod 755 sur test.sh et que je le lance avec

    $ ./test.sh
    GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
    Copyright (C) 2011 Free Software Foundation, Inc.
    Licence GPLv3+ : GNU GPL version 3 ou ultérieure http://gnu.org/licenses/gpl.html

    Ceci est un logiciel libre ; vous être libre de le modifier et de le redistribuer.
    Aucune garantie n'est fournie, dans la mesure de ce que la loi autorise.
    hello world

    ca ne marche pas si je le lance avec

    $ sh test.sh
    GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
    Copyright (C) 2011 Free Software Foundation, Inc.
    Licence GPLv3+ : GNU GPL version 3 ou ultérieure http://gnu.org/licenses/gpl.html

    Ceci est un logiciel libre ; vous être libre de le modifier et de le redistribuer.
    Aucune garantie n'est fournie, dans la mesure de ce que la loi autorise.
    test.sh: 5: test.sh: myarray[0]=hello: not found
    test.sh: 6: test.sh: myarray[1]=world: not found
    test.sh: 8: test.sh: Bad substitution

    c'est donc bien ta maniere de lancer le fichier qui pose souci.

    en le lancant avec sh test.sh
    sur certains serveurs sh est peut-etre remplacé par bash
    ce qui ne serait pas le cas de la nouvelle machine ?

    • [^] # Re: une piste

      Posté par  (site web personnel) . Évalué à 1.

      Très subtile le ./ qui effectivement marche.

      Born to Kill EndUser !

      • [^] # Re: une piste

        Posté par  . Évalué à 2.

        le ./ permet de preciser que tu cherches test.sh dans le dossier courant.
        tu aurais tres bien pu faire /home/tonuser/tmp/test.sh (mais c'est plus long)

        et ca ne marche qu'à condition d'avoir fait un chmod u+x test.sh (ou chmod 544 test.sh) pour lui donner le droit d'etre executer.

        • [^] # Re: une piste

          Posté par  . Évalué à 2. Dernière modification le 11 juin 2013 à 12:12.

          Pour complèter la réponse de NeoX, quand tu lance 'sh script.sh', le programme 'sh' va lire le fichier 'script.sh' et l'interprêter. Et la première ligne qui commence par '#' est ignorée car ce caractère indique le début d'un commentaire dans la syntaxe shell (c.a.d. que tu mettrais à la place '#! /outsiplou' cela marcherait encore).
          Lorsque tu lance '/path/to/script.sh', le noyaux linux va lire ce shebang pour déterminer le nom de l'interprèteur et il va ensuite le lancer avec comme premier paramètre le nom du script.

          Bref, cela fonctionnerait aussi partout si tu lançais 'bash test.sh'.

          PS: la ligne 'bash --version' de ton script ne teste pas l'interprèteur qui est utilisée, mais lance une nouvelle commande bash. Sous linux, il est possible de tester /proc/$$/exe qui pointe vers le binaire du shell courant, i.e. utiliser '/proc/$$/exe --version' à la place te donnerait un résultat plus pertinant… (+1 à celui qui donne une manière portable de tester le shell courant :))

          PS2: les bonnes pratiques conseillent d'utiliser la version du shebang avec espace ('#! /path/') bien que les 2 fonctionnent…

          • [^] # Re: une piste

            Posté par  (site web personnel) . Évalué à 1. Dernière modification le 11 juin 2013 à 13:36.

            Merci pour ton complément d'information. Maintenant je comprends mieux la différente entre sh et ./

            bash --version était juste pour récupérer la version de bash utilisé dans le script et je partais du principe qu'il utilisait le shebang donc forcement bash.

            Born to Kill EndUser !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.