1、linux中实现命令的两种方式

1.1、命令都是单独的可执行程序

aston:~$ ls -l /bin/ls
-rwxr-xr-x 1 root root 138208  2鏈 8  2022 /bin/ls
aston:~$
aston:~$ ls -l /bin/mkdir
-rwxr-xr-x 1 root root 68096  2鏈 8  2022 /bin/mkdir
aston:~$
aston:~$ file /bin/ls
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=897f49cafa98c11d63e619e7e40352f855249c13, for GNU/Linux 3.2.0, stripped

(1)在linux的根文件系统中,系统自带的命令放在"/bin、/sbin"目录中,用户的命令放在"/usr/bin、/usr/sbin"目录中;
(2)用"ls -l"可知每个命令都是二进制文件,用"file"命令查看可知每个命令都是可执行文件;
(3)命令都是单独的可执行程序,这种方式一般都是Ubuntu、Centos、服务器的linux系统采用,部署在硬件资源比较充足的设备里;

1.2、命令是指向busybox的符号链接

(1)用"ls -l"可知每个命令都是符号链接,指向busybox;
(2)这种方式一般是嵌入式设备采用;

1.3、两种实现方式的对比

(1)每个命令都是单独的可执行程序:这种方式要求的资源更多,但是命令支持的功能也更丰富;
(2)用符号链接和busybox实现命令:busybox占用的空间明显小于所有单独命令可执行程序占用空间之和,节省更多的资源,但是busybox的命令都是裁剪过的,只支持命令中常用的选项;
(3)busybox适合嵌入式设备,支持必要的命令,而且占用的空间小,嵌入式设备flash和内存一般都不富裕;
(4)命令是单独可执行程序的方式:更适合在电脑、服务器上运行的linux系统,flash和内存等硬件资源都比较充裕,更注重性能和命令的完整;

2、busybox介绍

2.1、为什么需要busybox

(1)busybox集成了常用的所有命令,可以很方便的构建文件系统。假设现在要构建文件系统,如果没有busybox,则需要去下载"ls、cd、mkdir······"每个命令的源码再编译,工作量很大且很繁琐;
(2)busybox高度可裁剪,需要支持什么命令就配置busybox编译哪些命令的源码,有效减小busybox的体积,节省空间;

2.2、busybox的源码获取

官网地址:www.busybox.net

2.3、busybox的两种使用方式

(1)符号链接:建立符号链接指向busybox,为每个命令建立一个符号链接;
(2)直接调用busybox,比如:"busybox ls"的效果和直接执行"ls"命令是相同的;

3、C语言实现简易版busybox

3.1、源码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//计算数组的成员个数
#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))//实现ls命令功能
int my_ls_main(int argc, char * argv[])
{char bufCmd[256] = {0};sprintf(bufCmd, "ls %s", argv[1]);system(bufCmd);return 0;
}//实现mkdir命令功能
int my_mkdir_main(int argc, char * argv[])
{char bufCmd[256] = {0};sprintf(bufCmd, "mkdir %s", argv[1]);system(bufCmd);return 0;
}//busybox的说明函数
int my_help_main(int argc, char * argv[])
{printf("busybox only support commond:ls and mkdir\n");return 0;
}//支持的命令列表
const char *applet_names[] =
{"my_ls",
"my_mkdir",
"--help",
"-h"
};//每个命令对应的实现函数,顺序要和applet_names数组的顺序一一对应
int (*const applet_main[])(int argc, char * argv[]) =
{my_ls_main,    my_mkdir_main,my_help_main,my_help_main,
};int main(int argc, char * argv[])
{int i = 0;char *cmdBuf = malloc(256);int start_index = 0;memset(cmdBuf, 0, sizeof(cmdBuf));//打印接收到的命令
#if 0while(i < argc){printf("argv[%d] = %s \n", i, argv[i]);i++;}
#endif//如果是直接调用的busybox需要特殊处理if(strcmp(argv[0], "my_busybox") == 0){start_index = 1;}//在支持的命令列表里查找是否支持该命令for(i = 0; i < ARRAY_SIZE(applet_names); i++){if (strcmp(argv[start_index], applet_names[i]) == 0){applet_main[i](argc, argv);break;}}//查找不到输入的命令则不支持该命令if(i == ARRAY_SIZE(applet_names)){printf("command not found\n");return -1;}return 0;
}

3.2、代码的编译和使用

