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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    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 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    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 293
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente (Poitou Charente)

    Informations forums :
    Inscription : Septembre 2005
    Messages : 5 293
    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
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 840
    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 840
    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]

+ 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