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

Linux Discussion :

Tester unicité d'un script


Sujet :

Linux

  1. #1
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 46
    Points : 40
    Points
    40
    Par défaut Tester unicité d'un script
    Bonsoir à toutes et à tous.

    Développant tranquillou à la maison sous Linux, j'ai créé un petit script appelé monScript.sh en bash.

    Je voudrais que l'on ne puisse pas le lancer deux fois. j'ai donc penser à placer une petite boucle if en début de script, de la façon suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #/bin/bash
     
    sNomScript=`basename $0`
    if [ `ps | grep ${sNomScript} | wc -l` -gt 1 ]; then
         echo "ERREUR : Script deja lance"
         exit 1
    fi
    Je voulais me la tenter comme ça, car quand j'essayais a la mano ca marchait plutôt pas mal.
    Je lançais d'abord mon script de la manière suivante : Puis je faisais un et cela me retournait bien une seule et unique ligne.

    Cependant, dans le script, la commande
    me ramène plusieurs lignes. Je soupçonne le grep de s'ajouter à la liste des process correspondant à ma recherche, mais je n'en suis pas certain.

    Je me tâte du coup pour savoir comme faire pour tester l'unicité de mon script. ^_^

    Comment faire pour ne pas voir le grep dans la liste de mes process et voir uniquement ce que je précise dans ma recherche ?

    La solution facile serait d'incrémenter de 1 le nombre de lignes valides lorsqu'une seule occurence de monScript.sh est lancée, mais je ne trouve pas ça très propre :p.

    Merci d'avance pour votre aide.

    Cdt.

    Bahan

  2. #2
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Une solution est de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    grep toto | grep -v grep
    Cela dit la méthode du ps pour tester si le programme tourne déjà n'est pas très bonne. Quelqu'un peut lancer ton script avec un alias, ou via un lien symbolique, et dans ce cas tu ne le détectera pas.

    Une solution plus sûr et de générer dans ton script un fichier de lock, qui contient le pid du process. Quand tu te lances, tu vérifies si le fichier de lock existe. Si c'est le cas, tu regardes si le pid dans le fichier tourne. S'il tourne, tu ne te lance pas. S'il ne tourne pas, c'est un fichier qui n'a pas été correctement détruit, donc tu le détruis et te te lances.

    Note aussi qu'en général tu as une commande appelée "start-stop-daemon" qui fait exatement ça : lancer une commande avec un fichier de lock. En plus elle a plein d'options sympa pour lancer la commande en background, sous un user particulier, etc.

  3. #3
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 46
    Points : 40
    Points
    40
    Par défaut
    Cela dit la méthode du ps pour tester si le programme tourne déjà n'est pas très bonne. Quelqu'un peut lancer ton script avec un alias, ou via un lien symbolique, et dans ce cas tu ne le détectera pas.
    Hum, tu as raison sur ce point.

    Une solution plus sûr et de générer dans ton script un fichier de lock, qui contient le pid du process. Quand tu te lances, tu vérifies si le fichier de lock existe. Si c'est le cas, tu regardes si le pid dans le fichier tourne. S'il tourne, tu ne te lance pas. S'il ne tourne pas, c'est un fichier qui n'a pas été correctement détruit, donc tu le détruis et te te lances.
    J'y ai pensé mais il y a une situation me taraudait, celle du cas où mon fichier était stoppé abruptement. Cependant, avec ta méthode, c'est génial car avec le PID à l'intérieur du fichier .lock, je peux voir que le script ne tourne plus.

    Bien joué .

    Note aussi qu'en général tu as une commande appelée "start-stop-daemon" qui fait exatement ça : lancer une commande avec un fichier de lock. En plus elle a plein d'options sympa pour lancer la commande en background, sous un user particulier, etc.
    Merci pour cette information.
    Je vais aller également chercher de la documentation là-dessus.

    Cdt.

    Bahan

  4. #4
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 46
    Points : 40
    Points
    40
    Par défaut
    Bonjour,

    Je me permets de remonter ce message car un problème m'est survenu récemment.

    Voilà à quoi ressemble mon script d'unicité :
    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
    CtrlUnicity ()
    {
      if [ -e monFichierLock ]; then
        local sPrevPid=`cat monFichierLock`
     
        if [ `ps -e | grep ${sPrevPid} -c` -eq 1 ]; then
          # PID tourne
          echo "script deja lance" >> MonFichierLog
          exit 1
        else
          # PID tourne pas
          rm -f monFichierLock
          echo $$ > monFichierLock
        fi
      else
        # pas de fichier lock donc PID tourne pas
        echo $$ > monFichierLock
      fi
     }
    Cependant, j'ai essayé d'ordonnancer mon script avec la crontab et alors là, un phénomène intéressant se produit :

    Si je lance mon script deux fois manuellement, la deuxième fois, je me fais jeter, et tout va bien.

    Si je lance via la crontab deux fois mon script, alors la deuxième fois pareil l'unicité marche bien.

    Par contre, si je lance d'abord le script manuellement en tant que user MonUser, puis en utilisant la crontab de MonUser, et bien là, le script peut se lancer deux fois x_x.

    La raison que j'ai trouvée c'est que l'utilisateur MonUser ne voit pas les process de sa propre crontab et réciproquement...

    Pourquoi ne puis-je voir les processus lancés par la crontab de MonUser alors que je suis l'utilisateur MonUser ?

    Je voudrais vous demander votre avis pour savoir si j'ai raté quelque chose dans mon script d'unicité.

    Merci d'avance pour votre aide.

    Cdt.

    Bahan

  5. #5
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Je pense que c'est parce que cron n'exécute pas le script dans le même répertoire que ton user. Comme tu créé/lit le fichier MonFichierLog dans le répertoire courant, forcément, l'un ne voit pas l'autre.

    Donc, utilise un chemin absolu pour ton fichier de PID.

  6. #6
    Membre du Club
    Inscrit en
    Juillet 2008
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Juillet 2008
    Messages : 46
    Points : 40
    Points
    40
    Par défaut
    Bonsoir.
    Je pense que c'est parce que cron n'exécute pas le script dans le même répertoire que ton user. Comme tu créé/lit le fichier MonFichierLog dans le répertoire courant, forcément, l'un ne voit pas l'autre.

    Donc, utilise un chemin absolu pour ton fichier de PID.
    Arf, désolé, j'ai oublié de préciser mais quand je dis monFichierLock etc..., il s'agit bien de variables contenant le path absolu ^_^.

    Bahan

  7. #7
    LLB
    LLB est déconnecté
    Membre expérimenté
    Inscrit en
    Mars 2002
    Messages
    967
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 967
    Points : 1 410
    Points
    1 410
    Par défaut
    Avec ps -ax, tu devrais voir le processus.

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 718
    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 718
    Points : 31 035
    Points
    31 035
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Bahan_auboulot Voir le message
    La raison que j'ai trouvée c'est que l'utilisateur MonUser ne voit pas les process de sa propre crontab et réciproquement...
    Ta commande "ps -e" ne donne que tes processus. Faut y rajouter l'option "a" pour voir tous les processus et probablement, comme l'a dit LLB, l'option "x" pour voir ceux qui sont lancés sans terminal (comme cron) => ps -eax

    Citation Envoyé par Bahan_auboulot Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if [ `ps -e | grep ${sPrevPid} -c` -eq 1 ]; then
    Petite optimisation => grep renvoie "faux" s'il ne trouve rien donc on peut tester directement le grep (en prenant soin de rediriger son affichage) et éviter un sous processus (rappel: "if" peut vérifier le booléen de n'importe quelle commande et pas seulement celui de la commande "test")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ps -aex | grep ${sPrevPid} 1>/dev/null; then
    et le rm -f est inutile puisque le fichier est réécrasé par le echo
    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]

Discussions similaires

  1. Tester si le shell script est lance en background ou pas ?
    Par mhtrinh dans le forum Shell et commandes GNU
    Réponses: 4
    Dernier message: 20/02/2008, 10h14
  2. Fonction controlant l'unicite d'un script
    Par Bahan dans le forum C
    Réponses: 8
    Dernier message: 26/07/2006, 11h14
  3. [SQLPLUS]Tester l'ouverture d'un script sql
    Par maerste dans le forum Oracle
    Réponses: 1
    Dernier message: 29/12/2005, 22h38
  4. [débutant] Comment tester scripts sans installer Oracle ?
    Par belokan dans le forum Installation
    Réponses: 17
    Dernier message: 25/10/2005, 10h35
  5. Réponses: 3
    Dernier message: 16/10/2005, 13h43

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