[root#]$ ls -l
total 16
-rwxr-xr-x 1 310793 domain_users 8352 Nov 15 16:25 my_busybox
lrwxrwxrwx 1 310793 domain_users   10 Nov 15 16:25 my_ls -> my_busybox
lrwxrwxrwx 1 310793 domain_users   10 Nov 15 16:26 my_mkdir -> my_busybox
-rwxrw---- 1 310793 domain_users 1857 Nov 15 16:31 test.c

(1)为了避免与系统中的busybox冲突,将可执行程序命名为my_busybox;
(2)本简易版busybox仅支持ls和mkdir命令,所以创建my_ls和my_mkdir命令执行my_busybox;
(3)将代码所在目录导出到环境变量PATH中,可以自动查找到刚才构建的命令(export PATH=命令所在路径:$PATH);

3.3、代码执行效果

[310793@yanfa204_ubuntu18-jk128:weops 222]$ gcc test.c -o my_busybox
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_mkdir 112233
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_ls ./
112233  my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox my_ls ./
112233  my_busybox  my_ls  my_mkdir  test.c
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox -h
busybox only support commond:ls and mkdir
[310793@yanfa204_ubuntu18-jk128:weops 222]$
[310793@yanfa204_ubuntu18-jk128:weops 222]$ my_busybox --help
busybox only support commond:ls and mkdir

4、busybox实现框架分析

(1)busybox是个可执行程序,程序入口是main函数,在appletlib.c文件中;
(2)在main中只是实现逻辑控制,并不执行具体的功能,会把输入的指令进行解析,查找指令对应的函数去执行;
(3)在代码中有两个重要的数组,applet_main是函数指针数组,里面是每个命令对应的函数的函数指针,applet_names是保存的命令的字符串,两个数组的元素是一一对应的;
(4)将传递进来的命令先和applet_names数组进行比对,如果匹配上就拿数组下标去applet_main数组取的命令对应的函数并执行;
(5)每个命令都有对应的函数,比如:ls对应"ls_main"函数,cd命令对应"cd_main"函数;

推荐

再难的项目都是基础知识的复杂运用,基础是最重要的。给大家推荐一个学校嵌入式知识的网站,博主在大学时候学习嵌入式知识、找工作的时候都在用这个网站,网站里有C语言、Linux等等的笔试题、面试常问问题等等知识,无论是学习基础知识、面试刷题、交流工作经验都是不错的选择。大家一起进步,欢迎留言交流。
链接:学习神器跳转

busybox的实现原理分析(C语言实现简易版的busybox)相关推荐

  1. c语言小游戏 精简_C语言开发简易版扫雷小游戏

    C 语言开发简易版扫雷小游戏 本文给大家分享的是一个使用 C 语言开发的命令行下的简易版扫雷小游戏, 本身没有什么太 多的技术含量, 只不过是笔者的处女作, 所以还是推荐给大家, 希望对大家学习 C ...

  2. Java 语言实现简易版扫码登录

    基本介绍 相信大家对二维码都不陌生,生活中到处充斥着扫码登录的场景,如登录网页版微信.支付宝等.最近学习了一下扫码登录的原理,感觉蛮有趣的,于是自己实现了一个简易版扫码登录的 Demo,以此记录一下学 ...

  3. c语言程序设计中三子棋游戏,C语言实现简易版三子棋游戏

    本文实例为大家共享了C语言实现三子棋游戏的详细代码,供大家参考,详细内容如下 什么是多文件? 多数大型的工程的头文件和源文件非常多,我们也不可能把所有的代码都写在同一个文件里,这样也不方便代码的阅读与 ...

  4. 用JavaScript语言制作简易版轮播图

    //代码示例如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...

  5. 【C语言】简易版_飞机小游戏

    目录 前言 正文 一.利用scanf控制飞机移动 二.getch控制飞机移动 三.显示复杂的飞机图案 四.发射激光 五.打靶练习 写在最后 前言 在前面弹跳小球 的基础上实现一个简单的飞机游戏,主要包 ...

  6. 【C语言】简易版扫雷游戏(play game)

    目录 扫雷游戏

  7. 【C语言】简易版_反弹小球游戏

    目录 前言 正文 一.显示静止的小球 二.小球下落 三.上下弹跳的小球 四.斜着弹跳的小球 五.控制小球弹跳的速度 六.完整代码 写在最后 前言 我们利用printf 函数实现一个在屏幕上弹跳的小球, ...

  8. C语言实现简易版的扫雷游戏

    目录 在正式讲内容之前先说一说扫雷游戏的规则 首先看一下test.c: 接下来是game.h: 接下来是game.c: 在正式讲内容之前先说一说扫雷游戏的规则 游戏规则很简单,点击方格,如果是地雷,游 ...

  9. 利用计算机语言实现ID3算法,机器学习之决策树学习-id3算法-原理分析及c语言代码实现.pdf...

    机器学习之决策树学习-id3算法-原理分析及c语言代码实现.pdf 还剩 23页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保 ...

最新文章

  1. CCNP张SIR的视频教程(完全可以下载)
  2. GitHub 五万星登顶,命令行的艺术!
  3. php 7.1.5,Centos 7平滑无缝更新PHP7.1.0到PHP 7.1.5
  4. VS直接调试可执行文件main函数.exe输入参数argc(项目--> 属性--> 调试--> 命令参数)
  5. Android学习笔记(三)
  6. mapreduce 算法_MapReduce算法–顺序反转
  7. HDU2501_多米诺骨牌
  8. 3dmax里面cr材质转换vr材质_3DMAX零基础入门视频全套教程
  9. 状态模式(Unity中使用)
  10. android 声音突然变小,手机明明没坏,为什么声音开到最大依然很小?这个方法你知道吗...
  11. 5.4(将英里转化位千米)
  12. SqlServer 备份还原
  13. BeagleBoard-x15烧录emmc
  14. 屏幕适配以及ui切图规范和命名标准
  15. 基于逻辑回归的鸢尾花分类预测
  16. FindVariableFeatures(高可变基因)和FindMarkers(差异表达基因)的区别
  17. 提高Linux下打开WPS云文档速度的方法
  18. 境内区块链信息服务备案清单(第一批)
  19. 赫布理论 —— 机器学习思想的萌芽
  20. 这篇文章,我们来谈一谈Spring中的属性注入

热门文章

  1. Hash(散列)冲突解决之线性探测再散列和二次探测再散列
  2. 一个非常实用的漂浮广告代码(强烈推荐)
  3. 搜索引擎是如何工作的?
  4. 信息时代的管理信息系统
  5. 拒绝跟风,谈谈几种算法岗的区别和体验
  6. 小米再次回购股票:斥资近1亿港元 传递市场信心
  7. REW声学测试(二):离线测试
  8. 小程序订阅消息推送工具类
  9. python中怎么赋值一个数为负无穷_python里面正无穷和负无穷问题?
  10. 来看看生词:CVBS、S-Video、YPbPr、模拟RGB、DVI和HDMI