UNIX shell I / O重定向

时间:2017-04-13 16:13:50

标签: c linux

我正在尝试在C中实现LINUX shell但是当我尝试运行这样的命令时:sort -u < in.txt > out.txt它说:sort: cannot read: '<': No such file or directory。我也尝试了其他命令,如ls -l > out.txt等,但它一直在告诉我同样的事情。这是我的代码:

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


#define LENGTH 1024

int main(){
char line[LENGTH];
char* argv[100];
char* path= "/bin/";
char fullPath[30];
int option;
char* inputFile;
char* outputFile;   

while(1){

    printf("mysh3>");

    if(!fgets(line,LENGTH,stdin)){
        break;
    }

    size_t length = strlen(line);
    if(line[length-1]=='\n')
        line[length-1] = '\0';

}

char* token; 
token = strtok(line," ");
int i = 0;
while(token!=NULL){
    argv[i]=token;
    token = strtok(NULL," ");
    i++;
}

if(argv[1]==">"){
    option=1;
    outputFile=argv[2];
}
else if(argv[2]==">"){
    option = 1;
    outputFile=argv[3];
}
else if(argv[1]=="<" && argv[3]==">"){
    option=2;
    inputFile=argv[2];
    outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">"){
    option=2;
    inputFile=argv[3];
    outputFile=argv[5];
}
else if(argv[1]=="<" && argv[3]==">>"){
    option=3;
    inputFile=argv[2];
    outputFile=argv[4];
}
else if(argv[2]=="<" && argv[4]==">>"){
    option=3;
    inputFile=argv[3];
    outputFile=argv[5];
}


argv[i]=NULL;

strcpy(fullPath, path);
strcat(fullPath, argv[0]);

for(int i = 0; i < strlen(fullPath); i++){  
    if(fullPath[i]=='\n'){
        fullPath[i]='\0';
    }
}

int ret=forkEx2(argv,inputFile,outputFile,fullPath,option);
if(ret==-1) {
    return -1;
}

int forkEx2(char* argv[],char* inputFile,char* outputFile,char 
fullPath[],int option){
int fd;
pid_t pid,waitPid;
pid = fork();
if(pid<0){
    perror("ERROR: Fork failed.\n");
    return -1;
}
else if(pid==0){
    if(option==1){
        fd=open(outputFile,O_CREAT | O_TRUNC |  O_WRONLY, 0600);  //if the file does not exist the system create it. Clear all data from the file. Open the file for write only.Store its file descriptor in fd

        dup2(fd,STDOUT_FILENO);  //replace the standar out with the file
        close(fd);
    }
    else if(option==2){
        fd=open(inputFile,O_RDONLY,0600);  //open the file for read only

        dup2(fd,STDIN_FILENO);  //replace the standar in with the file
        close(fd);

        fd=open(outputFile,O_CREAT | O_TRUNC |  O_WRONLY, 0600);  //if the file does not exist the system create it. Clear all data from the file. Open the file for write only

        dup2(fd,STDOUT_FILENO);  //replace the standar out with the file
        close(fd);
    }
    else if(option==3){
        fd=open(inputFile,O_RDONLY,0600);  //open the file for read only

        dup2(fd,STDIN_FILENO);  //replace the standar in with the file
        close(fd);

        fd=open(outputFile, O_APPEND | O_WRONLY, 0600);  //append at the end of the file. Open the file for write only

        dup2(fd,STDOUT_FILENO);  //replace the standar out with the file
        close(fd);
    }

    execvp(fullPath,argv);
    perror("ERROR: Child should never arrive here.\n");

}

else{
    waitPid = wait(&waitPid);
    if (waitPid == -1) {
        perror("ERROR: Waitpid failed.\n");
        return -1;
    }

    printf("Parent: Finished pid %d.\n", waitPid);
}
}                   

}

感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

让我们来看看这个案例(在所有情况下都是一样的):

else if(argv[2]=="<" && argv[4]==">"){
    option=2;
    inputFile=argv[3];
    outputFile=argv[5];
}

首先,您使用==比较字符串:这不起作用。您必须使用strcmp或者您正在比较指针。

然后,您正在提取输入文件&amp;输出文件可以,但您忘记从argv中删除重定向参数。您必须将它们过滤掉(每次遇到一个重定向参数时,通过移动参数数组的其余部分)

除此之外:您应该初始化argv数组,否则如果没有足够的参数,您可能会遇到未定义的行为。