IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Un script qui copie en fonction du nom de l'OS/release


Sujet :

Shell et commandes GNU

  1. #1
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut Un script qui copie en fonction du nom de l'OS/release
    Bonsoir,

    J'ai un un fichier contenant une liste de hostnames de plusieurs OS et versions majeures : RedHat "4", RedHat "5", Solaris "8", Solaris "10", Fedora "12", Fedora "13" (je mets entre guillement la version majeure, car elle est très importante !). Pour chacun de ces hostnames, je veux déterminer le nom de l'OS et sa version majeure. Et en fonction de cela, copier des fichiers dans un répertoire sur la machine en question en écrasant ceux qui étaient là (je fais tout de même une sauvegarde de secours avant, on ne sait jamais !).

    Quelqu'un aurait-il la gentilesse de m'aider pour mettre en place ce script ?

    Il se peut que ce soit ridiculement facile à faire, mais je suis toujours un grand débutant, merci de ne pas m'en vouloir....

    En vous remerciant d'avance.

  2. #2
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Bonjour,

    Pour les distributions linux, lsb-release devrait t'aider.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Bonjour,

    Pour les distributions linux, lsb-release devrait t'aider.
    Sur RedHat, il ne connait pas!! Sinon, je vois à peu près comment trouver le nom de l'OS (ça marche pour tous les OS) :
    et sa release (par ex. pour redhat)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cat /etc/redhat-release | awk '{print $7}'
    Mon problème c'est, une fois tout ceci trouvé, comment le construire dans un script qui marche. Je me perds encore lorsqu'il y a des tests qui, suivant le résultat obtenu, on doit déclancher une action.
    Tiens, j'ai pensé à construire mon scipt autour d'un "case", mais comment mettre les chose en musique ? C'est encore un de mes problèmes et ça m'énerve...

  4. #4
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    oui, case est une bonne option.

    NB: awk '{print $7}' /etc/redhat-release ¡attention aux uuoc!
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    oui, case est une bonne option.

    NB: awk '{print $7}' /etc/redhat-release ¡attention aux uuoc!
    Merci pour la correction. Et voici un début avec "case", est-il possible d'avoir votre aide pour compléter ?


    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
    #!/bin/sh
     
    VAR=$(uname -s)
     
    case $VAR in
           Linux)
    	        REL=$(awk '{print $5}' /etc/redhat-release)
                    if [$REL="ES"] 
    		then    
    		        mv  /usr/local/bin/pinos /usr/local/bin/pinos-rh4.old
    			cp /home/oracle/pinos-rh4 /usr/local/bin/pinos
    		else
    			mv  /usr/local/bin/pinos /usr/local/bin/pinos-rh5.old
    			cp /home/oracle/pinos-rh5 /usr/local/bin/pinos 
    		fi
           ;;
     
          SunOS)
    	    REL=$(uname -r)
                if [$REL="5.8"] 
    	    then    
    		    mv  /usr/local/bin/pinos /usr/local/bin/pinos-sol8.old
    	            cp /export/home/oracle/pinos-sol8 /usr/local/bin/pinos
                else
    		    mv  /usr/local/bin/pinos /usr/local/bin/pinos-sol10.old
    		    cp /export/home/oracle/pinos-sol10 /usr/local/bin/pinos 
    	    fi
          ;;
     
          *) 
    	            echo "l'OS n'est ni un Linux ni un SunOS"
          ;;
     
    esac

  6. #6
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    en y regardant de plus près, je me dis qu'à un moment il va falloir que tu te connectes aux machines décrites dans maListeServeurs.txt...

    et je me rends compte que ta description n'est pas assez précise; il faudrait, avant d'attaquer le script, que tu aies dressé le plan détaillé des actions à effectuer (quoi faire, sur quelle machine, ...), et ensuite transcrire cela en langage de programmation.

    NB: indente scrupuleusement tes scripts (les commandes qui ouvrent, et qui ferment une commande composée doivent être sur la même colonne), dans le cas de conditions/case nombreu(x/se) la relecture, et la correction seront plus aisées.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  7. #7
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    en y regardant de plus près, je me dis qu'à un moment il va falloir que tu te connectes aux machines décrites dans maListeServeurs.txt...

    et je me rends compte que ta description n'est pas assez précise; il faudrait, avant d'attaquer le script, que tu aies dressé le plan détaillé des actions à effectuer (quoi faire, sur quelle machine, ...), et ensuite transcrire cela en langage de programmation.

    NB: indente scrupuleusement tes scripts (les commandes qui ouvrent, et qui ferment une commande composée doivent être sur la même colonne), dans le cas de conditions/case nombreu(x/se) la relecture, et la correction seront plus aisées.
    En fait, je n'ai pas à gérer le problème de connexions à chaque machine, cette histoire sera géré par quelqu'un d'autre. Je m'intéresse uniquement à ce qui se passe après la connexion sur l'une des machines du fichier maListeServeurs.txt. Et ce qui peut se résumer ainsi :

    Après connexion sur la machine ZZZ du fichier ListeServeurs.txt, commence par vérifier le type d'OS et sa version :

    si OS = RedHat et version = 4, alors :
    a) Renome le fichier redhat-4.bin qui se trouve dans le repertoire Y en redhat-4.bin.old
    b) remplace le fichier redhat-4.bin du repertoire Y par celui qui se trouve dans le répertoire X .
    c) écrit les erreurs éventuelles dans le fichier erreurs.txt

    si OS = RedHat et version = 5, alors :
    - repète les actions a), b) et c) pour le fichier redhat-5.bin.

    si OS = Solaris et version = 8, alors :
    - repète les actions a), b) et c) pour le fichier Solaris-8.bin.

    si OS = Solaris et version = 10, alors :
    - repète les actions a), b) et c) pour le fichier Solaris-10.bin.

    etc., ....

    FIN si

    FIN pour la machine ZZZ


    Je ne m'occupe donc pas de comment se connecter sur une machine de la liste (ce qui facilite grandement les choses !), j'ai juste à scripter les actions à effectuer une fois sur la machine en question.
    Certes, qu'on aurait aussi regrouper le 1° et 2° ensemble et ne tester que par rapport à la version (tout comme le 3° et 4° d'ailleurs) car l'OS est le même à chaque fois. Mais mon souci ici est de clarifier mon problème et non pas l'optimisation du code

    J'espère que les chose sont maintenant un peu plus claires pour vous.

    En appliquant ce qui précède, j'ai fait cette nuit le script suivant. Pouvez-vous SVP me dire si cela peut marcher, s'il n'y a pas d'erreurs de logique ou d'écritre?

    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
    #!/bin/sh
     
     
    case `uname -s` in
           Linux)
    	        REL=`awk '{print $5}' /etc/redhat-release`
                    if [ "$REL" = "ES" ] 
    		then    
    		        mv  /usr/local/bin/pinos /usr/local/bin/pinos-rh4.old
    			cp /home/oracle/pinos-rh4 /usr/local/bin/pinos
    		else
    			mv  /usr/local/bin/pinos /usr/local/bin/pinos-rh5.old
    			cp /home/oracle/pinos-rh5 /usr/local/bin/pinos 
    		fi
           ;;
     
          SunOS)
    	    REL=`uname -r`
                if [ "$REL" = "5.8" ] 
    	    then    
    		    mv  /usr/local/bin/pinos /usr/local/bin/pinos-sol8.old
    	            cp /export/home/oracle/pinos-sol8 /usr/local/bin/pinos
                else
    		    mv  /usr/local/bin/pinos /usr/local/bin/pinos-sol10.old
    		    cp /export/home/oracle/pinos-sol10 /usr/local/bin/pinos 
    	    fi
          ;;
     
          *) 
    	            echo "l'OS n'est ni un Linux ni un SunOS"
          ;;
     
    esac

  8. #8
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    ah ! oui, c'est mieux comme ça !
    quelques remarques :
    case $(uname -s ) in, puisque apparemment tu ne te ressers pas de VAR
    je ferais une fonction des mv/cp (quand tu vois, comme ici, du code se répéter, cela permet de ne modifier qu'à un seul endroit (dans la définition de la fonction) le code; ça évite les erreurs, les oublis...), à laquelle je passerais le nom du répertoire, et "l'extension" (rh4, sol10) du fichier à considérer.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  9. #9
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    ah ! oui, c'est mieux comme ça !
    quelques remarques :
    case $(uname -s ) in, puisque apparemment tu ne te ressers pas de VAR
    je ferais une fonction des mv/cp (quand tu vois, comme ici, du code se répéter, cela permet de ne modifier qu'à un seul endroit (dans la définition de la fonction) le code; ça évite les erreurs, les oublis...), à laquelle je passerais le nom du répertoire, et "l'extension" (rh4, sol10) du fichier à considérer.
    Je te remercie pour ces 2 remarques ! C'est corrigé pour la première, quant à la seconde : hmmmm, je dirai que je m'y pencherai certainement plus tard (comme j'ai appris cette nuit, le "case", "if" structurés, c'est une première pour moi )

    En revanche, ce serait très gentil de ta part si tu peux m'aider à introduire la gestion des erreurs. Je souhaite par exemple que les erreurs affichées sur l'écran soient écrites dans un fichier (par exemple : lorsque le fichier n'existe pas, ou le cp/mv ne marcheraient pas pour X rasions).

  10. #10
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    la sortie normale des commandes est envoyée vers STDOUT (/dev/fd/1)
    les messages d'erreurs sont envoyés sur STDERR (/dev/fd/2)

    pour envoyer la sortie d'erreur vers un fichier, il faut rediriger 2 (STDERR) vers le fichier souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    deplace() {
       mv "$1" "$2"
    }
     
    deplace $HOME/quinexistepas $HOME/ 2>fichier.log
    par la même occasion tu vois un peu comment fonctionne une fonction

    Cependant, il est facile de tester qu'une fichier, ou un répertoire, existe ou non, afin d'éviter d'exécuter des commandes qui sortiraient des erreurs...
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    la sortie normale des commandes est envoyée vers STDOUT (/dev/fd/1)
    les messages d'erreurs sont envoyés sur STDERR (/dev/fd/2)

    pour envoyer la sortie d'erreur vers un fichier, il faut rediriger 2 (STDERR) vers le fichier souhaité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    deplace() {
       mv "$1" "$2"
    }
     
    deplace $HOME/quinexistepas $HOME/ 2>fichier.log
    par la même occasion tu vois un peu comment fonctionne une fonction

    Cependant, il est facile de tester qu'une fichier, ou un répertoire, existe ou non, afin d'éviter d'exécuter des commandes qui sortiraient des erreurs...
    - le script affiche une erreur pour les Solaris que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./copybin.sh: syntax error at line 3: `(' unexpected
    Je viens de le faire marcher sur Solaris en remplaçant les $() par des `` !!!
    Il faut que je teste maintenant si le script marche toujours sur les Linux...

  12. #12
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par bras39 Voir le message
    - le script affiche une erreur pour les Solaris que voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./copybin.sh: syntax error at line 3: `(' unexpected
    Je viens de le faire marcher sur Solaris en remplaçant les $() par des `` !!!
    Il faut que je teste maintenant si le script marche toujours sur les Linux...

    La même modification marche aussi sous Linux.

    Sinon, comment faites-vous pour éviter dès le départ ce genre de surprises lorsqu'un script devrait s'exécuter sur plusieurs OS ? Pouvez-vous me donner des docs ou des liens qui expliquent comment scripter sous la contrainte de portabilité ?
    Merci

  13. #13
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Ça ne devrait pas arriver. À moins d'atterrir sur un shell qui ne serait pas conforme à la norme POSIX, ou très ancien...
    ?

    vers quoi pointe /bin/sh sur Solaris ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  14. #14
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Ça ne devrait pas arriver. À moins d'atterrir sur un shell qui ne serait pas conforme à la norme POSIX, ou très ancien...
    ?

    vers quoi pointe /bin/sh sur Solaris ?
    Dans mon Solaris /bin pointe vers /usr/bin et :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # which sh
    /usr/bin/sh

  15. #15
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    ah, ah, ah ! mdr ! et /usr/bin/sh ? y pointe vers quoi ?
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  16. #16
    Membre du Club
    Femme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    54
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 54
    Points : 63
    Points
    63
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    ah, ah, ah ! mdr ! et /usr/bin/sh ? y pointe vers quoi ?
    Le Solaris ne connait pas "readlink" !

    Mais j'ai ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    # ls -al /usr/bin/sh
    lrwxrwxrwx   1 root     root          13 Aug 30 18:36 /usr/bin/sh -> ../../sbin/sh

  17. #17
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 552
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    poisse !
    avec un peu de pas_d'chance /sbin/sh est aussi un lien, non ?
    c'est quand même bizarre qu'il ne veuille pas de $( )
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 11/04/2014, 16h22
  2. Script shell copie fichier en fonction de leur nom
    Par Borowsky dans le forum Shell et commandes GNU
    Réponses: 2
    Dernier message: 09/12/2009, 09h27
  3. Réponses: 15
    Dernier message: 29/11/2008, 11h56
  4. Script qui créé plusieurs fonctions
    Par the java lover dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 18/06/2008, 14h10
  5. Réponses: 6
    Dernier message: 16/01/2006, 15h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo