0

我有一个接受用户输入的分词器。从那里我继续扫描“>”或“<”以寻找潜在的重定向。

for(i=0;i<n;i++){  //I/O redirection
        //printf("extracted token is %s\n",tokens[i]);

        //get the
        if (strcmp(tokens[i],"<")==0) {
            printf("found <  !!!!\n");

            if(tokens[i+1] == NULL){  //if there isn't a input file
                printf("Please have a input file\n");
                break;
            }else if(tokens[i-1] == NULL){ //if there isn't a output file
                printf("Pleae have a output file\n");
                break;
            }
            infile = 1;
            outfile = 1;

            fd=fopen(tokens[i-1],"w");
            fclose(fd);
        }
 }

上面的代码只处理“<”重定向。请注意,这只是围绕 while 循环(shell 设计)的一小段代码。在它通过这个for循环之后,我有这个:

for(i=0;i<n;i++){
        //printf("extracted token is %s\n",tokens[i]);
        char *ex = "exit";
        char *his = "history";

        if(strcmp(tokens[0],his) == 0 && max_cmd == 0 ){ //get history
            for(j=0;j<counter;j++){
                printf("%i. %s\n",j+1,historic_cmd[j]);         
            }

        }else if(strcmp(tokens[0], his) ==0 && max_cmd == 1){
            for(j=0; j<CMD_MAX;j++){
                printf("%i. %s\n",j+1,historic_cmd[j]);
            }
        }else if(strcmp(tokens[0],ex) == 0){ //exit program
            exit(2);
        }else{                      //forking
            pid = fork();
            if(pid){
                pid=wait(NULL);

                if(infile > 0)
                    dup2(fileno(fd),0);

                if(outfile > 0)
                    dup2(fileno(fd),1);

            }else{
                if(execvp(tokens[0],tokens)){
                    puts(strerror(errno));
                    exit(127);
                }

            }

        }




    } // end of for loop



}//end of while loop for user input

我对它为什么不执行重定向感到困惑。如果我输入以下内容:

ps > s

它在工作目录中创建文件 s,但它是空的。我是否错误地使用了“dup2”?

“ps > s”的示例输出:

user$>ps > s
ps: illegal option -- >
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
      [-u]
      [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
   ps [-L]
ps: illegal option -- >
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
      [-u]
      [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
   ps [-L]
ps: illegal option -- >
usage: ps [-AaCcEefhjlMmrSTvwXx] [-O fmt | -o fmt] [-G gid[,gid...]]
      [-u]
      [-p pid[,pid...]] [-t tty[,tty...]] [-U user[,user...]]
   ps [-L]
found > !!!!!----------------------------------------------------
4

2 回答 2

0

这是您应该用来在 C 中进行重定向的流程。

int file_stdin;
int file_stdout;
int file_stderr;

/*--------------------------------------------------------------------
; code to set infile and outfile I'll assume that if redirection isn't
; being used, the appropriate filehandle will be -1.
;
; file_stdin  should be a file that is opened using O_RDONLY.
; file_stdout should be a file that is opened using O_WRONLY.
; file_stdout should be a file that is opened using O_WRONLY.
;
; Be wary of using a file descriptor opened for both reading and writing
; and using the same file descriptor---it will probably not do what you
; expect it to do.
;
; Also note, you can also use file descriptors from the pipe() system
; call (to allow piping from command to command) or network sockets, or
; anything that can be read/written from a file descriptor.
;---------------------------------------------------------------------*/

pid_t child;

child = fork();
if (child < 0)
  report_error(errno);
else if (child > 0)
{
  int status;
  int rc;

  /*------------------------------------------------------------------
  ; wait for the child process.  More code needs to be added to
  ; descriptor errors and what not, but that's left as an exercise for
  ; the reader
  ;-----------------------------------------------------------------*/

  rc = wait(&status);
}
else
{
  /*--------------------------------------------------------------------
  ; child process.  Set up redirection if required.  Once the rediretion
  ; has been set (using dup2()), the original file descriptor is closed   
  ; as it is no longer needed and just wastes file descriptors in the   
  ; child process.
  ;-------------------------------------------------------------------*/

  if (file_stdin > -1)
  {
    dup2(file_stdin,STDIN_FILENO);
    close(file_stdin);
  }

  if (file_stdout > -1)
  {
    dup2(file_stdout,STDOUT_FILENO);
    close(file_stdout);
  }

  if (file_stderr > -1)
  {
    dup2(file_stderr,STDERR_FILENO);
    close(file_stderr);
  }

  /*------------------------------------------------------------------
  ; close any unneeded open files here ... 
  ;------------------------------------------------------------------*/

  /*------------------------------------------------------------------
  ; PROGRAM, ARGV and ENVP need to be replaced with appropriate values
  ;------------------------------------------------------------------*/

  if(execve(PROGRAM,ARGV,ENVP) < 0)
    _exit(EXIT_FAILURE);
}

显然,上面的代码需要适应您的项目,但这是一般流程。

于 2013-02-11T01:43:24.820 回答
0

您替换进程的stdinand (在 中),它不会影响您的孩子。将东西移到分支,就在.stdoutif(pid)dup2elseexecvp

于 2013-02-10T22:27:28.527 回答