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 :

shell script et signaux


Sujet :

Linux

  1. #1
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut shell script et signaux
    Bonjour,
    je voudrais écrire un script shell et j'aurais besoin d'aide en ce qui concerne l'envoi et la gestion des signaux.

    Dans mon script je voudrais faire la chose suivante.

    Dans une boucle (disons 10x ) je voudrais appeler une fonction qui fait un certain traitement.

    Je voudrais que ces fonctions soient exécutées en parallèle.

    Le "main" attend que toute les instances des fonctions soient terminées et puis se termine.

    Je pense a l'utilisation des signaux. Le code ressemblerait a ceci:

    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
     
    #!/bin/bash
     
    function myFunction()
    {
    	# faire qqch long ici
    	echo "fonction finie"
    	# envoyer signal ?
    }
     
    i=1
    while [ $i -le 10 
    do
    	myFunction &
    	let "i+=1"
    done
     
    # Attendre ici que toutes les fonctions se terminent
    # trap un signal ici ?
    echo "Fin"
    exit 0;
    myFunction est appelé en arriere plan avec "&". Après la boucle while, le main attend de recevoir 10x un signal de fin de fonction et puis se termine.

    Qu'en pensez vous ?
    pourriez-vous me rediriger vers une doc montrant l'utilisation des signaux dans un script shell ?

    Merci d'avance,
    Tex

  2. #2
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Bon j'ai un peu avance. Voici ce que ca donne:

    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
     
    #!/bin/bash
     
    NUM_FUNCTIONS=10
     
    function myFunction()
    {
    	echo "Function $1 start."
    	sleep 5
    	echo "Sending signal to pid: $$."
     
    	kill -s SIGUSR1 $$
    	echo "Function $1 end."
     
    }
     
    function handle_signal()
    {
    	echo "Handeling signal"
    	let "NUM_FUNCTIONS-=1"
    	echo "NUM_FUNCTIONS: $NUM_FUNCTIONS:"
    }
     
     
    i=1
    echo "main pid: $$"
    while [ $i -le 10 ] 
    do
    	myFunction $i &
    	let "i+=1"
    done
     
    # Attendre ici que toutes les fonctions se terminent
    # trap un signal ici ?
     
    trap handle_signal SIGUSR1 SIGINT
     
    while [ $NUM_FUNCTIONS -ge 0 ]
    do
            sleep 0	
    done
     
    echo "Main end"
     
    exit 0;
    Le probleme est que j'intercepte bien le signal SIGINT si j'appuie sur Ctrl+C pendant l'exécution mais le signal SIGUSR1 que n'a pas l'air de marcher ...

    EDIT: en fait , ca marche mais le programme n'intercepte pas tout les SIGUSR1 envoyés par les fonctions. On dirait qu'il en rate qqs uns. Si j'en envoie d'autre "a la main" via un autre shell ca marche.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Salut !
    L'utilisation des signaux dans un script shell ce fait avec deux commandes principal :
    -kill (ou killpg )
    -trap

    leurs syntaxe est simple : kill -sig -pid
    trap `command` -sig

  4. #4
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    Salut !
    L'utilisation des signaux dans un script shell ce fait avec deux commandes principal :
    -kill (ou killpg )
    -trap

    leurs syntaxe est simple : kill -sig -pid
    trap `command` -sig
    ok c'est ce que j'ai fais dans ma réponse mais j'ai qd meme un souci. cf. plus haut

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Oui ben ton trap est mal placé il doit etre avant l'appel de ta fonction qui envoie le signal ^^

    L'ordre logique c'est d'abord de mettre le systeme en alerte pour un eventuel signal (trap ...) et ensuite d'envoyer ton signal qui sera capter par trap.

  6. #6
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    Oui ben ton trap est mal placé il doit etre avant l'appel de ta fonction qui envoie le signal ^^
    Le resultat est le meme si je place le trap en debut du script.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Oui c'est assez bizare...je te conseil de restructuré ton code de facon a ce que le signal soit intercepté
    EDIT: essai de remplacer le signal SIGUSR1 par un autre... pour voir si ca vient du signal ou de ton algo

  8. #8
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Bon deja ce qui n'etait pas bon est la variable NUM_FUNCTION qui etait incrementee et decrementee en meme temps. maic ca ne change pas grand chose. Si j'execute ke code suivant SANS mettre la fonction en arriere pla, ca marche.

    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
     
    #!/bin/bash
     
    trap handle_signal SIGUSR1
    NUM_FUNCTIONS=5
    NUM_FUNCTIONS_LEFT=$NUM_FUNCTIONS
     
    function myFunction()
    {
    	echo "Function $1 start."
    	sleep 2
    	echo "Sending signal to pid: $$."
    	kill -s SIGUSR1 $$
    	#echo "Function $1 end."
     
    }
     
    function handle_signal()
    {
    	echo "Handeling signal"
    	let "NUM_FUNCTIONS_LEFT-=1"
    	echo "NUM_FUNCTIONS_LEFT: $NUM_FUNCTIONS_LEFT"
    }
     
     
    i=1
    echo "main pid: $$"
    while [ $i -le $NUM_FUNCTIONS ] 
    do
    	myFunction $i
    	let "i+=1"
    done
     
    echo "sleeping"
    while [ $NUM_FUNCTIONS_LEFT -gt 0 ]
    do
            sleep 0	# This script is not really doing anything.
    done
     
    echo "Main end"
     
    exit 0;
    Des que je rajoute le & ca ne marche plus.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Oki ^^ Oui le signal SIGUSR1 ne doit pas etre prevue pour fonctionné avec des programme ou fonction en fond...

  10. #10
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    Oki ^^ Oui le signal SIGUSR1 ne doit pas etre prevue pour fonctionné avec des programme ou fonction en fond...
    en effet Alors quel signal dois-je utiliser ?

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Ca depend de l'utilisation que tu veux faire de ton programme...
    Je suppose que si tu as utiliser SIGUSR1 c'est pour faire un systeme d'interprocessus de base non ?

  12. #12
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    Ca depend de l'utilisation que tu veux faire de ton programme...
    Je suppose que si tu as utiliser SIGUSR1 c'est pour faire un systeme d'interprocessus de base non ?
    Oui mais je suis en train de me demander si je ne fais pas une connerie. Disons je voudrais juste que ce code marche

    Le communication inter-processus se situe entre la fonction et le main donc peut etre qu' il n'y a meme pas besoin d'envoyer les signaux. Dans cet exemple, on voit que le pid est le meme dans la fonction (executee en arriere plan) que dans le main.

    Je pourrais alors decrementer la variable FUNCTION_LEFT directement dans la fonction. Le problème est que cette variable nÄest pas "statique" donc si je la decremente 5x dans 5 fonction en arriere plan, elle sera egale a 4 et non pas a 0.

    Comment pourrais-je m'en sortir alors ?

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    J'avoue c'est un petit casse tete cette histoire lol ^^
    A la place de ton while utilise une boucle d'itération (5x).
    Honnetement je programme rarement des scripts shell complexe donc je ne saurais t'aider plus que je ne l'ai fait... dsl .

  14. #14
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    A la place de ton while utilise une boucle d'itération (5x).
    Ca changerait quoi ?

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Effectivement rien --_-- dsl j'ai confondu deux de tes variables lool. non ca changerais effectivement rien dutout...
    EDIT : dsl mais je vais bosser GTK là donc bonne chance pour ton script.
    au passage si tu programme en C tu peux m'envoyer un message avec ton adresse msn je cherche des programmeurs pour un projet sous linux

  16. #16
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    Effectivement rien --_-- dsl j'ai confondu deux de tes variables lool. non ca changerais effectivement rien dutout...
    EDIT : dsl mais je vais bosser GTK là donc bonne chance pour ton script.
    ok bon courage

  17. #17
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Bon, je m'en suis sorti autrement:
    Je lance les fonctions en arrière plan et je récupère leur pid dans le main avec l'opérateur $!. J'attends ensuite que chacun des ses processus (pid) se finisse avec la fonction wait pid:

    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
     
    #!/bin/bash
     
    # number of functions to run in background
    NUM_FUNCTIONS=10
     
    # array of backgroud function pid's
    declare -a FUNCTION_PID
     
    function myFunction()
    {
    	echo "Function $1 sleeps."
    	sleep 2
    }
     
     
     
    i=1
    echo "main pid: $$"
     
    THREADS=1
     
    if [ $THREADS -eq 1 ];then
    	echo "THREADS"
    else
    	echo "NO THREADS"
    fi
     
     
    while [ $i -le $NUM_FUNCTIONS ] 
    do
    	myFunction $i $i & 
    	FUNCTION_PID[$i]=$!
    	let "i+=1"
    done
     
     
    # we wait here for all the child processes to terminate
    for i in ${FUNCTION_PID[@]} ; do
    	#echo "Waiting for $i ..."
    	wait $i
    	echo "$i ret code is $?. "
    done
     
    echo "Main end"
     
    exit 0;

  18. #18
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Ah oui c'est une bonne solution ^^ tu pouvais peut etre aussi faire un test $? - ne 0 apres chaque fonction executer pour attendre leurs valeur de retour.

  19. #19
    Membre régulier Avatar de Tex-Twil
    Inscrit en
    Avril 2004
    Messages
    447
    Détails du profil
    Informations forums :
    Inscription : Avril 2004
    Messages : 447
    Points : 122
    Points
    122
    Par défaut
    Citation Envoyé par suyeon Voir le message
    tu pouvais peut etre aussi faire un test $? - ne 0 apres chaque fonction executer pour attendre leurs valeur de retour.
    Non justement. Je ne veux pas attendre le retour des fonctions dans le while. Je peux récupérer les codes de retour des fonctions avec le wait. J'ai modifie un peu le code dans mon precedent post pour afficher le ret code de chaque fonction a la fin

  20. #20
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    43
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 43
    Points : 31
    Points
    31
    Par défaut
    Ah oui effectivement tu as besoin du pid de chaque fonctions pour ton wait ^^.

Discussions similaires

  1. Envoi d'une variable en shell script sur php
    Par Ponchi dans le forum Langage
    Réponses: 3
    Dernier message: 07/02/2006, 14h54
  2. Executer en tant que en shell script ?
    Par fabszn dans le forum Linux
    Réponses: 3
    Dernier message: 13/01/2006, 16h08
  3. shell script depuis c
    Par 03011226 dans le forum C
    Réponses: 10
    Dernier message: 08/12/2005, 19h56
  4. Parser une chaine en shell script
    Par Gogoye dans le forum Linux
    Réponses: 10
    Dernier message: 19/07/2004, 18h49
  5. Retour de requete postgresql / Shell Script
    Par doohan dans le forum Requêtes
    Réponses: 3
    Dernier message: 26/06/2003, 19h07

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