用于在shell中重定向输入和输出的代码

时间:2016-04-28 13:38:54

标签: c linux shell

我创建了一个shell程序,可以或多或少地执行普通的linux shell。我的程序可以正确地重定向输入或输出,但不能同时重定向输入或输出。到目前为止,任何在线解决方案都对我有用。

e.g。

 " echo hi kenny > kenny.txt "  works

 " cat in.txt | less "      works

但是,(假设in.txt是随机字母文件)

 " sort -u < in.txt > out.txt " does not work for  both, only for the input(<).

我的代码大致如下:

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

 readLine();

 if (lineHasSpecialSymbols()) {
    if(hasInput()){
       inRedirection();
    }else
      outRedirection();
 }

}

让我们假设这一切都需要。没有管道等。

readLine()从终端读取一行并将其保存在args []

lineHasSpecialSymbols()检测&#39;&lt;&#39;的第一个实例或者&#39;&gt;&#39;并返回。

这是inRedirection()如何工作的棘手部分:

void inRedirection(void) {
extractCommand("<");
int fd;
if ((pid = fork()) == -1) {
  perror("fork");
  exit(1);
}
if (pid == 0) {
  close(0);
  //open the file args2[0] and use it as standard input
  fd = open(args2[0], O_RDWR);
  execvp(args[0], args);
  perror("execv");
  exit(1);
}
if (pid != 0) {
  wait(NULL);
  printf("Done ");
  printf(args[0]);
  printf(".\n");
 }
}

outRedirection():

void outRedirection(void) {
extractCommand(">");
int fd;
if ((pid = fork()) == -1) {
  perror("fork");
  exit(1);
}
if (pid == 0) {
  close(1);
  fd = creat(args2[0], 0644);
  execvp(args[0], args);
  perror("execv");
  exit(1);
}
if (pid != 0) {
  wait(NULL);
  printf("Done ");
  printf(args[0]);
  printf(".\n");
 }
}

最后,extractCommand():

void extractCommand(char* symbol) {
int i;
int count = 0;
for (i = 0; args[i] != NULL; i++)
  if (!strcmp(args[i], symbol)) {
     args[i] = NULL;
     while (args[i+1] != NULL) {
           args2[count] = args[i+1];
           args[i+1] = NULL;
           i++;
           count++;
     }
  }
}

抱歉,对于巨大的代码。这就是问题所在:

我们说我输入命令:

&#34; sort -u&lt; in.txt&gt; out.txt&#34;

代码会检测到&#39;&lt;&#39;并将命令提取为两部分。

args[0] = "sort"   args2[0] = "in.txt"    args2[2] = "out.txt"
args[1] = "-u"     args2[1] = ">"

只有&#34;排序-u&lt; in.txt&#34;而不是其余的。我的问题是如何更改我的代码才能成为意图?另外,如何为两个以上的命令执行此操作?例如:&#34; ls -l / home / user | sort -u | wc -l&gt; in.txt&#34;

我已经想过一些算法,比如制作第三个args(args3),但是在更多这两个命令的情况下会发生碰撞。

1 个答案:

答案 0 :(得分:1)

我建议你改变你的方法。

int outRedirection(void) {
  int i;
  int j;
  for(i = 0; args[i] != NULL; i++) {
    // Look for the >
    if(args[i][0] == '>') {
      args[i] = NULL;
      // Get the filename
      if(args[i+1] != NULL) {
    output_filename[0] = args[i+1];
      } else {
    return -1;
      }
            //For- loop to make input AND output functional
           for(j = i; args[j-1] != NULL; j++) {
                        args[j] = args[j+2];
           }
      return 1;
    }
  }
  return 0;
}

对输入做同样的事情然后执行如下:

    void IOcommand(void){
    if ((pid = fork())== -1){
        perror("fork");
        exit(1);
    }if (pid == 0){

    if (input == 1)
        freopen(input_filename[0], "r", stdin);

    if (output == 1)
        freopen(output_filename[0], "w+", stdout);

        execvp(args[0],args);
        exit(-1);
 }
 if (pid != 0 ){
     wait(NULL);
     printf("Done ");
     printf(args[0]);
     printf(".\n");
 }
}