为了实现一个简单的 shell 命令行解释器,我们需要使用 C++ 进行编程,并使用 Linux 系统提供的系统调用,例如 fork()
、exec()
系列函数以及 waitpid()
。下面是一个简单的 shell 实现,支持基本的内部命令:
cd <目录>
:更改当前的工作目录。environ
:列出所有环境变量。echo <内容>
:显示 echo 后的内容。help
:显示 shell 的使用方法和基本功能。jobs
:显示当前的子进程。quit
,exit
,bye
:退出 shell。-
出现
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
-
#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; }