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

Bibliothèque standard C Discussion :

UNIX, AIX, du bon usage de la commande system


Sujet :

Bibliothèque standard C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut UNIX, AIX, du bon usage de la commande system
    la commande "ls /et" renvoie 2 sur mon unix aix et renvoie 512 avec la commande system. Comment faire pour avoir 2 ???

    pour le source:

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    int main()
    {
           char  cmd[256] ;
           int num;
     
           strcpy (cmd, "ls /et") ;
           num = system(cmd);
           printf("int : %d\n",num);
           return (num) ;
    }
    pour la compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /usr/vac/bin/xlc  -c  main.c
    /usr/vac/bin/xlc -o main main.o
    Merci d'avance.

  2. #2
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    euh....

    la sortie de ls n'EST PAS la sortie de system...

    la sortie de system est (voir le man page) en gros succès ou erreur.

    Pour obtenir la sortie de ls, pas vraiment de moyen direct. Un pipe, un script qui transforme la valeur de sortie en variable qu'après tu exportes,.....

  3. #3
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Pour obtenir la sortie de ls, pas vraiment de moyen direct. Un pipe,
    Utiliser popen()/pclose() plutot que pipe() si possible.

    un script qui transforme la valeur de sortie en variable qu'après tu exportes,.....
    Tu es distrait, exporter une variable vers le processus pere, ca me semble impossible.

  4. #4
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    l'exemple du ls c'est pour le forum. J'ai un binaire qui renvoie 0, 1,... 200

    en gros avec la commande system j'ai 0 ou n'importe quoi

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par elecoest Voir le message
    l'exemple du ls c'est pour le forum. J'ai un binaire qui renvoie 0, 1,... 200

    en gros avec la commande system j'ai 0 ou n'importe quoi
    2 solutions que j'ai trouvées :

    • soit tu fais sortir ton binaire (si ton binaire tu peux lui rajouter un fprintf(stdout) à la fin) dans un fichier tempo, et tu fais :

      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
       
      FILE *f=NULL ;
      char command[500] ;
      int s, result ;
       
      sprintf ( command, "./monbinaire > ./sortie.txt");
      s = system(command);
       
      if ( (f = fopen("./sortie.txt", "r")) != NULL )
       {
           fgets ( command, 500, f);
           sscanf ( command, "%d", &result);
       
           fclose(f);
           sprintf ( command, "rm -f ./sortie.txt");
           s = system(command);
       }
    • soit, si tu connais ton nom de binaire au début, par exemple, tu peux faire (sans rien changer au binaire ui ressort une valeur numérique):

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ./monprog `./monbinaire`
      quand tu le lances, et dans ton prog monprog tu as

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
       
      int main ( int argc, char **argv )
      {
        ......
        sscanf ( argv[1], "%d", &result);
      ....
      }

  6. #6
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    inconvénient c'est que ce n'est pas un binaire mais un .so. C'est une technique Oracle pour lancer des ordres host : tu encapsules la commande system dans une procédure externe écrite en C.

    Possibilité 1 : pas d'accès disque (les admins système vont raler) et l'accès peut être concurrent.

    Possibilité 2 : pas possible avec le .so (du moins je pense)

    Merci pour votre aide. je vais en rester à mon cas : si <> 0 alors pas bon

  7. #7
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    euh....

    la sortie de ls n'EST PAS la sortie de system...

    la sortie de system est (voir le man page) en gros succès ou erreur.
    man system() :
    La valeur renvoyée est 127 si l'appel système execve() pour /bin/sh échoue, -1 si une autre erreur se produit, ou le code de retour de la commande sinon.

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    POSIX demande que le resultat de system soit la valeur retournee par waitpid. Donc il faut
    utiliser WIFEXITED et ses copains pour voir la cause de termination et WEXITSTATUS si WIFEXITED retourne qqch de non nul pour avoir le code retourne. (Il y a WIFSIGNALED et WTERMSIG quand la cause de termination est un signal).

  9. #9
    Membre Expert
    Avatar de Emmanuel Lecoester
    Profil pro
    Inscrit en
    Février 2003
    Messages
    1 493
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Février 2003
    Messages : 1 493
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    POSIX demande que le resultat de system soit la valeur retournee par waitpid. Donc il faut
    utiliser WIFEXITED et ses copains pour voir la cause de termination et WEXITSTATUS si WIFEXITED retourne qqch de non nul pour avoir le code retourne. (Il y a WIFSIGNALED et WTERMSIG quand la cause de termination est un signal).
    Tu aurais un lien ou encore mieux un exemple de réécriture de commande system ?

    j'ai trouvé çà mais çà me semble un peu lourd
    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
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    /* like system(), but executes the specified command as a background
     * job, returning the pid of the shell process (which is also the pgrp
     * of the job, suitable for kill_job etc.)
     * If INFD, OUTFD or ERRFD are non-NULL, then a pipe will be opened and
     * a descriptor for the parent end of the relevent pipe stored there.
     * If any of these are NULL, they will be redirected to /dev/null in the
     * child.
     * Also closes all FDs > 2 in the child process (an oft-overlooked task)
     */
     
    pid_t spawn_background_command(const char *cmd,
                                   int *infd, int *outfd, int *errfd)
    {
        int nullfd = -1;
        int pipefds[3][2];
        int error = 0;
     
        if (!cmd)
            return errno = EINVAL, -1;
     
        pipefds[0][0] = pipefds[0][1] = -1;
        pipefds[1][0] = pipefds[1][1] = -1;
        pipefds[2][0] = pipefds[2][1] = -1;
     
        if (infd && pipe(pipefds[0]) < 0)
            error = errno;
        else if (outfd && pipe(pipefds[1]) < 0)
            error = errno;
        else if (errfd && pipe(pipefds[2]) < 0)
            error = errno;
     
        if (!error && !(infd && outfd && errfd))
        {
            nullfd = open("/dev/null",O_RDWR);
            if (nullfd < 0)
                error = errno;
        }
     
        if (!error)
        {
            pid_t pid = spawn_job(0, -1);
            switch (pid)
            {
                case -1: /* fork failure */
                    error = errno;
                    break;
     
                case 0: /* child proc */
     
                    dup2(infd ? pipefds[0][0] : nullfd, 0);
                    dup2(outfd ? pipefds[1][1] : nullfd, 1);
                    dup2(errfd ? pipefds[2][1] : nullfd, 2);
                    closeall(3);
     
                    execl("/bin/sh","sh","-c",cmd,(char*)NULL);
     
                    _exit(127);
     
                default: /* parent proc */
     
                    close(nullfd);
                    if (infd)
                        close(pipefds[0][0]), *infd = pipefds[0][1];
                    if (outfd)
                        close(pipefds[1][1]), *outfd = pipefds[1][0];
                    if (errfd)
                        close(pipefds[2][1]), *errfd = pipefds[2][0];
     
                    return pid;
            }
        }
     
        /* only reached if error */
     
        {
            int i,j;
            for (i = 0; i < 3; ++i)
                for (j = 0; j < 2; ++j)
                    if (pipefds[i][j] >= 0)
                        close(pipefds[i][j]);
        }
     
        if (nullfd >= 0)
            close(nullfd);
     
        return errno = error, (pid_t) -1;
    }

  10. #10
    Expert confirmé

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nicolas.sitbon Voir le message
    man system() :
    man system (pas les man pages traduites, le vrai original )

    dit :

    RETURN VALUE
    If command is a null pointer, system() shall return non-zero to indicate that a command processor is avail-
    able, or zero if none is available. The system() function shall always return non-zero when command is NULL.

    If command is not a null pointer, system() shall return the termination status of the command language inter-
    preter
    in the format specified by waitpid(). The termination status shall be as defined for the sh utility;
    otherwise, the termination status is unspecified. If some error prevents the command language interpreter
    from executing after the child process is created, the return value from system() shall be as if the command
    language interpreter had terminated using exit(127) or _exit(127). If a child process cannot be created, or if
    the termination status for the command language interpreter cannot be obtained, system() shall return -1 and
    set errno to indicate the error.

    ERRORS
    The system() function may set errno values as described by fork() .

    In addition, system() may fail if:

    ECHILD The status of the child process created by system() is no longer available.

    The following sections are informative.

    EXAMPLES
    None.

    APPLICATION USAGE
    If the return value of system() is not -1, its value can be decoded through the use of the macros described in
    <sys/wait.h>. For convenience, these macros are also provided in <stdlib.h>.
    Mauvaise traduction...


    Pas le code de retour de la commande, le code de retour DU SHELL.

    Or, man sh donne :

    EXIT STATUS
    For the shell's purposes, a command which exits with a zero exit status has succeeded. An exit status of zero
    indicates success. A non-zero exit status indicates failure. When a command terminates on a fatal signal N,
    bash uses the value of 128+N as the exit status.

    If a command is not found, the child process created to execute it returns a status of 127. If a command is
    found but is not executable, the return status is 126.

    If a command fails because of an error during expansion or redirection, the exit status is greater than zero.

    Shell builtin commands return a status of 0 (true) if successful, and non-zero (false) if an error occurs
    while they execute. All builtins return an exit status of 2 to indicate incorrect usage.

    Bash itself returns the exit status of the last command executed, unless a syntax error occurs, in which case
    it exits with a non-zero value. See also the exit builtin command below.

    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    POSIX demande que le resultat de system soit la valeur retournee par waitpid. Donc il faut
    utiliser WIFEXITED et ses copains pour voir la cause de termination et WEXITSTATUS si WIFEXITED retourne qqch de non nul pour avoir le code retourne. (Il y a WIFSIGNALED et WTERMSIG quand la cause de termination est un signal).
    Non, c'est le FORMAT qui doit etre celui du waitpid. La VALEUR est normalement celle du retour de sh....

  11. #11
    Membre Expert Avatar de nicolas.sitbon
    Profil pro
    Inscrit en
    Août 2007
    Messages
    2 015
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 2 015
    Par défaut
    Ah oui effectivement autant pour moi, je viens aussi de vérifier dans le Stevens et :
    the return value from system() is the termination status of the shell, in the format specified for waitpid()
    Pour en revenir à cette erreur de traduction, elle est répercutée aussi dans l'ouvrage de Christophe Blaess, logique puisque c'est lui qui a le plus traduit les man pages.
    Merci pour ces précisions.

  12. #12
    Membre Expert
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Par défaut
    Citation Envoyé par souviron34 Voir le message
    Non, c'est le FORMAT qui doit etre celui du waitpid. La VALEUR est normalement celle du retour de sh....
    Ben oui, mais la valeur de retour de sh est celle de la derniere commande executee... Donc, a moins que sh n'ait pas pu demarrer, tu recuperes bien le retour de ta commande !
    Un exemple est toujours meilleur qu'un long discours:
    Un programme qui renvoit une valeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main(void)
    {
      return 42;
    }
    et un programme qui appelle celui au-dessus et affiche la valeur renvoyee:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/wait.h>
     
    int main(void)
    {
      int ret = system("./toto");
      printf("toto returned %d.\n", WEXITSTATUS(ret));
     
      return 0;
    }
    Ca me sort:
    toto returned 42.
    C'est un comportement conforme a POSIX, je pense.

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

Discussions similaires

  1. du bon usage de ONCLICK
    Par devboy dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 15/05/2007, 15h52
  2. Bon Usage : Constructeur ou Load
    Par gridin dans le forum VB.NET
    Réponses: 1
    Dernier message: 10/05/2007, 07h48
  3. [Delphi - Firebird] Comment faire bon usage des transactions?
    Par Lili21 dans le forum Connexion aux bases de données
    Réponses: 2
    Dernier message: 07/05/2007, 20h59
  4. Quel est le bon usage des fichiers "*.bpk" ?!
    Par bnadem35 dans le forum C++Builder
    Réponses: 3
    Dernier message: 12/09/2006, 17h31
  5. [xml] bon usage du xml
    Par Jeddo dans le forum XML/XSL et SOAP
    Réponses: 8
    Dernier message: 02/05/2005, 16h49

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