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 :

[bash] Compararaison de chaines


Sujet :

Shell et commandes GNU

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut [bash] Compararaison de chaines
    Bonjour,
    Je sais que vu le titre, on se dit que le problème a déjà été abordé 1000 fois, et ce n'est pas complètement faux, seulement j'ai beau avoir, je pense, tout essayé de ce qui est proposé un peu partout, et mon problème est toujours d'actualité et je ne comprends vraiment pas pourquoi.

    Voilà mon problème, j'ai une variable contenant une chaine de caractère qui est retournée par un petit script SQL, je la nommerai $reco_result
    JE SAIS quelle est sa valeur à l'heure actuelle, en l'occurrence "MANAGED REAL TIME APPLY" (sans les double quote).

    J'ai écrit une petite condition pour vérifier cette valeur comme suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [[ $reco_result == "MANAGED REAL TIME APPLY" ]]
    then
    echo "OK"
    fi
    Et je n'ai jamais le résultat OK que j'attends...

    J'ai essayé cette condition dans tous les sens comme suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [[ "$reco_result" == "MANAGED REAL TIME APPLY" ]]
    > then
    > echo "OK"
    > fi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [[ $reco_result = "MANAGED REAL TIME APPLY" ]]
    > then
    > echo "OK"
    > fi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if [[ "$reco_result" != 'MANAGED REAL TIME APPLY' ]]
    > then
    > echo "KO"
    > fi
    KO
    J'ai ensuite stocké la string MANAGED REAL TIME APPLY dans une variable $manag pour tester, mais pas mieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [[ "$reco_result" = "$manag" ]]
    > then
    > echo "OK"
    > fi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [[ $reco_result = $manag ]]
    > then
    > echo "OK"
    > fi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if [ "$reco_result" = "$manag" ]
    > then
    > echo "OK"
    > fi
    En résumé quand je teste l'égalité, le echo ne s'exécute pas, quand je teste l'inégalité, le echo s'exécute bien, donc pour le système les deux strings sont vraiment différentes alors que pour moi elles sont identiques, j'ai revérifiée en faisant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     echo $reco_result ; echo $manag
    MANAGED REAL TIME APPLY
    MANAGED REAL TIME APPLY
    Enfin j'ai même été jusqu'à envoyer les résultats de mes variables dans des fichiers textes que j'ai édités avec Vi, puis en faisant un :set list pour voir dans chaque fichier s'il n'y avait pas un espace ou un caractère de fin de ligne, mais non rien. Même un diff de ces deux fichiers textes ne me remonte aucune différence donc je ne comprends vraiment pas pourquoi ma condition ne renvoie pas l'égalité...

    Help ?

    Merci d'avance.

    Bonne journée.

  2. #2
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 292
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    $  echo $reco_result ; echo $manag
    tra lala
    tra lala
    $  echo "$reco_result" ; echo "$manag"
    tra
    lala
    tra lala
    $

  3. #3
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    echo "$reco_result" ; echo "$manag"
    MANAGED REAL TIME APPLY
    MANAGED REAL TIME APPLY
     
     
    echo $reco_result ; echo $manag
    MANAGED REAL TIME APPLY
    MANAGED REAL TIME APPLY

  4. #4
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 292
    Par défaut
    Et bien, d'après ce que je vois, il y a des retours à la lignes dans la variable manag. Ou alors est-ce une mise en forme artificielle?

    Quand on en arrive là, perso, je fais appelle à od -c
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    $  echo "$reco_result" |od -c
    0000000   t   r   a  \n   l   a   l   a  \n
    0000011
     
    $ echo "$manag" |od -c
    0000000   t   r   a       l   a   l   a  \n
    0000011
     
    $

  5. #5
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut
    Effectivement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [nagios@SFE09:/tmp]$ echo "$reco_result" | od -c
    0000000   M   A   N   A   G   E   D       R   E   A   L       T   I   M
    0000020   E       A   P   P   L   Y
    0000040
    *
    0000120  \n
    0000121
    [nagios@SFE09:/tmp]$ echo "$manag" | od -c
    0000000   M   A   N   A   G   E   D       R   E   A   L       T   I   M
    0000020   E       A   P   P   L   Y  \n
    0000030
    Du coup je suis bien embêté.

    J'ai donc un script qui balance une requête SQL qui me retourne le résultat dans une variable $reco_result.
    Mon but est de vérifier que ce résultat est bien MANAGED REAL TIME APPLY, si c'est le cas alors je retourne OK, avec une code retour 0.
    Si ce n'est pas le cas je retourne KO avec un code retour 2 (pour être plus précis il s'agit d'une sonde pour Nagios).

    Comment puis-je vérifier l'inégalité ou l'égalité du retour de la commande SQL avec une chaine de caractère connue ? Sachant que le résultat peut être MANAGED REAL TIME APPLY si tout va bien mais beaucoup d'autres choses si c'est KO, c'est pour ça que je teste l'inégalité de la variable. Mais comme le fait de taper à la main MANAGED REAL TIME APPLY ne semble pas convenir pour le script, ma question est, comment puis-je obtenir mon résultat ?

    Je poste ci-dessous le code source complet de mon script.

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #!/bin/bash
     
    export ORACLE_BASE=/usr/lib/oracle
    export ORACLE_HOME=$ORACLE_BASE/12.1/client64
    export ORACLE_SID=VISABIO
    export TNS_ADMIN=/usr/lib/nagios/plugins
    export ORACLE_TERM=xterm
    export PATH=/usr/sbin:$PATH
    export PATH=$ORACLE_HOME/bin:$PATH
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
    export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
     
    DB_USER=$1
    DB_PASS=$2
    DB_NAME=$3
     
    (
    sqlplus -S $DB_USER/$DB_PASS@$DB_NAME <<EOF
    set pagesize 0
    set termout OFF
    set feedback OFF
    set heading OFF
    set echo OFF
    set serveroutput ON
     
    spool /tmp/reco.tmp
    select recovery_mode from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool /tmp/syncstatus.tmp
    select SYNCHRONIZATION_STATUS from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool /tmp/sync.tmp
    select SYNCHRONIZED from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    EOF
    )
     
    reco_result=`cat /tmp/reco.tmp`
    syncstatus_result=`cat /tmp/syncstatus.tmp`
    sync_result=`cat /tmp/sync.tmp`
     
    rm -f /tmp/reco.tmp /tmp/syncstatus.tmp /tmp/sync.tmp
     
    if [[ $reco_result != "MANAGED REAL TIME APPLY" ]] || [[ $syncstatus_result != "OK" ]] || [[ $sync_result != "YES" ]]
    then
            echo "KO, la synchro Dataguard de la base $DB_NAME n'est plus active"
            exit 2
    else
            echo "OK"
            exit 0
    fi

  6. #6
    Expert confirmé Avatar de Flodelarab
    Homme Profil pro
    Inscrit en
    Septembre 2005
    Messages
    5 292
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 292
    Par défaut
    Tu peux opter pour la version "filtre" grep:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ if grep -q "MANAGED REAL TIME APPLY" <<<"$manag"; then echo "ok"; fi
    ok
    Ou alors supprimer les éléments qui gênent la comparaison. Et faire le test sur le résultat.
    Ici, je prends l'exemple d'un retour dont seule la première ligne est intéressante et sans '\n':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ manag_modif=$(sed 's/\n//g;q' <<<"$manag" )
    Il reste à déterminer la modification de texte qui TE convient.
    Outils de manipulation de texte idoines: bash, grep, sed, awk.

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 660
    Par défaut
    grep n'est pas utile :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    if [[ $reco_result =~ $manag ]]; then echo OK; else echo ko; fi

    c'est quoi ça : ???
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  8. #8
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    grep n'est pas utile :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    if [[ $reco_result =~ $manag ]]; then echo OK; else echo ko; fi
    Oui je viens de trouver le "=~" que je ne connaissais pas, je pense que je vais inverser ma condition et partir là-dessus. Sauf si quelqu'un connait l'équivalent inverse (tester la non présence d'une string au sein d'une autre).

    Citation Envoyé par N_BaH Voir le message
    c'est quoi ça : ???
    Je ne sais pas d'où ça sort, vu que c'est le résultat d'une commande SQL à la base ça doit peut-être sortir un résultat bizarre dans le genre...
    Je ne sais pas trop pourquoi j'ai ça en plus...

    Je teste en inversant ma condition et si ok je passe le post en résolu.

  9. #9
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut
    Citation Envoyé par Flodelarab Voir le message
    Tu peux opter pour la version "filtre" grep:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ if grep -q "MANAGED REAL TIME APPLY" <<<"$manag"; then echo "ok"; fi
    ok
    J'ai vu ça mais pour ce que j'ai à faire ça compliquerait la tâche inutilement je pense.

    Citation Envoyé par Flodelarab Voir le message
    Ou alors supprimer les éléments qui gênent la comparaison. Et faire le test sur le résultat.
    Ici, je prends l'exemple d'un retour dont seule la première ligne est intéressante et sans '\n':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $ manag_modif=$(sed 's/\n//g;q' <<<"$manag" )
    Il reste à déterminer la modification de texte qui TE convient.
    Outils de manipulation de texte idoines: bash, grep, sed, awk.
    Avec sed ça ne fonctionne pas, le "\n" ne doit pas suffire, sûrement à cause du caractère parasite qu'on retrouve sur la ligne


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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 660
    Par défaut
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    $ reco_result="MANAGED REAL TIME APPLY *"
    $ manag="MANAGED REAL TIME APPLY"
    $ if [[ $reco_result =~ $manag ]]; then echo OK; else echo ko; fi
    OK
    $ if [[ ! $reco_result =~ $manag ]]; then echo OK; else echo ko; fi
    ko
    $
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  11. #11
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 349
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 349
    Par défaut
    Citation Envoyé par veis Voir le message
    Avec sed ça ne fonctionne pas, le "\n" ne doit pas suffire, sûrement à cause du caractère parasite qu'on retrouve sur la ligne

    Bonjour,
    Juste pour la compréhension, le 0000040 est l'offset dans le fichier (la position en octal), le * c'est pour préciser que toute la ligne (0000040 à 0000057) est répétée jusqu'à la prochaine position (multiple de 20 en octal) qu'il indique, donc ici 0000120.
    Si tu veux connaitre explicitement le caractère (qui ici doit être un espace), tu peux faire un "od -t a" au lieu de "od -c".

  12. #12
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2011
    Messages
    1 946
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 1 946
    Par défaut
    Salut,

    Le script (cat foo.sh ) :
    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
    #!/bin/bash
     
    A="bla bla bla"
    B="bla bla bla                                                         "
     
    echo -e "${A}\n${B}" | cat -A
    echo
    echo -e "${A}\n${B}" | od -c
    echo
    echo -e "${A}\n${B}" | od -t a
    echo
    if [[ ${A} =~ ${B%"${B##*[![:space:]]}"} ]]
    	then echo "OK"
    	else echo "KO"
    fi
    L'exécution (./foo.sh ) :
    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
    bla bla bla$
    bla bla bla                                                         $
     
    0000000   b   l   a       b   l   a       b   l   a  \n   b   l   a    
    0000020   b   l   a       b   l   a                                    
    0000040                                                                
    *
    0000120  \n
    0000121
     
    0000000   b   l   a  sp   b   l   a  sp   b   l   a  nl   b   l   a  sp
    0000020   b   l   a  sp   b   l   a  sp  sp  sp  sp  sp  sp  sp  sp  sp
    0000040  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp  sp
    *
    0000120  nl
    0000121
     
    OK

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 660
    Par défaut
    Citation Envoyé par disedorgue
    Juste pour la compréhension, le 0000040 est l'offset dans le fichier (la position en octal), le * c'est pour préciser que toute la ligne (0000040 à 0000057) est répétée jusqu'à la prochaine position (multiple de 20 en octal) qu'il indique, donc ici 0000120.
    ce qui me fait penser que même une regex n'est pas utile, puisque le début le chaîne correspond, utilisons un motif générique, qui fonctionne avec [[ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ reco_result="MANAGED REAL TIME APPLY <espaces> "
    $ manag="MANAGED REAL TIME APPLY"
    $ if [[ ! $reco_result == $manag* ]]; then echo "ne correspnd pas"; else echo "correspond"; fi
    correspond
    $
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  14. #14
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par veis Voir le message
    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
    #!/bin/bash
    (
    sqlplus -S $DB_USER/$DB_PASS@$DB_NAME <<EOF
    set pagesize 0
    set termout OFF
    set feedback OFF
    set heading OFF
    set echo OFF
    set serveroutput ON
     
    spool /tmp/reco.tmp
    select recovery_mode from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool /tmp/syncstatus.tmp
    select SYNCHRONIZATION_STATUS from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool /tmp/sync.tmp
    select SYNCHRONIZED from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    EOF
    )
     
    reco_result=`cat /tmp/reco.tmp`
    syncstatus_result=`cat /tmp/syncstatus.tmp`
    sync_result=`cat /tmp/sync.tmp`
     
    rm -f /tmp/reco.tmp /tmp/syncstatus.tmp /tmp/sync.tmp
    Bonjour

    En dehors de ton soucis de string, j'en vois un autre: les fichiers temporaires.
    Bon, déjà c'est super bien de penser à travailler dans /tmp. J'ai connu un admin, une fois, il mettait tout dans "/". J'avais envie de le balancer lui et sa machine par la fenêtre.
    Toutefois, n'oublie pas qu'un script est toujours susceptible d'avoir plusieurs instances qui tournent en parallèle (Unix est multi users multi tâches). Et dans ce cas, grosse collision sur les fichiers /tmp/reco.tmp et autres.

    Astuces pour éviter ce danger
    • penser que sur les Unix récents, les users possèdent leur propre tmp => $HOME/tmp
    • penser à la variable $$ donnant le pid en cours (unique à un instant donné)
    • éventuellement essayer de donner aux fichiers un nom en relation avec le script qui les crée ($0)


    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
    #!/bin/bash
     
    base=`basename "$0"`
    reco_tmp="$HOME/tmp/$base_reco_$$.tmp"
    status_tmp="$HOME/tmp/$base_status_$$.tmp"
    sync_tmp="$HOME/tmp/$base_sync_$$.tmp"
     
    (
    sqlplus -S $DB_USER/$DB_PASS@$DB_NAME <<_EOT_
    set pagesize 0
    set termout OFF
    set feedback OFF
    set heading OFF
    set echo OFF
    set serveroutput ON
     
    spool "$reco_tmp"
    select recovery_mode from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool "$status_tmp"
    select SYNCHRONIZATION_STATUS from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool "$sync_tmp"
    select SYNCHRONIZED from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    _EOT_
    )
     
    reco_result=`cat "$reco_tmp"`
    syncstatus_result=`cat "$status_tmp"`
    sync_result=`cat "$sync_tmp"`
     
    rm -f "$reco_tmp" "$status_tmp" "$sync_tmp"
    Oui, c'est vrai, un peu plus de rigueur. Mais que de soucis évités en retour...

    PS: tu remarqueras que je protège toujours mes chaines (ou les variables qui contiennent des chaines) par des guillemets. C'est aussi un élément de rigueur de plus pour éviter les soucis de noms avec espace...
    PS2: les lignes situées après le << sont des lignes texte, non du "fichier". Alors autant être cohérent (et montrer qu'on sait ce qu'on manipule) et nommer le tag de fermeture "_EOT_" (End Of text) et non "EOF" (End Of File). Les underscores c'est juste pour qu'il se démarque plus facilement à la lecture...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  15. #15
    Membre averti
    Homme Profil pro
    Administrateur systèmes et applicatif
    Inscrit en
    Novembre 2004
    Messages
    27
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Administrateur systèmes et applicatif
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Novembre 2004
    Messages : 27
    Par défaut
    Bonjour à tous,

    Merci Sve@r pour tes précieux conseils. Il est vrai que quand je code je suis un peu dans le speed donc je ne prends pas le temps de faire un truc super propre, l'essentiel étant que ça fonctionne.
    Aujourd'hui que j'ai un peu de temps j'en ai donc profité pour reprendre mon script et j'ai tenu compte de tes conseils.

    Merci à tous les autres également pour votre aide très précieuse.

    Je vous poste mon code remanié (un petit peu) au cas où quelqu'un d'autre aurait besoin de s'en inspirer pour monitorer un Dataguard Oracle

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    #!/bin/bash
     
    export ORACLE_BASE=/usr/lib/oracle
    export ORACLE_HOME=$ORACLE_BASE/12.1/client64
    export ORACLE_SID=VISABIO
    export TNS_ADMIN=/usr/lib/nagios/plugins
    export ORACLE_TERM=xterm
    export PATH=/usr/sbin:$PATH
    export PATH=$ORACLE_HOME/bin:$PATH
    export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
    export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib
     
    DB_USER=system
    DB_PASS=manager
    DB_NAME=$1
     
    base=`basename "$0"`
    reco_tmp="/var/log/nagios/tmp/'$base'_reco_$$.tmp"
    status_tmp="/var/log/nagios/tmp/'$base'_status_$$.tmp"
    sync_tmp="/var/log/nagios/tmp/'$base'_sync_$$.tmp"
    protect_tmp="/var/log/nagios/tmp/'$base'_protect_$$.tmp"
     
    (
    sqlplus -S $DB_USER/$DB_PASS@$DB_NAME <<_EOT_
    set pagesize 0
    set termout OFF
    set feedback OFF
    set heading OFF
    set echo OFF
    set serveroutput ON
     
    spool "$reco_tmp"
    select recovery_mode from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool "$status_tmp"
    select SYNCHRONIZATION_STATUS from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool "$sync_tmp"
    select SYNCHRONIZED from v\$archive_dest_status where type='PHYSICAL' ;
    spool off
     
    spool "$protect_tmp"
    select PROTECTION_LEVEL from v\$database ;
    spool off
     
    _EOT_
    )
     
    reco_result=`cat $reco_tmp`
    syncstatus_result=`cat $status_tmp`
    sync_result=`cat $sync_tmp`
    protect_result=`cat $protect_tmp`
     
    rm -f "$reco_tmp" "$status_tmp" "$sync_tmp" "$protect_tmp"
     
    if [[ $reco_result =~ "MANAGED REAL TIME APPLY" ]] && [[ $syncstatus_result =~ "OK" ]] && [[ $sync_result =~ "YES" ]] && [[ $protect_result =~ "MAXIMUM AVAILABILITY" ]]
    then
            echo "OK"
            exit 0
    else
            echo "KO, la synchro Dataguard de la base $DB_NAME n'est plus active"
            exit 2
    fi
    Tu remarqueras que je n'ai pas utilisé la variable $HOME dans mes noms de variables, la raison étant qu'il prenait le /root et forcément, l'utilisateur nagios n'a pas les droits pour écrire à cet endroit, du coup ça plantait ma sonde... Je n'ai pas trouvé pourquoi et je dois dire que je n'ai pas forcément le temps de chercher plus que ça non plus, donc j'ai mis le chemin en dur et ça fonctionne comme ça. Ceci dit ça reste un mystère pour moi, sachant que les sondes sont exécutées en tant qu'uilisateur nagios, je ne sais pas pourquoi il a voulu prendre le /root comme $HOME...
    Et j'ai également dû protéger le '$base' entre quote dans le nom des variables, sinon avec les underscores il voulait prendre tout le nom commençant par un $ pour une variable, et forcément me disait que la variable n'existe pas.
    En tout cas merci à tous

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 660
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    base=`basename "$0"`
    reco_tmp="/var/log/nagios/tmp/${base}_reco_$$.tmp"
    ...
    ?
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  17. #17
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 835
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 835
    Billets dans le blog
    1
    Par défaut
    N_Bah t'a montré comment protéger un nom de variable => les accolades
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    prix=10
    echo "Mon vélo coûte ${prix}F"             # Evite que le shell essaye d'afficher la variable "$prixF"

    Permet en plus des manipulations sympas
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    prix=10
    echo "Mon vélo coûte ${prix:-100}F"               # Si "prix" existe et est non vide, cela affichera sa valeur, sinon ça affichera "100"

    Citation Envoyé par veis Voir le message
    Tu remarqueras que je n'ai pas utilisé la variable $HOME dans mes noms de variables, la raison étant qu'il prenait le /root et forcément, l'utilisateur nagios n'a pas les droits pour écrire à cet endroit, du coup ça plantait ma sonde... Je n'ai pas trouvé pourquoi et je dois dire que je n'ai pas forcément le temps de chercher plus que ça non plus, donc j'ai mis le chemin en dur et ça fonctionne comme ça. Ceci dit ça reste un mystère pour moi, sachant que les sondes sont exécutées en tant qu'uilisateur nagios, je ne sais pas pourquoi il a voulu prendre le /root comme $HOME...
    Si tu appelles ton programme avec su nagios, alors il garde l'environnement de celui qui a appelé su (ici root).
    Si tu prends soin de préciser su - nagios, alors il prend aussi l'environnement de nagios.

    Si c'est pas ça, alors tu devrais vite t'intéresser au truc parce que tu as un gros gros soucis de paramétrage (beaucoup de programmes utilisent $HOME)...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. [bash] Découper une chaine de caractères
    Par _PaTaTe_ dans le forum Shell et commandes GNU
    Réponses: 8
    Dernier message: 28/02/2015, 18h16
  2. Bash - Découper une chaine de caractères
    Par nicolas.pissard dans le forum Shell et commandes GNU
    Réponses: 13
    Dernier message: 16/12/2014, 13h18
  3. Réponses: 8
    Dernier message: 22/02/2010, 09h35
  4. [BASH] extraire une chaine d'une autre
    Par zevince dans le forum Linux
    Réponses: 4
    Dernier message: 05/03/2009, 12h00
  5. Réponses: 4
    Dernier message: 04/08/2007, 15h13

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