使用C在Linux Shell中重定向输入和输出

时间:2019-05-22 05:50:25

标签: c linux

嗨,我一直在用c编写外壳程序,尝试重定向时被卡住了。

shell命令有效,但是重定向不起作用,它给我“无法创建输出文件!:无效的参数”,与输入相同。

我想要这样的东西:

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

输入重定向:cat < out.txt&

myprog < myfile > theoutput

这是我编写的代码:

#include "command_line.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/errno.h>
#include <signal.h>
#include <sys/wait.h>

#define MAX_LINE_LENGTH 512
#define MAXARGS 512


extern char ** environ;

void unix_error(char * msg);
pid_t Fork(void);
int cdHandler(char ** argv);
void childHandler(int sig);

void exithandler(int sig) {}


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

    //silently reap children
    struct sigaction sa;
    sa.sa_handler = & childHandler;
    sigemptyset( & sa.sa_mask);
    sa.sa_flags = SA_RESTART;
    if (sigaction(SIGCHLD, & sa, 0) == -1) {
        perror(0);
        exit(1);
    }

    signal(SIGINT, exithandler);
    //kill foreground processes without killing shell

    char cmdline[MAX_LINE_LENGTH];
    struct CommandLine command;

    for (;;) {
        printf("> ");
        fgets(cmdline, MAX_LINE_LENGTH, stdin);

        if (feof(stdin)) {
            printf("exit");
            exit(0);
        }

        bool gotLine = parseLine( & command, cmdline);

        //pid_t pid = Fork();
        int stat;

        if (gotLine) {
            if (command.arguments[0] == NULL) {
                return;
            }

            if (!cdHandler(command.arguments)) {
                //child runs user job
                pid_t pid = Fork();

                if (pid == 0) {
                    printCommand( & command);
                    char * com[MAX_ARGS];
                    int i = 0;
                    for (; i < command.argCount; i++) {
                        if (strcmp(command.arguments[i], ">") != 0 && strcmp(command.arguments[i], "<") != 0) {
                            com[i] = command.arguments[i];

                        } else if (strcmp(command.arguments[i], ">") == 0) {
                            char * filename = command.arguments[i + 1];
                            printf("-----%s------  \n", filename);
                            int outputfileptr = open(command.arguments[i + 1], "w+");

                            if (outputfileptr == -1)

                            {
                                perror("Cannot create output file!");
                                return;
                            }
                            dup2(outputfileptr, 1);
                            close(outputfileptr);
                            i++;
                        } else if (strcmp(command.arguments[i], "<") == 0) {
                            char * filename = command.arguments[i + 1];
                            int inputfileptr = open(filename, "r");

                            if (inputfileptr == -1) {
                                perror("Input file does not exist!");
                                return;
                            }
                            // Run dup2 again to redirect input/output
                            dup2(inputfileptr, 0);
                            close(inputfileptr);
                            i++;
                        }

                    }
                    printf("%s /n", com[0]);

                    if (execvp(command.arguments[0], command.arguments) < 0) {
                        printf("There was a Command error \n");
                        exit(0);
                    }
                } else {
                    //parent
                    if (!command.background)
                        waitpid(pid, & stat, WUNTRACED);
                }
            }
        }
    }

    return;

    printCommand( & command);
    freeCommand( & command);
}

//error handling for fork method

pid_t Fork(void) {
    pid_t pid = 0;
    if ((pid = fork()) < 0) {
        unix_error("fork error");
    }
    return pid;
}

//prints out message is an error to address error occured

void unix_error(char * msg) {
    fprintf(stderr, "%s : %s\n", msg, strerror(errno));
    exit(0);
}

int cdHandler(char ** argv) {
    if (!strcmp(argv[0], "cd")) {
        if (chdir(argv[1]) != 0)
            perror("cd did not change directory");
        return 1;
    }
    if (!strcmp(argv[0], "exit"))
        exit(0);
    return 0;
}

void childHandler(int sig) {
    int ps;
    int saved_errno = errno;
    while (waitpid((pid_t)(-1), & ps, WNOHANG) > 0) {

        if (WIFEXITED(ps)) {
            printf("Exit status: %d\n", WEXITSTATUS(ps));
        } else if (WTERMSIG(ps)) {

            printf("Exit signal: %d\n", WTERMSIG(ps));
        }
    }
    errno = saved_errno;
}

0 个答案:

没有答案