2
votes

Différence entre exec, execvp, execl, execv?

J'écris un code qui représente un nouveau shell sous Linux. L'une des commandes que je souhaite prendre en charge consiste à exécuter un processus par exemple si j'obtiens la ligne suivante

commande [arguments]

Ensuite, je veux exécuter la commande en tant que processus jusqu'à ce qu'elle ait fini d'exécuter le processus.

Pour ce faire, je sais que je dois utiliser fork () afin d'obtenir le processus enfant et d'obtenir son PID, mon problème est que je ne sais pas quelle est la différence entre:

exec , execvp , execl , execv ... et je ne sais pas lequel utiliser et pourquoi.

Mon code actuel:

void External_Process(char *arguments[MAX_ARG], char* command)
{
    int pID;
    switch(pID = fork())
    {
    case -1:
        perror("fork failed");
        break;
    case 0 :
        setpgrp();

        //execv(command, arguments);
        //execvp(command, arguments);
        //execl("/bin/bash", "/bin/bash","-c",command,NULL);

        printf("smash error: > bad command %s\n" , command);
        exit(-1) ;

        break;

    default:
        return ;
    }
}

Merci!


3 Réponses :


0
votes

Essayez de lire le manuel: https://linux.die.net/man/3 / execv

Extrait:

Description La famille de fonctions exec () remplace la mémoire image actuelle par une nouvelle image processus. Les fonctions décrites dans cette page de manuel sont des interfaces pour execve (2). (Voir la page de manuel de execve (2) pour plus de détails sur le remplacement de la mémoire image actuelle.)

L'argument initial de ces fonctions est le nom d'un fichier à exécuter.

Le const char * arg et les ellipses suivantes dans les fonctions execl (), execlp () et execle () peuvent être considérés comme arg0, arg1, ..., argn. Ensemble, ils décrivent une liste d'un ou plusieurs pointeurs vers des chaînes terminées par NULL qui représentent la liste d'arguments disponible pour le programme exécuté. Le premier argument, par convention, doit pointer vers le nom de fichier associé au fichier en cours d'exécution. La liste des arguments doit être terminée par un pointeur NULL, et, comme ce sont des fonctions variadiques, ce pointeur doit être cast (char *) NULL.

Les fonctions execv (), execvp () et execvpe () fournissent un tableau de pointeurs vers des chaînes terminées par null qui représentent la liste d'arguments disponible pour le nouveau programme. Le premier argument, par convention, doit pointer vers le nom de fichier associé au fichier en cours d'exécution. Le tableau de pointeurs doit être terminé par un pointeur NULL.

Les fonctions execle () et execvpe () permettent à l'appelant de spécifier l'environnement du programme exécuté via l'argument envp. L'argument envp est un tableau de pointeurs vers des chaînes terminées par NULL et doit être terminé par un pointeur NULL. Les autres fonctions prennent l'environnement de la nouvelle image de process de la variable externe environ dans le processus appelant.

Sémantique spéciale pour execlp () et execvp ()

Les fonctions execlp (), execvp () et execvpe () dupliquent les actions du shell en recherchant un fichier exécutable si le nom de fichier spécifié ne contient pas de barre oblique (/). Le fichier est recherché dans la liste des chemins de répertoire séparés par deux-points spécifiés dans la variable d'environnement PATH. Si cette variable n'est pas définie, la liste des chemins par défaut est le répertoire courant suivi de la liste des répertoires renvoyée par confstr (_CS_PATH). (Cet appel confstr (3) renvoie généralement la valeur "/ bin: / usr / bin".)


0 commentaires

0
votes

En C, vous pouvez utiliser la commande 'system'. Ceci exécutera ce que vous entrez comme argument de fonction.

Voici un exemple:

system("ls -l");

Si vous voulez prendre la sortie, vous pouvez rediriger vers une autre source. p>


0 commentaires

3
votes

Résumé: Dans votre cas, je recommanderais d'utiliser execvp .

Pour connaître les différences entre les fonctions exec * , vous devriez lire la documentation:
https://linux.die.net/man/3/exec
https://linux.die.net/man/2/execve

La différence entre execl * et execv * est le passage d'argument. execl * nécessite une liste d'arguments tandis que execv * nécessite un vecteur d'arguments.
Une liste d'arguments est utile si vous connaissez tous les arguments au moment de la compilation. Dans votre cas, les arguments seront saisis par l'utilisateur et vous devez construire un vecteur d'arguments au moment de l'exécution, vous devez donc utiliser l'une des fonctions execv * .

Les fonctions avec le suffixe p utilisent la variable d'environnement PATH pour trouver le programme (par exemple "ls" ), sans cela vous devez spécifier le chemin complet (absolu ou relatif au répertoire courant, par exemple "/ bin / ls" ). Utiliser PATH est ce que font normalement les shells, donc cela semble être le bon choix pour vous.

Les fonctions avec le suffixe e permettent de spécifier l'environnement du processus. Pour simplifier, je n'utiliserais pas cela dans votre cas.

Ceci mène à la conclusion: execvp

Bien sûr, vous pouvez également utiliser system (au lieu de fork / exec * / wait * ) comme mentionné dans la réponse de vladxjohn, mais dans ce cas, vous utiliseriez simplement un shell pour interpréter votre commande au lieu d'implémenter un shell de base.


0 commentaires