简体   繁体   English

C Bash Shell重定向

[英]C Bash Shell Redirection

I am new into programming in C. I am trying to implement a redirection feature into my program. 我是C语言编程的新手。我正在尝试在程序中实现重定向功能。

I have been working on this code for a while now and would really appreciate some new perspectives. 我已经在这段代码上工作了一段时间了,非常感谢一些新观点。

As i said earlier, I am working on adding the redirection feature that bash has (example : pwd > output.txt), the code is able to handle most of the basic functions, I have commented how I put it together. 正如我之前所说,我正在努力添加bash具有的重定向功能(例如:pwd> output.txt),该代码能够处理大多数基本功能,我评论了如何将其组合在一起。

My question(s) : 我的问题:

  1. Would creating a function that takes the user commands for redirection be something smart to write? 创建一个需要用户命令进行重定向的函数编写起来会很聪明吗? My code is pretty dirty(i'd appreciate any tips on cleaning ) 我的代码很脏(我很感谢任何清洁技巧)
  2. I assume that i'll be using strcmp again, searching for '<' in one control if and then '>' in the other, but I am not sure where exactly I should put the search (if I stay in the main, without creating a new function). 我假设我将再次使用strcmp,如果在一个控件中搜索“ <”,然后在另一个控件中搜索“>”,但我不确定应该将搜索放在哪里(如果我留在主控件中,创建一个新功能)。

I am currently hitting a brick wall, maybe it's because I have been at this all day, here is what my shell looks like now, thank you all. 我目前正在碰壁,也许是因为我整天都在这里,这是我的外壳现在的样子,谢谢大家。

#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

/* C based bash shell, working on creating redirects..*/
int main(int argc, char* argv[]){
    char cmnd[1024];  
    char* str1[100];        
    const char* str2 = "exit"; //string to compare for exit
    char* fullpath= "/bin/";//path set to bin
    char progpath[100];//complete file path
    const char* home = getenv("HOME");  //get home enviornment
    char directory[1024];
    char fileD[100];
    char* str3[100];
if(argc == 1)
    {
while(1){

    printf("dollar sign: "); 

    if(!fgets(cmnd, 1024, stdin))
        break;
    size_t length = strlen(cmnd);
    if (cmnd[length - 1] == '\n')
        cmnd[length - 1] = '\0';

     if(strcmp(cmnd, str2)==0){ //check if cmnd is exit
        break;
    }

    char *tkn; //split cmnd into separate strings
    tkn = strtok(cmnd," ");
    int i=0;
    while(tkn!=NULL){//until null is reached, break into tkns
        str1[i]=tkn;      
        tkn = strtok(NULL," ");
        i++;
    }
    str1[i]=NULL;  //last set to Null (EXECVP req)
    strcpy(progpath, fullpath); //copy string /bin/ to file path, for running
    if(strcmp(cmnd, "help")==0)//help line
    {
        printf("Enter bash cmnds, or 'exit' to exit\n");//if help is issued, ignore the rest
    } else if(strcmp(cmnd, "today")==0){//today doesn't exist, but "date" does. Replace today with date.
        strcat(progpath, "date");
    }else{
    strcat(progpath, str1[0]);//add program to path
    }

    for(i=0; i<strlen(progpath); i++){//delete newcmnd
        if(progpath[i]=='\n'){      
            progpath[i]='\0';
        }
    }//start fork
    int pid= fork();

    if(pid==0){//if child
    if(strcmp(str1[0],"cd") == 0)
    {
        int tempCmnd;
        if(!str1[1])
        {

            tempCmnd = chdir(getenv("HOME"));//for moving home
            if(tempCmnd == -1)
            {
                fprintf(stderr, "CD err.\n");
            }else{          
            getcwd(directory, sizeof(directory));
            printf("Currently in %s\n", directory);
            }
        }else{

            tempCmnd = chdir(str1[1]);
            if(tempCmnd == -1)
            {
                fprintf(stderr, "CD err.\n");
            }else{          
                getcwd(directory, sizeof(directory));
                printf("Move Success :  %s\n", directory);//pwd
            }
            }
        break;//(end child proc)
    }else{
        execvp(progpath,str1);
        if(strcmp(cmnd, "help")==0)//ignore the error if help is issued, otherwise standard error
        {
            //printf("Test")
        }
        else{fprintf(stderr, "Child process could not do execvp\n");}
    break;}
    }
    else{//Parent control
        wait(NULL);
    }
    }
}else{

    FILE * pfile;
    pfile = fopen(argv[1], "r" );
    if ( pfile == 0 )
    {
        printf( "Opening file failed\n" );
    }else{
        fgets(fileD, 100, pfile);//fget file into string
        fclose(pfile);//close

        char *tkn; //split pCommand by strtok
        tkn = strtok(fileD," ");
        int i=0;
        while(tkn!=NULL){//until null is reached, break into tkns
        str1[i]=tkn;      
        tkn = strtok(NULL," ");
        i++;
        }
        str1[i]=NULL; //end set to null
        strcpy(progpath, fullpath); //copy full path to program path
        strcat(progpath, str1[0]);//add cmnd to the path
        for(i=0; i<strlen(progpath); i++){// iterate to delete newcmnd
        if(progpath[i]=='\n'){      
            progpath[i]='\0';
        }
      }
        execvp(progpath,str1); //execvp with new string
    }
}
}

Yes, one way to put it together is by using strcmp() to find the character < . 是的,将其组合在一起的一种方法是使用strcmp()查找字符< You can get filename by splitting the string using strtok() or strchr() . 您可以使用strtok()strchr()分割字符串来获取文件名。 Then passing the contents of the file to the command as arguments. 然后将文件的内容作为参数传递给命令。

To redirect output: 要重定向输出:

Open a file descriptor, and use dup2(fd, 1) to write to open file descriptor. 打开文件描述符,然后使用dup2(fd, 1)进行写操作以打开文件描述符。

Or,use popen() to execute the command, and write output to file. 或者,使用popen()执行命令,然后将输出写入文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM