Utiliser execv (langage C) pour exécuter des commandes à partir d’une invite de commande linux

La seule partie sur laquelle je suis confus jusqu’à présent est de savoir comment configurer execv avec le premier paramètre comme répertoire de travail actuel. J’ai essayé les deux “.” et “~” n’exécutent rien à l’écran; pareil pour “/.” et “/ ~”. Je suis confus sur la façon dont execv exécuter quelque chose comme ça:
$ ./prog ls -t -al

Et le faire exécuter les commandes après l’exécution du programme (qui sont stockées dans argv) dans le répertoire en cours, ou dans le même répertoire que le fichier (qui variera en fonction de l’utilisateur).

Mon code:

#include  #include  #include  #include  void main(int argc, char *argv[]) { int pid; int count = 0; char *argv2[argc+1]; for(count = 0; count < argc-1; count++){ argv2[count] = argv[count+1]; printf("Argv2: %s\n", argv2[count]); //just double checking argv2[argc-1] = NULL; } pid = fork(); if(pid == 0){ printf("Child's PID is %d. Parent's PID is %d\n", (int)getpid, (int)getppid()); execv(".", argv2); //<---- confused here } else{ wait(pid); exit(0); } } 

Quelques exemples de sortie:
$ ./prog ls -t -al
Argv2: ls
Argv2: -t
Argv2: -al
La PID de l’enfant est 19194. La PID du parent est 19193

Je suppose que execv est ce qui doit être utilisé. execvp est beaucoup plus agréable car il va chercher des commandes dans votre paramètre PATH.

 execv(".", argv2); //<---- confused here 

...

 #include  #include  if ( execv(argv2[0],argv2) ) { printf("execv failed with error %d %s\n",errno,strerror(errno)); return 254; } 

 wait(pid); 

...

 pid_t wait_status = wait(&pid); 

Le premier argument, par convention, doit indiquer le nom de fichier associé au fichier en cours d’exécution. Vous voulez exécuter ls , donc le premier argument devrait être /bin/ls , cela signifie que le code est

 execv("/bin/ls", argv2); 

Vous pourriez l’essayer

 /* main() returns int */ int main(int argc, char *argv[]) { int pid; pid = fork(); if(pid == 0){ printf("Child's PID is %d. Parent's PID is %d\n" , (int)getpid, (int)getppid()); execv(argv[1], argv+1); } else{ wait(NULL); exit(0); } return 0; } 

UPDATE: execv () a besoin du chemin absolu de l’exécutable; pour les fichiers dans le répertoire en cours, vous devrez construire ce chemin (par exemple via pwd ()). Si vous voulez que l’exécutable soit recherché via la variable d’environnement $ PATH, vous pouvez utiliser execvp (), qui effectue toutes les recherches pour vous.

Le premier argument à execv () n’est pas le répertoire dans lequel exécuter mais le chemin du fichier à exécuter. Par défaut, votre programme exec-ed s’exécutera dans le contexte du répertoire actuel de l’appelant.

Le premier argument est le chemin absolu du programme que vous souhaitez exécuter; en d’autres termes, la première partie de la commande que vous tapez dans un terminal. Vous pouvez trouver où le programme en utilisant la commande whereis . De plus, execv fonction execv peut rechercher le chemin pour vous, ce qui rend votre code plus portable.

Échantillon de code pour votre référence:

 #include  int main() { int ret = fork(); if(ret == 0) { char *params[4] = {"/bin/ls", "-l",0}; //cmd params filled int res = execv( "/bin/ls" , params); //parameters for cmd //int res = execv( "/bin/ls" , NULL); //this is fail case (when child-exit with -1 status can be seen) printf("\n child exiting (%d) .. \n", res); //on successful execution of cmd, this exit never appears } else { waitpid(ret,1,0); printf("parent exiting\n"); } return 1; }