推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:[Linux,Nginx,ZeroMQ,MySQL,Redis,
fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,
TCP/IP,协程,DPDK等技术内容,点击立即学习:

目录

前言

一 busybox文件原理

基本原理

验证一下

验证1 删掉ls命令:

验证2 自己创建一个ls的链接:

二 用代码来证明原理

1 先写一个普通的小程序

2 创建链接,见证奇迹

三 模拟一个busybox

1 编写模拟busybox程序代码

2 运行验证

1) 验证lk命令

2)验证hg命令

四 将我的命令lk和hg添加到PATH环境变量

添加PATH环境变量

开始验证了

总结


前言

书接上文,前一节已经成功构建了一个最简单的根文件系统,并且在根文件系统中运行了一个静态编译的C程序。本文编写一个busybox模拟程序,来说明busybox文件的实现原理。

一 busybox文件原理

为什么busybox一个文件可以链接成为那么多命令呢

基本原理

根据查看BusyBox源码,发现里面有很多xxx_main函数,BusyBox根文件系统运行时,输入的命令,如ls,是以argv[0]的形式,传递给BusyBox的终端交互程序,也就是说,我们输入的这个地方本身就是一个程序,如下所示,它处理我们输入的数据,例如我们输入ls,它就处理ls。

Please press Enter to activate this console.
/ #

如何找的呢,分两步:

1)它先去PATH对应的环境变量找,找到ls

2)发现ls是被链接到busybox文件,然后将ls名字传递给busybox文件,busybox文件会接收ls这个参数,并调用相应的ls_main函数,就顺利执行了ls命令。

验证一下

验证1 删掉ls命令:

/ # which ls
/bin/ls
/ # rm /bin/ls
/ # ls
-/bin/sh: ls: not found
/ # ls

现在,ls命令已经被删除,且执行时-/bin/sh: ls: not found,说明,并没有去直接执行busybox,这个还是很关键的。这说明即便是busybox自带的命令也要受PATH环境变量的约束。

验证2 自己创建一个ls的链接:

如下所示,先验证ls确实不存在,然后创建一个指向busybox的链接,并命名为ls,然后进入根目录,再次测试ls命令,结果证明,ls确实是指向busybox的链接,并且仅仅是一个普通的链接,没有没有什么特别之处,特别的是busybox对于命令行参数的处理,有机会我们也写一个自己的busybox小程序试试。

/ # cd bin/
/bin # ls
-/bin/sh: ls: not found
/bin # ln -s busybox ls
/ # ls
app      bin      etc      linuxrc  sbin     test.sh  usr
arm_app  dev      hello.c  proc     sys      tmp      var
/ #

二 用代码来证明原理

这个自己做出来以后才发现,真相原理一直就在眼前,只是我们一直把它神话了。

1 先写一个普通的小程序

代码如下所示:保存命名为main.c

#include <stdio.h>int main(int argc,char *argv[])
{int i = 0;for(i = 0;i < argc;i++){printf("argv[%d] = %s .\n",i,argv[i]);}return 0;
}

编译测试

lkmao@ubuntu:~$ gcc main.c -o busy
lkmao@ubuntu:~$ ./busy
argv[0] = ./busy .

看输出结果,argv[0]是程序名,是busy。

2 创建链接,见证奇迹

首先我创建了一个指向busy的链接,命名为lk,

lkmao@ubuntu:~$ ln -s busy lk

然后执行lk,见证结果啦

lkmao@ubuntu:~$ ./lk
argv[0] = ./lk .

看到了吧。基本原理就是这样了。

三 模拟一个busybox

1 编写模拟busybox程序代码

修改main.c文件,并重命名为busy.c的代码如下所示:

#include <stdio.h>
#include <string.h>#define debug(format,...)   printf("%s:%s:%d - "format"\n",\__FILE__,__func__,__LINE__,##__VA_ARGS__);
int main(int argc,char *argv[])
{int i = 0;char *cmd;for(i = 0;i < argc;i++){debug("argv[%d] = %s .",i,argv[i]);}if(argv[0][0] == '.' && argv[0][1] == '/'){cmd = &argv[0][2];}else{cmd = &argv[0][0];}if(strcmp("lk",cmd) == 0){debug("i'm comand lk");return 0;}if(strcmp("hg",cmd) == 0){debug("i'm comand hg");return 0;}debug("unknown cmd %s",cmd);debug("do you want \"lk\" or \"hg\"");return 0;
}

编译,然后创建相应的链接文件lk和hg。

lkmao@ubuntu:~$ gcc busy.c -o busy
lkmao@ubuntu:~$ ln -s busy lk
lkmao@ubuntu:~$ ln -s busy hg

2 运行验证

1) 验证lk命令

lkmao@ubuntu:~$ ./lk
busy.c:main:11 - argv[0] = ./lk .
busy.c:main:19 - i'm comand lk
lkmao@ubuntu:~$

2)验证hg命令

lkmao@ubuntu:~$ ./hg
busy.c:main:11 - argv[0] = ./hg .
busy.c:main:24 - i'm comand hg
lkmao@ubuntu:~$

好了,执行成功。

四 将我的命令lk和hg添加到PATH环境变量

添加PATH环境变量

创建文件夹mycmd,将文件busy lk hg都放进去


lkmao@ubuntu:~$ mkdir mycmd
lkmao@ubuntu:~$ mv busy lk hg mycmd/
lkmao@ubuntu:~$

然后通过export命令将mycmd放到PATH环境变量中

lkmao@ubuntu:~$ export PATH=${PATH}:/home/lkmao/mycmd
lkmao@ubuntu:~$ echo $PATH
/home/lkmao/bin:/home/lkmao/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin:/home/lkmao/mycmd
lkmao@ubuntu:~$

从PATH的值可知,我们已经将/home/lkmao/mycmd添加到了PATH的尾部。

开始验证了

验证lk

lkmao@ubuntu:~$ lk
busy.c:main:11 - argv[0] = lk .
busy.c:main:19 - i'm comand lk

验证hg

lkmao@ubuntu:~$ hg
busy.c:main:11 - argv[0] = hg .
busy.c:main:24 - i'm comand hg

验证完毕,结果OK.

总结

其实这个原理并不复杂,甚至也可以说简单,只是我们把busybox神话了,神话到不敢去探究它的真面目,发现真相的那一刻我惊呆了,这感觉,有点酸爽啊。

Busybox实践2:分析busybox文件链接原理并编程模拟实现自己的busybox文件相关推荐

  1. java文件读入原理_描述一下JVM加载class文件的原理机制

    1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从"Hello World "开始的,然后会写个复杂点class ,然后再找一些开源 ...

  2. 软考网络管理员教程精讲之文件链接命令

    离2017年下半年软考网络管理员考试只有半年的时间了.大家都在找各种复习资料吧!下面是希赛小编为大家整理了一些软考网络管理员知识点,下文主讲文件链接命令.希望能帮助各位学员. 文件链接命令 红旗Lin ...

  3. ios 静态库合成_iOS链接原理解析与应用实践

    在iOS App开发中,程序的链接是由Xcode中自带的LLVM来帮助我们完成的,程序员们也因此更注重业务逻辑的编写.但其实了解链接的原理能让我们对iOS的底层有更深层次的认识,也有助于我们从底层原理 ...

  4. 软硬链接、文件删除原理、linux中的三种时间、chkconfig优化

    第1章 软硬链接 1.1 硬链接 1.1.1 含义 多个文件拥有相同的inode号码 硬链接即文件的多个入口 1.1.2 作用 防止你误删除文件 1.1.3 如何创建硬链接 ln 命令,前面是源文件  ...

  5. 内存映射文件mmap原理分析

    本文来说下内存映射文件 mmap 原理 文章目录 mmap原理分析 mmap原理分析 假设我们要把一个磁盘文件映射到内存里来,然后把映射到内存中的数据通过socket发送出去. 零拷贝有两种实现方式, ...

  6. 【Python网络爬虫实战篇】使用selenium+requests爬取下载高清源视频:关于爬取m3u8文件链接解析为ts视频合并成mp4视频的分析实战

    这两天博主在摸鱼时,偶然间接触到了流媒体的概念,一时间来了兴致.再加上之前博主有着七.八年的视频制作经验,深知视频素材获取的不易.因此,打算利用自己所学的python网络爬虫的知识,通过编写代码实现获 ...

  7. C++模板声明与实现分开--由此想到的编译,链接原理

    问题来源:当模板文件的实现与声明分开在不同文件中时,链接时会提示找不到相应模板函数,如下 一,编译和链接的大概原理: 1,编译,遍历工程的所有代码文件,进行文件分析,这里的分析与文件后缀无关,并不是说 ...

  8. 编译调试 .NET Core 5.0 Preview 并分析 Span 的实现原理

    很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的????.这次的文章主要介绍如何在 Linux 上编译调试最新的 .NET Core 5.0 Preview 与简 ...

  9. 实验楼 linux内核原理与分析,《Linux内核原理与分析》第一周作业 20189210

    实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...

最新文章

  1. Django+Linux+Uwsgi+Nginx项目部署文档
  2. AB1601编译优化参数引发的问题
  3. Java图像处理之亮度调整
  4. python读取上一级文件夹下的图片
  5. oracle先执行哪个from,Oracle(二)SELECT语句执行顺序
  6. 小隐隐于野:基于TCP反射DDoS攻击分析
  7. 使用extract-text-webpack-plugin提取css文件
  8. 什么,双非学渣唯一的出路是打比赛?
  9. 游戏程序中的骨骼插件
  10. 【EJB基础】开发一个简单的EJB应用程序
  11. SQL基础教程(第2版)读书笔记
  12. Tecplot 自定义色谱颜色
  13. 午间一乐:no zuo no die,唱起来
  14. 2022年茶艺师(初级)考试练习题模拟考试平台操作
  15. C语言求解一元二次方程组的代码
  16. 肖 sir_就业课__005项目数据
  17. 用DIV+CSS技术设计的游戏企业网页(网页制作课作业)
  18. jQuery实现弹幕效果(鼠标单击和键盘回车键)
  19. Android混淆技术综述
  20. 计算机辅助电路与设计试卷,计算机辅助电路设计_习题集(含答案).doc

热门文章

  1. goahead之GoAction实现
  2. Jenkins 通过 Version Number Plug 优雅的生成项目版本号
  3. GateWay网关访问服务出现503的问题解决
  4. 关于12球问题的讨论
  5. 小程序自定义导航栏指南
  6. 安装arosics做自动几何校正
  7. JavaScript中的Event.target
  8. 建筑工地通道管理系统(有效防止考勤作弊)
  9. iOS 作为蓝牙外设广播信息
  10. 华为手机输入键盘声音_华为键盘声音怎么设置