C程序执行外壳管道和重定向

C程序执行外壳管道和重定向,c,shell,unix,redirect,piping,C,Shell,Unix,Redirect,Piping,这有点新鲜。我正在编写一个C程序,允许用户输入UNIX命令,例如 ls –la | wc -l and ls | head > file.txt 我已经实现了管道,并完成了少量重定向代码。目前,我只能执行像cat file1.txt>file2.txt这样的命令,或者以重定向结束的其他命令 如果我把这段注释掉,所有管道链都可以正常工作 char * srch; srch = strchr(cmd, '>'); *srch++ = '\0'; while(*srch

这有点新鲜。我正在编写一个C程序,允许用户输入UNIX命令,例如

ls –la | wc -l  and ls | head > file.txt
我已经实现了管道,并完成了少量重定向代码。目前,我只能执行像cat file1.txt>file2.txt这样的命令,或者以重定向结束的其他命令

如果我把这段注释掉,所有管道链都可以正常工作

  char * srch;
  srch = strchr(cmd, '>');
  *srch++ = '\0';
  while(*srch == ' ')
  {
      ++srch;
  }

  if(srch)
  {
    dup2(open(srch, O_RDWR|O_CREAT), STDOUT_FILENO);
  }
当我尝试将管道和重定向合并到同一个命令(如cmd1 p1 p2 p3file2)中时,就会出现问题。或者更简单的命令,如ls | head>file.txt

有人能帮我实现在同一个命令中添加重定向和管道的功能吗。我一直在努力,但我想不出来

以下是我目前掌握的情况:

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

/*get args function*/

#define MAXARGS 256
char ** getargs(char * cmd) {
    // assumes that cmd ends with NULL
    char** argsarray;
    int nargs = 0;
    int nlen = strlen(cmd);
    int i = 0;
    argsarray = (char**) malloc(sizeof(char*) * MAXARGS);
    argsarray[0] = strtok(cmd," ");
    i = 0;
    while (argsarray[i] != NULL){
        i++;
        argsarray[i] = strtok(NULL," ");
    }
    return argsarray;
}


int main(void){

  pid_t childpid;
  int fd[256][2];
  char cmd[256];
  char * sepCmd[256];
  char * pch;

  printf("Please enter a command sequence: \n");
  gets(cmd);
  //scanf("%s", cmd);
  printf("You have entered: %s \n", cmd);


  printf("Attempting to split up command: \n");
  pch = strtok (cmd, "|");


  //problems here...
  char * srch;
  srch = strchr(cmd, '>');
  *srch++ = '\0';
  while(*srch == ' ')
  {
      ++srch;
  }

  if(srch)
  {
    dup2(open(srch, O_RDWR|O_CREAT), STDOUT_FILENO);
  }




  int count = 0;  
    while (pch != NULL && count < 256) {
      printf("%s\n", pch);
      sepCmd[count] = pch;
      printf("The value in this array value is: %s\n", sepCmd[count]);
      pch = strtok (NULL, "|");
      count++;
  }

  char ** argue;
  int k;

  /* Block that deals with the first command given by the user */
  k = 0;
  pipe(fd[k]);
  if(!fork()) {
        dup2(fd[k][1], STDOUT_FILENO);
        close(fd[k][0]);
        argue = getargs(sepCmd[k]);
        execvp(argue[0], argue);
        perror(argue[0]);
        exit(0);
  }

  /*Loop that will control all other comands except the last*/
  for(k = 1; k <= count - 2; k++) {
      close(fd[k-1][1]);
      pipe(fd[k]);

      if(!fork()) {
          close(fd[k][0]);
          dup2(fd[k-1][0], STDIN_FILENO);
          dup2(fd[k][1], STDOUT_FILENO);
          argue = getargs(sepCmd[k]);
          execvp(argue[0], argue);
          perror(argue[0]);
          exit(0);
      }
  }


  /*Block that will take care of the last command in the sequence*/
  k = count - 1;

  //  if(reDir){
  //argue = getargs(sepCmd[k]);
  //open(argue[count], O_RDWR);

  //if(!fork()){
  //  close(fd[0]);
  //  close(fd[1]);
  //  dup2(fd[k-1][0], STDOUT_FILENO);
  //  execl("/bin/>", argue[count]);}
  //}
  //else{

  close(fd[k-1][1]);
  if(!fork()) {
      dup2(fd[k-1][0], STDIN_FILENO);
      argue = getargs(sepCmd[k]);
      execvp(argue[0], argue);
      perror(argue[0]);
      exit(0);
  }
  // }
  while(waitpid(-1, NULL, 0) != -1);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
/*获取args函数*/
#定义MAXARGS 256
char**getargs(char*cmd){
//假定cmd以NULL结尾
字符**argsarray;
int-nargs=0;
int-nlen=strlen(cmd);
int i=0;
argsarray=(char**)malloc(sizeof(char*)*MAXARGS);
argsarray[0]=strtok(cmd,“”);
i=0;
while(argsarray[i]!=NULL){
i++;
argsarray[i]=strtok(NULL,“”);
}
返回argsarray;
}
内部主(空){
pid_t childpid;
int fd[256][2];
char-cmd[256];
char*sepCmd[256];
char*pch;
printf(“请输入命令序列:\n”);
获取(cmd);
//scanf(“%s”,cmd);
printf(“您已输入:%s\n”,cmd);
printf(“正在尝试拆分命令:\n”);
pch=strtok(cmd,“|”);
//这里的问题。。。
char*srch;
srch=strchr(cmd,“>”);
*srch++='\0';
而(*srch=='')
{
++srch;
}
if(srch)
{
dup2(开放(srch,O|RDWR | O|u CREAT),标准文件号);
}
整数计数=0;
while(pch!=NULL&&count<256){
printf(“%s\n”,pch);
sepCmd[count]=pch;
printf(“此数组值中的值为:%s\n”,sepCmd[count]);
pch=strtok(空,“|”);
计数++;
}
争论;
int k;
/*处理用户发出的第一个命令的块*/
k=0;
管道(fd[k]);
如果(!fork()){
dup2(fd[k][1],标准文件号);
关闭(fd[k][0]);
argue=getargs(sepCmd[k]);
execvp(argue[0],argue);
perror(argue[0]);
出口(0);
}
/*将控制除最后一个命令外的所有其他命令的循环*/

for(k=1;k注释的代码是错误的。您正在查找'>'(
srch=strchr(cmd,'>'))
)在没有检查结果的情况下,使用“\0”终止预期结果。因此,当没有重定向时,用户会立即出现分段错误,并且当没有任何好的结果发生时。顺便说一句,我建议去掉
get
,因为它非常不受欢迎。编译时,您将得到函数“get”的
隐式声明关于实现的技巧,在谷歌上搜索会显示很多不错的结果,比如:或者你可以检查他们是如何做到的。

注释的代码是错误的。你正在寻找“>”(
srch=strchr(cmd,”>)
)在没有检查结果的情况下,使用“\0”终止预期结果。因此,当没有重定向时,用户会立即出现分段错误,并且当没有任何好的结果发生时。顺便说一句,我建议去掉
get
,因为它非常不受欢迎。编译时,您将得到函数“get”的
隐式声明g with
--std=gnu11
。至于实现技巧,在谷歌上搜索会显示很多不错的结果,比如:或者你可以看看他们是怎么做到的。

嘿-谢谢你的回复。这真的很有帮助。另外,谢谢你的链接。这些链接也真的帮助我了解了如何把它们放在一起。嘿-谢谢你的回复。真的很有帮助ped。另外,谢谢你的链接。这些链接还真的帮助我了解了如何把它们放在一起。