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

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;  
}