UNIX shell C исполнение по трубе - PullRequest
0 голосов
/ 20 октября 2011

Моя программа должна принимать данные из терминала и выполнять команду например: "ls" или "ls -l | wc"

{...}

//Split the command and store each string in parameter[]
    parameter[0] = malloc(255);                     //Allocate some space to the first element in the array
    cp = strtok(command, " ");                      //Get the initial string (the command)
    strncpy(parameter[0], cp, 50);
    for(i = 1; i < MAX_ARG; i++)
    {
        parameter[i] = malloc(255);
        cp = strtok(NULL, " ");                 //Check for each string in the array
        parameter[i] = cp;                      //Store the result string in an indexed off array
        if(strcmp(parameter[i], "|") == 0)
        {
            i = MAX_ARG;
            cp = strtok(NULL, " ");
            parameter2[0] = malloc(255);
            strncpy(parameter2[0], cp, 50);
            break;
        }
        if(parameter[i]  == NULL)
        {
            break;
        }
    }

    //Find the second set of commands and parameter
    //strncpy(parameter2[0], cp, 50);
    for (j = 1; j < MAX_ARG; j++)
    {
        parameter2[j] = malloc(255);
        cp = strtok(NULL, " ");
        parameter2[j] = cp;
    }

{...} // Это выполнение части команды и параметра:

if (proc1 ==  0)
        {
            close(fd[0]);                           //process1 doenst need to read from pipe
            close(STD_INPUT);                       //prepare for output
            dup(fd[1]);                             //Standard output = fd[1]
            close(fd[1]);
            execvp(parameter[0], parameter);        //Execute the process
        }


 else {
if (proc2 == 0)
            {
                close(fd[1]);
                close(STD_OUTPUT);
                dup(fd[0]);
                close(fd[0]);
                execvp(parameter2[0], parameter2);
            }
            //Parent process
            else
            {
            waitpid(-1, &status, 0);            //Wait for the child to be done
            }
   }

Я не уверен, что делаю неправильно, потому что, когда я ввожу "ls -l | wc", я получаю сообщение "| not found in directory"

1 Ответ

2 голосов
/ 20 октября 2011

Вы можете выполнить ls и wc напрямую с помощью execvp, но | является функцией вашей программы оболочки.Итак, что вам действительно нужно сделать, это запустить bash, а затем передать в качестве параметра вашу команду

execl("/bin/bash","-c",command);

Хотя это так тривиально, кажется, что вы действительно должны делать, это реализовывать оболочкусам.Для этого вам нужно будет выполнить какой-то синтаксический анализ, а не просто наивный токенинг со strtok.Если это задание, я надеюсь, что они дадут вам четкие инструкции о том, как это сделать, или, по крайней мере, какие виды команд оболочки вам нужно принять (возможно, просто конвейеры? Подоболочки?).Если вы просто пытаетесь реализовать это самостоятельно, я бы начал с чтения некоторых инструментов компилятора, таких как lex и yacc , которые могут помочь вам разобрать команды оболочки и выполнить их.

...