execvp(grep)后丢失控制

时间:2013-03-08 15:59:13

标签: c shell grep execvp

我正在尝试编写一个程序来通过execvp运行grep。这与我here的问题基本相同,但在这种情况下,它只发生在我运行grep时(而不是echo,ls,emacs等都可以正常工作)并且我改变了错误wait()(我相信)。我也试过在我想找的文本上使用引号

我的代码:

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
# :(

3 个答案:

答案 0 :(得分: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:~$ 

答案 1 :(得分:0)

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

wait(&status);

使用WIFEXITED宏解释它,

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

答案 2 :(得分:0)

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

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]的价值。