Linux编程 实现一个简单的 shell(命令行解释器)

实验环境

操作系统:Ubuntu 16.04
编辑器:vim
编译器:gcc

需求说明

要设计的 shell 类似于 sh,bash,csh 等,必须支持以下内部命令:

  • cd <目录>更改当前的工作目录到另一个<目录>。如果<目录>未指定,输出当前工作目录。如
  • 果<目录>不存在,应当有适当的错误信息提示。这个命令应该也能改变 PWD 的环境变量。
  • environ 列出所有环境变量字符串的设置(类似于 Unix 系统下的 env 命令)。
  • echo <内容 > 显示 echo 后的内容且换行
  • help 简短概要的输出你的 shell 的使用方法和基本功能。
  • jobs 输出 shell 当前的一系列子进程,必须提供子进程的命名和 PID 号。
  • quit,exit,bye 退出 shell。

代码实现

// 简单的操作说明
// 编辑dai.c文件
vi dai.c
// 编译dai.c文件为dai.o
gcc dai.c -o dai.o
// 运行dai.o
./dai.o
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
    char cmd[100];
    while(1)
    {
        printf("dai > ");
        gets(cmd);
        int len=strlen(cmd);
        if(cmd[0] == 'e' && cmd[1] == 'c') // echo
        {
            int flag=0;
            for(int i=5; i<len; i++)
            {
                if(cmd[i]!=' ') flag=1;
                if(flag)
                {
                    putchar(cmd[i]);
                }
            }
            if(flag) putchar('\n');
        }
        else if(cmd[0]=='q' || cmd[1]=='x' || cmd[0]=='b') // quit,exit,bye
        {
            puts('Bye ~');
            return 0;
        }
        else if(cmd[0]=='h') // help
        {
            printf("/**********************************/\n");
            printf("echo <content>\tprint a line content\n");
            printf("quit,exit,bye\tend produce\n");
            printf("cd <catalog>\techo catalog\n");
            printf("jobs\techo process name and pid...\n");
            printf("environ\techo environment variable\n");
            printf("/**********************************/\n");
        }
        else
        {
            char cata[100];
            int cnt=0;
            if(cmd[0]=='c') // cd
            {
                int flag=0;
                for(int i=3; i<len; i++)
                {
                    if(cmd[i]!=' ') flag=1;
                    if(flag)
                    {
                        cata[cnt++] = cmd[i];
                    }
                }
                if(cnt==0)
                {
                    cata[0]='.';
                    cata[1]='\0';
                }
            }
            /* fork a child process */
            pid_t pid = fork();
            if (pid < 0)
            {
                /* error occurred */
                fprintf(stderr, "Fork Failed");
                return 1;
            }
            else if(pid==0)
            {
                if(cmd[0]=='c') // cd
                {
                    execlp("/bin/ls",cata,NULL);
                }
                else if(cmd[0]=='j') // jobs
                {
                    execlp("pstree","-p",NULL);
                }
                else if(cmd[0]=='e') // environ
                {
                    execlp("env","",NULL);
                }
            }
            else
            {
                /* wait wait,until child process exit*/
                wait();
            }
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/deaidai/article/details/80832863