1

<、>、>>、|、& の任意の組み合わせを受け入れるミニ シェルを C で実装しようとしています。コマンドを読み取り、ファイルのリダイレクトなどを実行する場所に持っていますが、上記のコマンドの組み合わせを受け入れるようにプログラムする方法について、Google で適切なチュートリアルを見つけることができないようです。私がこれまでに持っているコードは次のとおりです(組み合わせのために試したものを削除しましたが、それを行う方法がわからず、混乱していました)(一部の非標準関数は、使用しているライブラリからのものです。 ):

int main(int argc, char **argv)
{
int i,j,frv,status,x,fd1;
IS is;
is = new_inputstruct(NULL);

/* read each line of input */
while (get_line(is) >= 0)
{
    if (is->NF != 0)
    {

        /*fork off a new process to execute the command specified */
        frv = fork();
        /* if this is the child process, execute the desired command */
        if (frv == 0)
        {
            if (strcmp(is->fields[is->NF-1],"&") == 0) is->fields[is->NF-1] = NULL;
            while (is->fields[frv] != NULL)
            {
                /* if we see <, make the next file standard input */
                if (strcmp(is->fields[frv],"<") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1], O_RDONLY);
                    dup2(fd1, 0);
                    close(fd1);

                }
                /* if we see >, make the next file standard output and create/truncate it if needed */
                else if (strcmp(is->fields[frv],">") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1],O_TRUNC | O_WRONLY | O_CREAT, 0666);
                    dup2(fd1, 1);
                    close(fd1);

                }
                /* if we see >>, make the next file standard output and create/append it if needed */
                else if (strcmp(is->fields[frv],">>") == 0)
                {
                    is->fields[frv] = NULL;
                    fd1 = open(is->fields[frv+1], O_WRONLY | O_APPEND | O_CREAT, 0666);
                    dup2(fd1, 1);
                    close(fd1);

                }
                frv++;
            }
            /* execute the command */
            status = execvp(is->fields[0], is->fields);
            if (status == -1)
            {
                perror(is->fields[0]);
                exit(1);
            }
        }
        /* if this is parent process, check if need to wait or not */
        else
        {
            if (strcmp(is->fields[is->NF-1],"&") != 0) while(wait(&status) != frv);
        }
        /* clean up the values */
        for(j = 0; j < is->NF; j++) is->fields[j] = NULL;
    }
}
return 0;
}
4

1 に答える 1

0

最初に入力コマンドをトークン化する必要があります。

トークンは、意味を持つ 1 つまたは複数の記号の集まりです。

たとえば&|>>><はトークンです。

レクサーの作成を開始する方法については、こちらをご覧ください(それほど複雑ではありません)。

おそらく、コンパイラ構築のいくつかの基本も役立つでしょう。

于 2013-04-11T06:48:47.733 に答える