【问题标题】:How to put input/output redirection in your newly-created c shell?如何将输入/输出重定向放在新创建的 c shell 中?
【发布时间】:2015-04-04 14:25:11
【问题描述】:

我想知道是否有人可以为我指出如何做到这一点的正确方向?比如我写“ls > contents.txt”,我希望ls的输出写到content.txt中。

这是我目前所拥有的。

 #include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <ctype.h>

void  parse(char *line, char **argv)
{
     while (*line != '\0') { 
          while (*line == ' ' || *line == '\t' || *line == '\n')
               *line++ = '\0';     
          *argv++ = line;          
          while (*line != '\0' && *line != ' ' && 
                 *line != '\t' && *line != '\n') 
               line++;            
     }
     *argv = '\0';               
}

void  execute(char **argv)
{
     pid_t  pid;
     int    status;

     if ((pid = fork()) < 0) {     
          printf("*** ERROR: forking child process failed\n");
          exit(1);
     }
     else if (pid == 0) {          
          if (execvp(*argv, argv) < 0) {     
               printf("*** ERROR: exec failed\n");
               exit(1);
          }

     }
     else {                                 
          while (wait(&status) != pid)      
               ;
     }
}
void main(char *envp[])
{
    char line[1024];
    char *argv[64];
    while (1){
      printf("shell>>");
      gets(line);
      printf("\n");
      parse(line, argv);
      if (strcmp(argv[0], "exit")==0)
    exit(0);
      execute(argv);
    }
}

【问题讨论】:

  • 这段代码块:'while (*line == ' ' || *line == '\t' || *line == '\n') *line++ = '\0'; '正在终止行[],因此解析函数将退出而不解析第一个参数以外的任何内容(在本例中为'ls')
  • 这一行:'void main(char envp[])' 不会在 linux 中干净地编译。建议:int main(int argc, char argv[], char *envp[])
  • 请注意,编写自己的 shell 可能涉及大量工作。例如,“ls *.gz >contents.txt”将无法按预期工作。当通过 exec 传递时,通配符将没有意义。即使您的目录中有很多 .xz 文件,它也会说“没有这样的文件 *.xz”,因为 ls 被要求逐字查找名为“*.xz”的文件 通常 shell 首先找到所有匹配的文件通配符,然后将它们作为参数传递给命令。大多数命令本身不知道如何扩展通配符。
  • 您对如何解析有其他建议吗?

标签: c linux shell io io-redirection


【解决方案1】:

在测试 pid==0 和运行 execvp() 之间,您需要这样的代码:

int fd=open(outputfile,O_WRONLY|O_CREAT); 
dup2(fd,1);

这实际上会将 execvp() 运行的程序的标准输出设置为这个新文件。您将不得不修改解析代码以查找“>”并将其后的内容解析为文件名并存储在 outputfile 中。 您还需要做一些额外的检查以确保新文件可以正常打开,等等。

【讨论】:

    【解决方案2】:

    您需要:

    • 在传递的命令中检查&gt; [filename]
    • 如果存在,则打开相关文件进行输出,并使用dup2 将您获得的 fd 附加到分叉进程的stdout

    这应该足以为您指明正确的方向。

    【讨论】:

      猜你喜欢
      • 2016-03-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-26
      • 1970-01-01
      • 2023-03-10
      • 1970-01-01
      • 2023-03-30
      相关资源
      最近更新 更多