【问题标题】:Losing control after execvp(grep)execvp(grep) 后失去控制
【发布时间】:2013-02-24 05:45:23
【问题描述】:

我正在尝试编写一个小程序来通过 execvp 运行 grep。这与我遇到的here 的问题基本相同,但在这种情况下,它仅在我运行 grep 时发生(与 echo、ls、emacs 等都正常工作相反)并且我更改了不正确的等待( ) (我相信)。我也尝试在我想查找的文本上使用引号

我的代码:

int main(void) {

  int i;
  char inputprogram[50];
  char vars[50] = "a search.txt";
  printf("input grep\n");
  fflush(stdout);
  fgets(inputprogram,50,stdin);
  for(i = 0; i < 50; i++){
            if(inputprogram [i] == '\n' ){
                inputprogram[i] = 0;
            }
        }
  char *arg [] = {inputprogram, vars , NULL};
  printf(">%s<\n", arg[1]);
  printf(">%s<\n", arg[0]);

  int status = 0;
  pid_t child;

  (child = fork());
  if(child == 0){
    printf("execute\n");
    execvp(inputprogram,  arg);
    exit(1);
  }
  else{
    printf("parent waiting...\n");
    wait(&status);
  }
  return EXIT_SUCCESS;
}

search.txt:

a
b
c
abc

输入/输出(# 在我输入的行前面,虽然不是输入的一部分):

shell> # ./work
input grep
# grep
>a search.txt<
>grep<
parent waiting...
execute
# a;dlghasdf
# go back
# :(

【问题讨论】:

    标签: c shell grep execvp


    【解决方案1】:

    函数 execvp 期望每个参数作为传入数组中的单独参数。您将“vars”作为单个参数传递,其中包含空格。 Grep 正在等待来自标准输入(此处为控制台)的输入,并正在搜索包含“a search.txt”的行。以下程序可以满足您的期望。

    #include "unistd.h"
    int main(void) 
    {
      char * executable = "grep";
      char *arg[] = { executable, "a","search.txt", NULL };
      execvp(executable, arg);
      return 0;
    }
    

    通过将搜索到的字符串作为自己的参数传递,grep 将列表中的下一个参数视为要搜索的文件。

    这是该程序为我所做的:

    ericu@eric-phenom-linux:~$ gcc -o execgrep /home/ericu/execgrep.c 
    ericu@eric-phenom-linux:~$ ./execgrep 
    a
    abc
    ericu@eric-phenom-linux:~$ cat search.txt 
    c
    b
    a
    abc
    ericu@eric-phenom-linux:~$ 
    

    修改示例程序以反映您当前正在执行的操作

    #include "unistd.h"
    int main(void) 
    {
       char * executable = "grep";
       char *arg[] = { executable, "a search.txt", NULL };
       execvp(executable, arg);
       return 0;
    }
    

    导致程序需要来自标准输入的输入。

    ericu@eric-phenom-linux:~$ echo -e "Review the man page from proper usage of execvp.a search.txt\nThis line does not show up in the output" | ./execgrep 
    Review the man page from proper usage of execvp.a search.txt
    ericu@eric-phenom-linux:~$ 
    

    【讨论】:

    • 谢谢,有没有我遗漏的次要问题?
    • Infelicities ——比如 for 循环从 fgets() 中找到换行符,或 (child = fork());exit(1);exit(1);exit(EXIT_SUCCESS) 周围的奇怪括号(不一致)——可能会被提及。如果execvp() 返回,最好报告错误。在arg[1] 之前打印arg[0] 会更传统,但这不是一个不可克服的问题。代码可能会记录来自wait() 的返回值,并且可能使用子进程的退出状态来控制自己的退出状态。否则,我看不出有任何问题。
    【解决方案2】:

    获得已启动应用的退出状态后

    wait(&status);
    

    解释它,使用 WIFEXITED 宏,

    if ( WIFEXITED (status) )
        printf("App exit status = %u ",WEXITSTATUS(status));
    }
    

    【讨论】:

      【解决方案3】:

      在处理输入/输出之前,请确保您的程序正常工作。这是一个重现错误的小程序:

      int main(void) 
      {
        char *arg[] = { "grep", "a search.txt", NULL };
        execvp("/bin/grep", arg);
        return EXIT_SUCCESS;
      }
      

      但是,如果没有arg 的第一个字符串,它似乎可以工作:

      int main(void) 
      {
        char *arg[] = { "a search.txt", NULL };
        execvp("/bin/grep", arg);
        return EXIT_SUCCESS;
      }
      

      但是,我不知道为什么它会依赖于argv[0] 的值。

      【讨论】:

        猜你喜欢
        • 2013-02-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-09
        • 2013-07-31
        • 1970-01-01
        相关资源
        最近更新 更多