简体   繁体   English

如何执行Shell重定向C

[英]How to do shell redirection C

I have a tokenizer that takes in input from the user. 我有一个分词器,可以接收用户的输入。 From there I went on to scan for ">" or "<" for potential redirection. 从那里继续扫描“>”或“ <”进行潜在的重定向。

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);
        }
 }

The above code just deals with "<" redirection. 上面的代码仅处理“ <”重定向。 Note that this is just a small snippet of the code that is wrapped around a while loop (shell design). 请注意,这只是包装在while循环中的一小段代码(shell设计)。 After it passes this for loop, I have this: 在通过此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

I am confused on why it isn't performing the redirection. 我对为什么它不执行重定向感到困惑。 If I type in the following: 如果输入以下内容:

ps > s

It creates the file s in the working directory, but its empty. 它在工作目录中创建文件,但为空。 Am I using "dup2" incorrectly? 我是否错误地使用了“ dup2”?

Sample output from "ps > s": 来自“ 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 > !!!!!----------------------------------------------------

You replace stdin and stdout of your parent process (within the if(pid) ), and it doesn't affect your child. 您替换进程的stdinstdout (在if(pid) ),这不会影响您的孩子。 Move dup2 stuff to the else branch, right before execvp . dup2内容移到execvp之前的else分支。

This is the flow you should be using to do redirection in C. 这是在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);
}

Obviously, the code above will need to be adapted to your project, but this is the general flow. 显然,上面的代码需要适应您的项目,但这只是一般流程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM