C shell中的输入和输出重定向

C shell中的输入和输出重定向,c,shell,io-redirection,C,Shell,Io Redirection,我正在尝试用C实现输入和输出重定向。我阅读了这个问题的所有答案,但它不起作用!它转到最后一个if(execvp) 我想要这样的东西: 输出重定向:ls-al>output.txt 输入重定向:sort

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

我想要这样的东西:

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

输入重定向:
sort

以下是我编写的代码:

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
。对于包含排序的输入,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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
无效打印子项状态(int状态){
如果(妻子退出(状态)){
fprintf(stdout,“子项已退出,状态为%d\n”,WEXITSTATUS(状态));
}否则如果(WIFSTOPED(状态)){
fprintf(stdout,“被信号%d(%s)\n)停止的子级”,WSTOPSIG(状态),strsignal(WSTOPSIG(状态));
}否则如果(WIFSIGNALED(状态)){
fprintf(stdout,“被信号%d(%s)\n)杀死的子级”,WTERMSIG(状态),strsignal(WTERMSIG(状态));
}否则{
fprintf(stdout,“未知子状态”\n);
}
}
int io_重定向(char*args[],char*inputFile,char*outputFile,int选项){
int err=-1;
int fileDescriptor=-1;//介于0和19之间
pid_t pid=-10;
pid=fork();
如果(pid==-1){
printf(“无法创建子进程\n”);
返回-1;
}
否则如果(pid==0){
//选项0:输出重定向
如果(选项==0){
//我还尝试了fileDescriptor=creat(outputFile,0644);
fileDescriptor=open(outputFile,O|u CREAT | O|u TRUNC | O|u WRONLY,0600);
dup2(文件描述符,标准输出文件号);
关闭(文件描述符);
}
否则如果(选项==1){
//选项1:输入重定向
fileDescriptor=打开(仅输入文件);
printf(“输入重定向%d\n”,文件描述符);
dup2(文件描述符,标准文件号);
关闭(文件描述符);
}
err=execvp(args[0],args);
如果(错误){
printf(“错误%d\n”,错误);
}
返回错误;
}否则{
智力状态;
waitpid(pid和status,0);
打印子项状态(状态);
}
返回0;
}
int main(){
char*args[]={“ls”,“-l”,NULL};
io_重定向(args,NULL,“out.txt”,0);
char*args1[]={“grep”,“main”,NULL};
io_重定向(args1,“./test.c”,NULL,1);
返回0;
}

也许你的测试错了,我用下面的
code
测试是对的

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

  return 0;
}

您不需要测试
execvp()
中的返回值-如果返回,则失败;如果成功,它就不会返回。您似乎不允许在单个命令上进行
排序output.txt
——输入和输出重定向。如果不这样做,很难说
args
处于什么状态?持有
'
的元素和文件名是否已被删除,以便只剩下额外的参数?@JonathanLeffler并非如此,我在我的代码中多次使用了这种方法(例如在
管道中,它没有引起任何问题),此外,我尝试删除对其返回的测试,但以这种方式,它没有跳出循环。@DavidC.Rankin对于这个例子
ls-al>output.txt
:args包含
ls
-al
,但它仍然不适用于输入重定向它适用于我,检查open()的状态,你可能引用了一个不存在的文件。是的,这是我的错误,我修复了它。它适用于输出重定向,但不适用于输入重定向确保输入文件存在并且有足够的权限打开它,以及如何测试它@塞塔雷