【问题标题】:Input and output redirection in shellshell中的输入输出重定向
【发布时间】:2018-11-20 05:18:49
【问题描述】:

我正在尝试实现输入和输出重定向是 C。我阅读了这个问题的所有答案,但它不起作用!它转到最后一个 if (execvp)。

我想要这样的东西:

输出重定向:ls -al > output.txt

输入重定向:sort < input.txt

这是我写的代码:

int io_redirection(char * args[], char* inputFile, char* outputFile, int option){

    int err = -1;

    int fileDescriptor = -1; // between 0 and 19
    pid_t pid = -10;
    pid = fork();

    if(pid==-1){
        printf("Child process could not be created\n");
        return;
    }
    if(pid==0){
        // Option 0: output redirection
        if (option == 0){
            // I also tried fileDescriptor = creat(outputFile, 0644);
            fileDescriptor = open(outputFile, O_CREAT | O_TRUNC | O_WRONLY, 0600); 
            dup2(fileDescriptor, STDOUT_FILENO); 
            close(fileDescriptor);


        }
         else if (option == 1){
            // Option 1: input redirection

            fileDescriptor = open(inputFile, O_RDONLY, 0600);  
            dup2(fileDescriptor, STDIN_FILENO);
            close(fileDescriptor);

        }



        if (execvp(args[0],args)==err){
            printf("err");
            kill(getpid(),SIGTERM);
        }        
    }
    waitpid(pid,NULL,0);
}

对于输出重定向args 包含ls-al。对于输入,它包含sort

【问题讨论】:

  • 你不需要测试来自execvp()的返回值——如果它返回,它就失败了;如果成功,则不会返回。您似乎不允许 sort < input.txt > output.txt — 单个命令上的输入和输出重定向。
  • 没有A Minimal, Complete, and Verifiable Example (MCVE)很难说args处于什么状态?是否已经删除了包含 '<''>' 的元素和文件名,以便只保留其他参数?
  • @JonathanLeffler 不是这样,我在我的代码中多次使用这种方法(例如在pipe,它没有引起任何问题),此外我试图删除测试它的返回,但这样,它不会跳出循环。
  • @DavidC.Rankin 对于这个例子ls -al > output.txt:args 包含ls-al

标签: c shell io-redirection


【解决方案1】:

execvp 需要一个 NULL 作为最后一个参数。我猜你的命令综合忽略了这一点,其余的按预期工作。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/wait.h>


void print_child_status (int status) {
  if (WIFEXITED (status)) {
    fprintf (stdout, "Child exited with status %d\n", WEXITSTATUS (status));
  } else if (WIFSTOPPED (status)) {
    fprintf (stdout, "Child stopped by signal %d (%s)\n", WSTOPSIG (status), strsignal (WSTOPSIG (status)));
  } else if (WIFSIGNALED (status)) {
    fprintf (stdout, "Child killed by signal %d (%s)\n", WTERMSIG (status), strsignal (WTERMSIG (status)));
  } else {
    fprintf (stdout, "Unknown child status\n");
  }
}

int io_redirection(char * args[], char* inputFile, char* outputFile, int option){

    int err = -1;

    int fileDescriptor = -1; // between 0 and 19
    pid_t pid = -10;
    pid = fork();

    if(pid==-1){
        printf("Child process could not be created\n");
        return -1;
    }
    else if(pid == 0){
        // Option 0: output redirection
        if (option == 0){
            // I also tried fileDescriptor = creat(outputFile, 0644);
            fileDescriptor = open(outputFile, O_CREAT | O_TRUNC | O_WRONLY, 0600); 
            dup2(fileDescriptor, STDOUT_FILENO); 
            close(fileDescriptor);


        }
         else if (option == 1) {
            // Option 1: input redirection
            fileDescriptor = open(inputFile, O_RDONLY);
             printf("Input redirection %d\n", fileDescriptor);
            dup2(fileDescriptor, STDIN_FILENO);
            close(fileDescriptor);

        }
        err = execvp(args[0], args);

        if (err){
            printf("err %d\n", err);
        }
        return err;
    } else {
        int status;
        waitpid(pid, &status,0);
        print_child_status(status);
    }
    return 0;

}

int main() {
    char * args[] = {"ls", "-l", NULL};
    io_redirection(args, NULL, "out.txt", 0);
    char * args1[] = {"grep", "main", NULL};
    io_redirection(args1, "./test.c", NULL, 1);
    return 0;
}

【讨论】:

  • 但是对于输入重定向还是不行
  • 它对我有用,检查 open() 的状态,你可能引用了一个不存在的文件。
【解决方案2】:

可能你测试错了,我用下面code测试是对的。

int main() {
  char* argv[] = {"ls", "-al", NULL};
  io_redirection(argv, NULL, "test", 0);

  return 0;
}

【讨论】:

  • 是的,这是我的错误,我已经解决了。它适用于输出重定向,但不适用于输入重定向
  • 确保输入文件存在并且有足够的权限打开它,如何测试呢? @Setareh
猜你喜欢
  • 2016-03-10
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 2018-03-20
  • 1970-01-01
相关资源
最近更新 更多