【Linux】手把手教你做一个简易shell(命令行解释器)

简介: 【Linux】手把手教你做一个简易shell(命令行解释器)

> 作者简介:დ旧言~,目前大二,现在学习Java,c,c++,Python等

> 座右铭:松树千年终是朽,槿花一日自为荣。

> 目标:自己能写出一个简易shell(命令行解释器)

> 毒鸡汤:要让人觉得毫不费力,只能背后极其努力。

> 望小伙伴们点赞👍收藏✨加关注哟💕💕  



原理:

       shell是命令行解释器,当有命令需要执行时,shell创建子进程,让子进程执行命令,而shell只需等待子进程退出即可。



实现思路:

  • 获取命令行(fgets函数)。
  • 解析命令行(strtok分割字符串)。
  • 创建子进程(fork函数)。
  • 替换子进程(exec函数族)。
  • 等待子进程退出(waitpid函数)。


代码如下:

#include <stdio.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#define LEN 1024 //命令最大长度
#define NUM 32 //命令拆分后的最大个数
int main()
{
  char cmd[LEN]; //存储命令
  char* myargv[NUM]; //存储命令拆分后的结果
  char hostname[32]; //主机名
  char pwd[128]; //当前目录
  while (1){
    //获取命令提示信息
    struct passwd* pass = getpwuid(getuid());
    gethostname(hostname, sizeof(hostname)-1);
    getcwd(pwd, sizeof(pwd)-1);
    int len = strlen(pwd);
    char* p = pwd + len - 1;
    while (*p != '/'){
      p--;
    }
    p++;
    //打印命令提示信息
    printf("[%s@%s %s]$ ", pass->pw_name, hostname, p);
    //读取命令
    fgets(cmd, LEN, stdin);
    cmd[strlen(cmd) - 1] = '\0';
    //拆分命令
    myargv[0] = strtok(cmd, " ");
    int i = 1;
    while (myargv[i] = strtok(NULL, " ")){
      i++;
    }
    pid_t id = fork(); //创建子进程执行命令
    if (id == 0){
      //child
      execvp(myargv[0], myargv); //child进行程序替换
      exit(1); //替换失败的退出码设置为1
    }
    //shell
    int status = 0;
    pid_t ret = waitpid(id, &status, 0); //shell等待child退出
    if (ret > 0){
      printf("exit code:%d\n", WEXITSTATUS(status)); //打印child的退出码
    }
  }
  return 0;
}


运行结果:



说明:

当执行./myshell命令后,便是我们自己实现的shell在进行命令行解释,我们自己实现的shell在子进程退出后都打印了子进程的退出码,我们可以根据这一点来区分我们当前使用的是Linux操作系统的shell还是我们自己实现的shell。


🌟结束语

      今天内容就到这里啦,时间过得很快,大家沉下心来好好学习,会有一定的收获的,大家多多坚持,嘻嘻,成功路上注定孤独,因为坚持的人不多。那请大家举起自己的小手给博主一键三连,有你们的支持是我最大的动力💞💞💞,回见。


目录
相关文章
|
20天前
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
81 25
|
17天前
|
Linux Shell
shell_42:Linux参数移动
总的来说,参数移动是Linux shell脚本中的一个重要概念,掌握它可以帮助我们更好地处理和管理脚本中的参数。希望这个解释能帮助你理解和使用参数移动。
40 18
|
1月前
|
运维 安全 Linux
试试Linux设备命令行运维工具——Wowkey
WowKey 是一款专为 Linux 设备设计的命令行运维工具,提供自动化、批量化、标准化的运维解决方案。它简单易用、高效集成且无依赖,仅需 WIS 指令剧本文件、APT 账号密码文件和 wowkey 命令即可操作。通过分离鉴权与执行过程,WowKey 让运维人员专注于决策,摆脱繁琐的交互与执行工作,大幅提升运维效率与质量。无论是健康检查、数据采集还是配置更新,WowKey 都能助您轻松应对大规模设备运维挑战。立即从官方资源了解更多信息:https://atsight.top/training。
|
1月前
|
数据采集 运维 安全
Linux设备命令行运维工具WowKey问答
WowKey 是一款用于 Linux 设备运维的工具,可通过命令行手动或自动执行指令剧本,实现批量、标准化操作,如健康检查、数据采集、配置更新等。它简单易用,只需编写 WIS 指令剧本和 APT 帐号密码表文件,学习成本极低。支持不同流派的 Linux 系统,如 RHEL、Debian、SUSE 等,只要使用通用 Shell 命令即可通吃Linux设备。
|
3月前
|
Shell Linux
【linux】Shell脚本中basename和dirname的详细用法教程
本文详细介绍了Linux Shell脚本中 `basename`和 `dirname`命令的用法,包括去除路径信息、去除后缀、批量处理文件名和路径等。同时,通过文件备份和日志文件分离的实践应用,展示了这两个命令在实际脚本中的应用场景。希望本文能帮助您更好地理解和应用 `basename`和 `dirname`命令,提高Shell脚本编写的效率和灵活性。
172 32
|
3月前
|
缓存 Shell 开发工具
[oeasy]python064_命令行工作流的总结_vim_shell_python
本文总结了命令行工作流中的关键工具和操作,包括vim、shell和Python。主要内容如下: 1. **上次回顾**:完成了输入输出的代码编写,并再次练习了vim的使用。 2. **shell基础**:介绍了shell环境及其基本命令,如`pwd`、`cd`、`ll -l`等。 3. **Python游乐场**:通过`python3`命令进入Python交互环境,可以进行简单计算和函数调用,常用函数有`help`、`ord`、`chr`等。 4. **vim编辑器**:详细讲解了vim的三种模式(正常模式、插入模式、底行命令模式)及其切换方法,以及常用的底行命令如`:w`、`:q`、`
105 15
|
3月前
|
Ubuntu Shell Linux
Linux命令行解释器的模拟实现
Linux命令行解释器的模拟实现
|
6月前
|
人工智能 Shell iOS开发
AI Shell:在命令行里“对话” AI ,微软推出将 AI 助手引入命令行的 CLI 工具,打造对话式交互命令行
AI Shell 是一款强大的 CLI 工具,将人工智能直接集成到命令行中,帮助用户提高生产力。AI Shell 支持多种 AI 模型和助手,通过多代理框架提供丰富的功能和灵活的使用模式。
711 7
|
6月前
|
Ubuntu Linux 网络安全
linux系统ubuntu中在命令行中打开图形界面的文件夹
在Ubuntu系统中,通过命令行打开图形界面的文件夹是一个高效且实用的操作。无论是使用Nautilus、Dolphin还是Thunar,都可以根据具体桌面环境选择合适的文件管理器。通过上述命令和方法,可以简化日常工作,提高效率。同时,解决权限问题和图形界面问题也能确保操作的顺利进行。掌握这些技巧,可以使Linux操作更加便捷和灵活。
175 3
|
6月前
|
存储 Shell Linux
Linux 如何更改默认 Shell
Linux 如何更改默认 Shell
Linux 如何更改默认 Shell