imprimer des documents en utilisant un interpréteur de texte et execl

J’essaie d’imprimer des arguments de ligne de commande en utilisant la fonction execl qui exécute un interpréteur de texte mais je ne peux pas imprimer le premier argument.

c’est mon programme principal

#include #include #include #include #include int main(int argc,char *argv[]) { pid_t pid; if((pid=fork())<0) printf("error\n"); else if(pid==0) if((execl("textinterpreter","this","is","usp","lab",(char*)0)) list"); return 0; } 

Ceci est mon fichier texte

  #!/home/chirag/echoarg1 my1 

Ceci est mon fichier echoarg1.c

  #include #include #include #include #include main(int argc,char *argv[]) { int i; for(i=0;i<argc;i++) printf("argv[%d]=%s\n",i,argv[i]); } 

La sortie que je reçois est

  argv[0]=/home/chirag/echoarg1 argv[1]=my1 argv[2]=textinterpreter argv[3]=is argv[4]=usp argv[5]=lab 

Où est le résultat attendu?

  argv[0]=/home/chirag/echoarg1 argv[1]=my1 argv[2]=textinterpreter argv[3]=this argv[4]=is argv[5]=usp argv[6]=lab 

Quelqu’un peut-il s’il vous plaît signaler l’erreur.

à partir de la page de manuel execl:

int execl (const char * path, const char arg0, … / , (char *) 0 * /);

et

L’argument initial de ces fonctions est le chemin d’access d’un fichier à exécuter.

Le const char * arg0 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 de plusieurs pointeurs vers des chaînes terminées par un caractère nul qui représentent la liste d’arguments disponible pour le programme exécuté. Le premier argument, par convention, doit indiquer le nom de fichier associé au fichier en cours d’exécution. La liste des arguments doit être terminée par un pointeur NULL.


alors dans votre ligne:

  if((execl("textinterpreter","this","is","usp","lab",(char*)0))<0) 

"textinterpreter" est le chemin du fichier à exécuter, mais execl attend le prochain argument, arg0 , pour "pointer sur le nom de fichier associé au fichier en cours d'exécution".

en d'autres termes, il devrait ressembler davantage à:

  if((execl("textinterpreter","textinterpreter","this","is","usp","lab",(char*)0))<0) 

Habituellement, les deux premiers arguments à exécuter seraient les mêmes, mais vous avez la possibilité de spécifier un argument pour trouver le fichier à exécuter et un autre argument à transmettre comme argv [0].


Comme expérience, essayez de modifier votre execl pour appeler echoarg1 directement comme ceci:

 if((execl("echoarg1","FAKEPATH","this","is","usp","lab",(char*)0))<0) 

Vous devriez voir la sortie comme:

 argv[0]=FAKEPATH argv[1]=this argv[2]=is argv[3]=usp argv[4]=lab 

Dans votre exemple, il apparaît qu’il affiche "this" au lieu de "textinterpreter" en raison de la façon dont l’interprète bash gère votre script "textinterpreter". L'interpréteur bash semble agir comme suit:

  • prend la ligne de hash-bang et exécute /home/chirag/echoarg1
  • passe-le argv[0]=/home/chirag/echoarg1
  • passer le rest de la ligne de hachage sous la forme d'arguments supplémentaires (dans ce cas, juste argv[1]=my1 )
  • comme il ajoute la liste d'argv originale, il apparaît qu'il utilise le chemin exécutable ("textinterpreter") au lieu de l'argv [0] réel ("this") et continue ensuite avec argv [1] ("is") et le rest ...

Ce n’est pas l’interpréteur bash (peu importe ce que cela est censé signifier – il n’y a pas de bash impliqué ici) qui rejette arg0 , mais c’est la fonction load_script() du kernel avec l’instruction

  retval = remove_arg_zero(bprm); 

au-dessus il y a un commentaire disant

           * Splice dans (1) le nom de l'interpréteur pour argv [0]
           * (2) (optionnel) argument à l'interprète
           * (3) nom de fichier du script shell (remplacez argv [0])

– dans votre cas, (1) /home/chirag/echoarg1 , (2) my1 , (3) textinterpreter (remplacez this ).