【问题标题】:Piping and redirecting in my own simple shell在我自己的简单外壳中进行管道和重定向
【发布时间】:2016-09-11 22:43:16
【问题描述】:

我已经编写了一个简单 shell 的开头,到目前为止 'ls' 工作正常。我为分叉和执行编写了这段代码。 但是,当我尝试使用重定向时,我收到错误“无法访问'>':没有这样的文件或目录。 如何让这些运算符这样读取?

int startProcess (StringArray sa)
{
  int pid; 
  int status;
  int fd1;
  int fd2; 
  int current_in;
  int current_out; 

  switch( pid = fork()){
 case -1://This is an error 
   perror("Failure of child.");
   return 1;
 case 0: // This is the child
   execvp(sa[0], sa);

   for (int i = 0; i < strlen(sa); i++){
     if (sa[i] == '|'){
     }
     if (sa[i] == '>'){
       fd1 = creat(sa[i-1], 0644);
       dup2(fd1, STDOUT_FILENO);
       close(fd1); 
     }
     if(sa[i] == '<'){
       fd2 = open(sa[i-1], O_RDONLY, 0);
       dup2(fd2, STDIN_FILENO);
       close(fd2);
     }
   }

   perror(sa[0]);
   printf("Could not execute '%s'\n", sa[0]);
   exit(1);
 default:// This is the parent 
   wait(&status);
   return (status == 0) ? 0: 1;
  }
}

【问题讨论】:

  • sa[i + 1]替换creatopen中的sa[i - 1]
  • 呃...你为什么要执行 before 设置重定向?
  • 在 sa 上调用 strlen 也意味着 sa 实际上是 char * ... 这没有多大意义。
  • 当然您需要将重定向“令牌”传递给您正在执行的程序。

标签: c shell redirect pipe fork


【解决方案1】:

请看一下这个重定向到文件的例子。

#include <zconf.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/wait.h>;

int startProcess(char *sa[]) {
    int pid;
    int status;
    int fd1;
    int fd2;
    int current_in;
    int current_out;
    switch (pid = fork()) {
        case -1://This is an error
            perror("Failure of child.");
            return 1;
        case 0: // This is the child
            fd2 = open("output", O_WRONLY | O_CREAT, 0666);
            dup2(fd2, STDOUT_FILENO);
            close(fd2);
            execvp(sa[0], sa);
            perror(sa[0]);
            printf("Could not execute '%s'\n", sa[0]);
            exit(1);
        default:// This is the parent
            wait(&status);
            return (status == 0) ? 0 : 1;
    }
}

int main(int argc, const char *argv[]) {

    char *ch[] = {"ls", "-l", NULL};
    startProcess(ch);
    return 0;
}

测试

dac@dac-Latitude-E7450 ~/C/twodec> ls
a.out*  CMakeLists.txt  data.txt  in2  integers.txt  main.c  target.txt
dac@dac-Latitude-E7450 ~/C/twodec> gcc main.c 
dac@dac-Latitude-E7450 ~/C/twodec> ./a.out 
dac@dac-Latitude-E7450 ~/C/twodec> ls
a.out*  CMakeLists.txt  data.txt  in2  integers.txt  main.c  output  target.txt
dac@dac-Latitude-E7450 ~/C/twodec> more output 
total 36
-rwxrwxr-x 1 dac dac 9104 sep 12 04:29 a.out
-rw-rw-r-- 1 dac dac  177 sep 11 17:56 CMakeLists.txt
-rw-rw-r-- 1 dac dac  336 sep 11 15:58 data.txt
-rw-rw-r-- 1 dac dac   44 jul 28 05:34 in2
-rw-rw-r-- 1 dac dac   99 sep 10 15:08 integers.txt
-rw-rw-r-- 1 dac dac 1351 sep 12 04:29 main.c
-rw-rw-r-- 1 dac dac    0 sep 12 04:29 output
-rw-rw-r-- 1 dac dac   74 jul  5 08:22 target.txt

【讨论】: