Linux 命令解释程序(shell)的模拟实现

发布时间:2024年01月11日

1.实验内容

分析、设计与实现基于 Linux 内核的命令解释程序(Shell),主要包括系统环境变量的设置和初始化、系统命令提示符显示、命令辨别解析(区分内部命令与外部命令及不同内部命令)、典型内部命令(譬如显示指定目录下文件列表、显示文本文件内容、文件拷贝、文件删除、空文件创建、日期设置/显示)处理等功能,并在 Linux 操作系统上测试验证。

2.程序设计思路

  1. 设计命令列表,这个shell实现了"ls", "cd", "env", "ps", "date", "echo", "help", "exit"八个命令:? ls -查看当前目录内容

??????????? cd [] -前往指定目录

??????????? env -查看环境变量

??????????? ps -查看当前进程

??????????? date -查看当前的时间

????? ??????echo [] -显示指定的内容后换行

??????????? help -帮助

??????????? exit -退出

  1. shell的输入口实现,设计用户名和获取当前路径
  2. while循环获取用户输入的命令,在命令列表中则进入对应的命令执行部分,部分通过系统调用实现,命令无效发出报错。
  3. 对于和终端中一致的命令C++可以直接调用 execlp 系统调用的方式来实现
  4. 程序使用父子进程来实现并行执行命令和避免阻塞。当用户输入的命令是 "ls"、"env" 、 "ps" 等命令时,父进程会创建一个子进程来执行相应的命令。子进程通过调用 execlp 函数来执行外部命令。程序不会在执行 execlp 函数期间停止等待,这样可以在命令执行期间进行其他操作。
  5. 设计了一个help列表来展示所有的命令和功能

3.完整程序?

#include <iostream>  
#include <string>  
#include <vector>  
#include <sys/types.h>  
#include <sys/wait.h>  
using namespace std;  

int main() {  
    vector<string> cmds={"ls", "cd", "env", "ps", "date", "echo", "help", "exit"};  
    string fp;  
    while(1) {  
        string now = "ljj@shell:" + string(getcwd(nullptr, 0)) + "> ";  
        printf("%s", now.c_str());  
        string cmd;  
        cin >> cmd;  
        string p;  
        bool valid = false;  
        int index = -1;  
        for (int i = 0; i < cmds.size(); i++) {  
            if (cmd == cmds[i]) {  
                valid = true;  
                index = i;  
            }  
        }  
        if (!valid) {  
            printf("No command! Input -help for more information\n");  
            continue;  
        }  
        else {  
            if(index < 5) {  
                // 使用父子进程使得程序可以同时执行多个命令并防止阻塞  
                pid_t pid;  
                pid = fork();  
                if (pid < 0) {  
                    fprintf(stderr, "Fork Failed");  
                    return 1;  
                }  
                else if (pid == 0) {  
                    if(index == 0) { //ls  
                        execlp("/bin/ls", "ls", NULL);  
                    }  
                    else if(index == 1) { //cd  
                        cin >> p;  
                        chdir(p.c_str());  
                    }  
                    else if(index == 2) { //env  
                        execlp("env", "", NULL);  
                    }  
                    else if(index == 3) { //ps  
                        execlp("ps", "", NULL);  
                    }  
                    else if(index == 4) { //time  
                        execlp("date", "", NULL);  
                    }  
                }  
                else {  
                    waitpid(pid, NULL, 0);  
                }  
            }  
            else {  
                if(index == 5) { //echo  
                    cin >> p;  
                    cout << p << endl;  
                }  
                else if(index == 6) { //help  
                    printf("Shell Commands List:\n\  
                    ls -查看当前目录内容\n\  
                    cd [] -前往指定目录\n\  
                    env -查看环境变量\n\  
                    ps -查看当前进程\n\  
                    date -查看当前的时间\n\  
                    echo [] -显示指定的内容后换行\n\  
                    help -帮助\n\  
                    exit -退出\n");  
                }  
                else return 0; // exit  
            }  
        }  
    }  
    return 0;  
}  

文章来源:https://blog.csdn.net/lijj0304/article/details/135528349
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。