如何进行shell重定向C

如何进行shell重定向C,c,C,我有一个标记器,它接收用户的输入。然后我继续扫描“>”或“s”: 替换父进程的stdin和stdout(在if(pid)中),并且不会影响子进程。将dup2stuff移到else分支,就在execvp之前,这是在C中执行重定向时应该使用的流 int file_stdin; int file_stdout; int file_stderr; /*-------------------------------------------------------------------- ; code

我有一个标记器,它接收用户的输入。然后我继续扫描“>”或“s”:


替换父进程的
stdin
stdout
(在
if(pid)
中),并且不会影响子进程。将
dup2
stuff移到
else
分支,就在
execvp
之前,这是在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);
}
int文件\u stdin;
int文件标准输出;
int文件\u stderr;
/*--------------------------------------------------------------------
; 设置infile和outfile的代码,我假设如果重定向不是
; 使用时,相应的文件句柄将为-1。
;
; 文件stdin应该是仅使用O rdu打开的文件。
; 文件stdout应该是仅使用O_wr打开的文件。
; 文件stdout应该是仅使用O_wr打开的文件。
;
; 小心使用为读写同时打开的文件描述符
; 并且使用相同的文件描述符——它可能不会做您想做的事情
; 希望它能做到。
;
; 另外请注意,您还可以使用pipe()系统中的文件描述符
; 调用(以允许在命令之间进行管道连接)或网络插座,或
; 可以从文件描述符读取/写入的任何内容。
;---------------------------------------------------------------------*/
pid_t儿童;
child=fork();
if(子级<0)
报告错误(错误号);
else if(子项>0)
{
智力状态;
int rc;
/*------------------------------------------------------------------
;等待子进程。需要向中添加更多代码
;描述符错误等等,但这只是一个练习
;读者
;-----------------------------------------------------------------*/
rc=等待(&状态);
}
其他的
{
/*--------------------------------------------------------------------
;子进程。如果需要,设置重定向。一旦重新重定向
;已设置(使用dup2()),原始文件描述符已关闭
;因为它不再需要,只会浪费数据库中的文件描述符
;子进程。
;-------------------------------------------------------------------*/
如果(文件标准>-1)
{
dup2(文件标准,标准文件编号);
关闭(文件\u stdin);
}
如果(文件\u stdout>-1)
{
dup2(文件标准,标准文件编号);
关闭(文件存储);
}
如果(文件\u stderr>-1)
{
dup2(文件号、文件号);
关闭(文件存储);
}
/*------------------------------------------------------------------
;在此处关闭所有不需要的打开文件。。。
;------------------------------------------------------------------*/
/*------------------------------------------------------------------
;需要用适当的值替换程序、ARGV和ENVP
;------------------------------------------------------------------*/
if(execve(程序、ARGV、环境)<0)
_退出(退出失败);
}

显然,上面的代码需要根据您的项目进行调整,但这是一般流程

您在哪个平台上编程?是否打印过“find<!!!!”?请给出一个程序执行的示例。find<!!!!printedIs“michaelguan326>”是由您的程序打印的还是OS X命令行提示符?我尝试按照您的建议执行,但没有任何更改。输出相同。
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
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 > !!!!!----------------------------------------------------
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);
}