C管道使用命令行参数

时间:2014-03-20 23:20:49

标签: c input fork output piping

我需要一些帮助来模仿“|” unix中的命令。我需要能够使用第一个参数的输出作为第二个参数的输入,就像ls和更多一样简单。到目前为止我得到了这个代码,但我只是坚持到这一点。任何和所有帮助都会有所帮助。谢谢。

#include <sys/types.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char ** words)
{ 
  char** args;
  char *cmd1[2] = { words[1], 0 };
  char *cmd2[2] = { words[2], 0 };
  int colon, arg1 ,i, pid, status;
  int thepipe[2];
  char ch;
  args = (char **) malloc(argc*(sizeof(char*)));
  colon = -1;
  for (i=0;(i<argc); i=i+1){
    if (strcmp(words[i],":") == 0) {
      colon = i;
    }
    else {}
  }
  pipe(thepipe);
  arg1 = colon;
  arg1 = arg1 - 1;
  for (i=0;(i<arg1); i=i+1){
    args[i] = (char*) (malloc(strlen(words[i+1])+1));
    strcpy(args[i], words[i+1]);
  }
  args[argc] = NULL;
  pid = fork();
  if (pid == 0) {
    wait(&pid);
    dup2(thepipe[1], 1);
    close(thepipe[0]);
    printf("in new\n");
    execvp(*args, cmd1); 
  }
  else {
    close(thepipe[1]);
    printf("in old\n");
    while ((status=read(thepipe[0],&ch,1)) > 0){
    execvp(*args, cmd2);
    }
  }

}

1 个答案:

答案 0 :(得分:1)

假设argv[1]是一个单词命令(如ls)而argv[2]是第二个单词命令(如more),那么:

  1. 创建一个管道。
  2. 叉第一个孩子。
  3. 分叉第二个孩子。
  4. 关闭管道的两端。
  5. 父母等待两个孩子死亡,报告退出状态并退出。
  6. 儿童1

    1. 将管道的写入结束复制到标准输出。
    2. 关闭管道的两端。
    3. 使用execvp()argv[1]中运行命令。
    4. 退出,​​可能是写入标准错误的错误消息(如果execvp()返回)。
    5. 儿童2

      1. 将读取管道末端复制到标准输入。
      2. 关闭管道的两端。
      3. 使用execvp()argv[2]中运行命令。
      4. 退出,​​可能是写入标准错误的错误消息(如果execvp()返回)。
      5. 唯一剩下的技巧是你需要创建一个矢量,如:

        char cmd1[2] = { argv[1], 0 };
        char cmd2[2] = { argv[2], 0 };
        

        作为第二个参数传递给execvp()


        请注意,此大纲不会破坏字符串。如果要处理调用,例如:

        ./execute "ls -la" "wc -wl"
        

        然后您需要将每个参数拆分为单独的单词,并为cmd1cmd2创建更大的数组。如果要处理两个以上的命令,则需要仔细考虑如何管理管道中的额外阶段。第一个和最后一个命令与中间命令不同(因此3个进程有三种不同的机制,但除了第一个和最后一个命令之外,4个或更多个命令基本上使用相同的机制)。