使用execlp的简单shell很奇怪

时间:2010-08-08 13:33:10

标签: c unix process exec fork

我正在阅读 GNU / Linux应用程序编程第2版,你可以从here读到正在读的内容。在我编写类似于他的代码之后,但它工作奇怪:< / p>

$ ./shell
./shell>>quit
$ ./shell
./shell>>date
Sun Aug  8 21:19:37 CST 2010
./shell>>quit
$ ./shell
./shell>>abc
execlp failed: No such file or directory
./shell>>quit
./shell>>quit
$./shell 
./shell>>abcd execlp
execlp failed: No such file or directory
./shell>>quit 
./shell>>quit

第一种和第二种情况都可以,但是第三种和第二种情况有点需要两次退出才能退出。这不是我所期待的。我猜错了 fork( ),或 waitpid(),但在询问我周围的几个人后,这仍然没有解决。现在是夏天的时候,即暑假,我没有更多的伙伴去寻找。永远感谢。

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define LINE_LEN 80

int main(int argc,char* argv[])
{

 pid_t pid;
 char cmd[LINE_LEN+1]={'\0'};

 while(1)
 {
  printf("%s>>",argv[0]);
  if(fgets(cmd,sizeof(cmd),stdin)==NULL)
  {
   perror("fgets failed");
   break;
  }
  cmd[strlen(cmd)-1]='\0';
  if(strncmp(cmd,"quit",4)==0)
  {
   break;
  }
  if((pid=fork())==-1)
  {
   perror("fork failed");
   break;
  }else if(pid==0)
  {
   //TODO no option can be specified for cmd
   execlp(cmd,cmd,NULL);
   perror("execlp failed");
  }else
  {
   waitpid(pid,NULL,0);
  }
 }
 return 0;
}

3 个答案:

答案 0 :(得分:3)

通常,如果execlp成功,您的子进程就会成为新进程,因此代码的执行会在此时停止。

现在execlp失败,你打印出错误,继续子进程,好像什么都没发生一样!你应该exit(0)孩子,如果{{1}失败。

答案 1 :(得分:0)

如果execlp不存在,

cmd将失败。

正如mvds正确地说,当execlp失败时,您应该退出子进程。但我建议在cmd不存在时不要分叉。

在使用access之前,您可以使用fork之类的内容(请参阅access(2))以确保cmd存在(在PATH内),并且可执行文件。

答案 2 :(得分:0)

只需发布调试版本即可明确:在哪个进程中调用strncmp,以及在子进程或父进程时调用

#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#define LINE_LEN 80

int main(int argc,char* argv[])
{

    pid_t pid;
    char cmd[LINE_LEN+1]={'\0'};

    while(1)
    {
        printf("%s>>",argv[0]);
        if(fgets(cmd,sizeof(cmd),stdin)==NULL)
        {
            perror("fgets failed");
            break;
        }
        cmd[strlen(cmd)-1]='\0';
        if(strncmp(cmd,"quit",4)==0)
        {
            printf("process :%d in strncmp equal\n",getpid());
            break;
        }
        if((pid=fork())==-1)
        {
            perror("fork failed");
            break;
        }else if(pid==0)
        {
            printf("new child:%d\n",getpid());
            //TODO no option can be specified for cmd
            execlp(cmd,cmd,NULL);
            perror("execlp failed");
            //This is critical
            //exit(0);
        }else
        {
            printf("parent:%d(his child is %d)\n",getpid(),pid);
            waitpid(pid,NULL,0);
        }
    }
    printf("process :%d exit...\n",getpid());
    return 0;
}

只看一个案例:

./shell
./shell>>abc
parent:8356(his child is 8357)
new child:8357
execlp failed: No such file or directory
./shell>>quit
process :8357 in strncmp equal
process :8357 exit...
./shell>>quit
process :8356 in strncmp equal
process :8356 exit...