实现一个简单的 shell 命令行解释器

为了实现一个简单的 shell 命令行解释器,我们需要使用 C++ 进行编程,并使用 Linux 系统提供的系统调用,例如 fork()exec() 系列函数以及 waitpid()。下面是一个简单的 shell 实现,支持基本的内部命令:

  1. cd <目录>:更改当前的工作目录。
  2. environ:列出所有环境变量。
  3. echo <内容>:显示 echo 后的内容。
  4. help:显示 shell 的使用方法和基本功能。
  5. jobs:显示当前的子进程。
  6. quit, exit, bye:退出 shell。
  7. 出现 cc1plus 错误通常是因为编译器没有正确安装或配置。以下是解决这个问题的步骤:

    检查 g++ 是否安装

    首先,确保 g++ 已经安装。运行以下命令来检查:

    g++ --version

    如果 g++ 没有安装,可以使用以下命令来安装:

    在 Debian/Ubuntu 系统上

    sudo apt update sudo apt install g++

    在 Fedora 系统上

    sudo dnf install gcc-c++

    在 CentOS/RHEL 系统上

    sudo yum install gcc-c++

    验证编译器路径

    确保编译器路径在系统的 PATH 环境变量中。你可以运行以下命令来查看 g++ 的位置:

    which g++

    如果没有输出,说明 g++ 不在 PATH 中,可以手动将其添加到 PATH:

    export PATH=$PATH:/usr/bin/g++

    编译代码

    在确保 g++ 安装正确后,尝试重新编译代码:

    g++ -o mysh mysh.cpp

  8. #include <iostream>
    #include <vector>
    #include <string>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <sys/types.h>
    #include <cstring>
    #include <sstream>
    
    using namespace std;
    
    void printEnviron() {
        extern char **environ;
        for (int i = 0; environ[i] != nullptr; i++) {
            cout << environ[i] << endl;
        }
    }
    
    void executeCommand(vector<string>& args) {
        pid_t pid = fork();
        if (pid < 0) {
            perror("fork failed");
            return;
        }
        if (pid == 0) {
            vector<char*> c_args;
            for (auto& arg : args) {
                c_args.push_back(const_cast<char*>(arg.c_str()));
            }
            c_args.push_back(nullptr);
            if (execvp(c_args[0], c_args.data()) < 0) {
                perror("exec failed");
            }
            exit(1);
        } else {
            int status;
            waitpid(pid, &status, 0);
        }
    }
    
    void listJobs(vector<pid_t>& jobs) {
        for (size_t i = 0; i < jobs.size(); i++) {
            cout << "Job " << i + 1 << ": PID " << jobs[i] << endl;
        }
    }
    
    void changeDirectory(const string& path) {
        if (path.empty()) {
            char cwd[1024];
            if (getcwd(cwd, sizeof(cwd)) != nullptr) {
                cout << "Current directory: " << cwd << endl;
            } else {
                perror("getcwd failed");
            }
        } else {
            if (chdir(path.c_str()) < 0) {
                perror("chdir failed");
            }
        }
    }
    
    int main() {
        vector<pid_t> jobs;
        string input;
        
        while (true) {
            cout << "mysh> ";
            getline(cin, input);
    
            if (input.empty()) {
                continue;
            }
    
            vector<string> args;
            string arg;
            istringstream iss(input);
            while (iss >> arg) {
                args.push_back(arg);
            }
    
            if (args[0] == "quit" || args[0] == "exit" || args[0] == "bye") {
                break;
            } else if (args[0] == "cd") {
                if (args.size() > 1) {
                    changeDirectory(args[1]);
                } else {
                    changeDirectory("");
                }
            } else if (args[0] == "environ") {
                printEnviron();
            } else if (args[0] == "echo") {
                for (size_t i = 1; i < args.size(); i++) {
                    cout << args[i] << " ";
                }
                cout << endl;
            } else if (args[0] == "help") {
                cout << "Supported commands:" << endl;
                cout << "cd <dir> - change directory" << endl;
                cout << "environ - list all environment variables" << endl;
                cout << "echo <message> - print message" << endl;
                cout << "help - display help message" << endl;
                cout << "jobs - list current jobs" << endl;
                cout << "quit/exit/bye - exit the shell" << endl;
            } else if (args[0] == "jobs") {
                listJobs(jobs);
            } else {
                executeCommand(args);
            }
        }
        
        return 0;
    }
    

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值