欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

操作系统实验1实现简单的Shell(2020.10.6)

程序员文章站 2022-06-19 17:01:47
...

思路:
首先将用户输入的命令存储到 一维指针数组 *args[]中,整个args数组存储一条完整命令,并保存到二维指针数组 *str[][]中
然后通过循环数组,利用front 和rear实现记录最多十条的历史命令

源代码如下:



#include
<stdio.h>

#include <unistd.h>

#include <stdlib.h>

#include <string.h>

//the maximum length command

#define MAX_LINE 80

#define MAX_HIS 11



int main(void)

{

int should_run = 1;

char *args[MAX_LINE/2+1];//current command

char *str[MAX_HIS][MAX_LINE];// historical
command (whose maximun is 10 from 1 to 10)

int rear = 0;

int front = 0;

int sum = 0;//record the number of historical
commands at most 10

char judge[MAX_LINE];





    while(should_run){

    int label_w = 0;//decide whether to
wait

    int label_h = 0;//decide whether to
execute the history

    int label_hx = 0;//decide whether
to execute the !x

    int label_h0 = 0; //decide whether
to execute the !!

    printf("osh>");//print
the prompt

    fflush(stdout);//clear the output
buffer



    //get the args of the commmand one
line before the 'enter'        



    int i = 0;

    char x;

    do{        

        //get the args of the
commmand one line before the 'enter'

        args[i] =
malloc(MAX_LINE*sizeof(char));

        str[rear][i] =
malloc(MAX_LINE*sizeof(char));



        scanf("%s",
args[i]);

        strcpy(judge,
args[0]);



        if(0 == strcmp(judge,
"!!"))

        label_h0 = 1; 

        else if(0 ==
strcmp(judge, "history"))

        label_h = 1;  

        else if(judge[0] ==
'!' && judge[1] != '!')

        label_hx = 1;



        else

        strcpy(str[rear][i],
args[i]);

            

        x = getchar(); 
  

    ++i;    

    }while(x != '\n');

    //whether to rear++ and sum++

    if(label_h0 == 0 &&
label_hx == 0 && label_h == 0)

    {

        if((rear+1)%11 ==
front)//the special situation

        ++front;

        rear = (rear+1)%11;



        if(10 > sum) ++sum;

    }



    args[i] = NULL;

    str[rear][i] = NULL;

    //printf("sum = %d :\n",
sum);//test

    

    //judge whether the parent process
needs to wait

    if(0 == strcmp(args[i-1],
"&"))

    label_w = 1;







    //judge whether invoke the latest
command

    int irear = rear;//initial

    int ifront = front;

    if(1 == label_h0)

    {

    if(0 == sum) {printf("No
commands in history.\n"); continue;}



    //h0 

    int itest = 0;

    while(str[irear][itest] != NULL)

    {

    args[itest] = malloc(MAX_LINE*sizeof(char));//ready

    strcpy(args[itest], str[irear-1][itest]);//ready
for the execvp

    printf("%s ",
str[irear-1][itest]);

    ++itest;

    }

    printf("\n");

    args[itest] = NULL;//ready for the
execvp

    //h0

    }







    irear = rear;//initial

    ifront = front;

    //judge whether list the recent command
at most 10

    if(1 == label_h)

    {

    int count = 1;

    do{

    

    printf("%d: ", count++);

    

    //hcount

    int itest = 0;

    while(str[ifront][itest] != NULL)

    {

    printf("%s ",
str[ifront][itest]);

    ++itest;

    }

    printf("\n");

    //hcount

    ifront = (ifront+1)%MAX_HIS;

    }while(sum != count-1);

    }









    irear = rear;//initial

    ifront = front;

    //judge whether list the specific
number command

    if(1 == label_hx)

    {///



    int number = judge[1]-'0';



    if('1' == judge[1] 

    && '0' == judge[2] 

    && '\0' ==
judge[3])//special sutuation

    number = 10;

    else if('1' <= judge[2] 
&& '9' >= judge[2])

    number = 99;

    //printf("number = %d,
judge[2] = %c\n", number, judge[2]);



    int count = 1;

    do{

    //when the his is empty

    if(0 == sum) break;

    //when the his is empty



    if(count == number)

    {

        //hcount

        int itest = 0;

        while(str[ifront][itest]
!= NULL)

        {

        args[itest] =
malloc(MAX_LINE*sizeof(char));//ready

        strcpy(args[itest],
str[ifront][itest]);//ready for the execvp

        printf("%s
", str[ifront][itest]);

        ++itest;

        }

        printf("\n");

        args[itest] =
NULL;//ready for the execvp

        //hcount

        ++count;// easy to
ignore

        break;

    }

    ifront = (ifront+1)%MAX_HIS;



    ++count;

    }while(ifront != irear);



    if(count <= number)
{printf("No such command in history.\n");

    //printf("count = %d, number =
%d---for test---\n", count, number);

    continue;}

    }///





    //printf("sum = %d---for
test---\n", sum);



    //create the child process//

    pid_t pid = fork();

    if(0 == pid){

        if(0 != strcmp(judge,
"exit")

        && 1 !=
label_h

        )

        execvp(args[0], args);

        break;

    }

    else

    {    

        if(0 == label_w)

        wait(NULL);

        //the followings
aren't going until the child ends without"&"

        if(0 == strcmp(args[0],
"exit"))

        should_run = 0;

        fflush(stdin);

    }

    //create the child process//





    }



return 0;

}

以后补充细节

相关标签: 操作系统