使用文本解释器和excel打印参数

时间:2014-05-10 14:38:30

标签: c unix

我正在尝试使用execl函数打印命令行参数,该函数执行文本解释器,但我无法打印第一个参数。

这是我的主要计划

    #include<unistd.h>
    #include<stdio.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<sys/stat.h>

   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))<0)
            perror("error in execl\n");

      if(waitpid(pid,NULL,0) !=pid)
          printf("error1\n");
      system("ls > list");
      return 0;
    }  

这是我的textinterpreter文件

      #!/home/chirag/echoarg1 my1

这是我的echoarg1.c文件

     #include<stdio.h>
     #include<unistd.h>
     #include<fcntl.h>
     #include<sys/types.h>
     #include<sys/stat.h>
    main(int argc,char *argv[])
    {
       int i;
       for(i=0;i<argc;i++)
           printf("argv[%d]=%s\n",i,argv[i]);
     }

我得到的输出是

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

预期输出

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

有人可以指出错误。

2 个答案:

答案 0 :(得分:0)

来自execl手册页:

  

INT   execl(const char * path,const char arg0,... / ,(char *)0 * /);

  

这些函数的初始参数是文件的路径名   将被执行。

     

execl(),execlp()中的const char * arg0和后续省略号,   和execle()函数可以被认为是arg0,arg1,...,argn。   它们一起描述了一个或多个指向null终止的指针的列表   表示执行程序可用的参数列表的字符串。按照惯例,第一个参数应指向文件名   与正在执行的文件相关联。参数列表必须是   由NULL指针终止。


所以在你的行中:

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

&#34; textinterpreter&#34;是要执行的文件的路径,但execl期望下一个参数arg0到&#34;指向与正在执行的文件关联的文件名&#34;。

换句话说,它应该看起来更像:

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

通常execl的前两个参数可能是相同的,但它允许您灵活地指定一个arg用于查找要执行的文件,另一个参数作为argv [0]传递。


作为实验,请尝试将execl更改为直接调用echoarg1,如下所示:

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

您应该看到如下输出:

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

在您的示例中,它似乎显示了&#34;这个&#34;而不是&#34; textinterpreter&#34;由于bash解释器如何处理你的&#34; textinterpreter&#34;脚本。 bash解释器似乎表现如下:

  • 接受hash-bang行并运行/home/chirag/echoarg1
  • 传递argv[0]=/home/chirag/echoarg1
  • 将其余的hashbang行传递给其他args(在本例中只是argv[1]=my1
  • 当它附加原始的argv列表时,它会出现使用可执行路径(&#34; textinterpreter&#34;)而不是实际的argv [0](&#34;这个&#34;)然后继续使用argv [ 1](&#34;是&#34;)和其他......

答案 1 :(得分:0)

它不是 bash解释器(不管是什么意思 - 这里没有涉及bash)丢弃arg0,但它是内核的函数{{ 3}}带语句

         retval = remove_arg_zero(bprm);
上面有一条评论说

          * Splice in (1) the interpreter's name for argv[0]
          *           (2) (optional) argument to interpreter
          *           (3) filename of shell script (replace argv[0])

- 在您的情况下,(1)/home/chirag/echoarg1,(2)my1,(3)textinterpreter(替换this)。