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

这段代码实现了一个简单的命令行解析器,可以记录并执行用户输入的历史命令。程序使用二维指针数组存储历史命令,支持!!执行最近的命令,历史命令列表以及特定编号的历史命令。当历史记录满10条时,会覆盖最早的一条记录。
摘要由CSDN通过智能技术生成

思路:
首先将用户输入的命令存储到 一维指针数组 *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;

}

以后补充细节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值