Busybox实践2:分析busybox文件链接原理并编程模拟实现自己的busybox文件
推荐一个零声学院免费教程,个人觉得老师讲得不错,
分享给大家:[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文件相关推荐
- java文件读入原理_描述一下JVM加载class文件的原理机制
1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从"Hello World "开始的,然后会写个复杂点class ,然后再找一些开源 ...
- 软考网络管理员教程精讲之文件链接命令
离2017年下半年软考网络管理员考试只有半年的时间了.大家都在找各种复习资料吧!下面是希赛小编为大家整理了一些软考网络管理员知识点,下文主讲文件链接命令.希望能帮助各位学员. 文件链接命令 红旗Lin ...
- ios 静态库合成_iOS链接原理解析与应用实践
在iOS App开发中,程序的链接是由Xcode中自带的LLVM来帮助我们完成的,程序员们也因此更注重业务逻辑的编写.但其实了解链接的原理能让我们对iOS的底层有更深层次的认识,也有助于我们从底层原理 ...
- 软硬链接、文件删除原理、linux中的三种时间、chkconfig优化
第1章 软硬链接 1.1 硬链接 1.1.1 含义 多个文件拥有相同的inode号码 硬链接即文件的多个入口 1.1.2 作用 防止你误删除文件 1.1.3 如何创建硬链接 ln 命令,前面是源文件 ...
- 内存映射文件mmap原理分析
本文来说下内存映射文件 mmap 原理 文章目录 mmap原理分析 mmap原理分析 假设我们要把一个磁盘文件映射到内存里来,然后把映射到内存中的数据通过socket发送出去. 零拷贝有两种实现方式, ...
- 【Python网络爬虫实战篇】使用selenium+requests爬取下载高清源视频:关于爬取m3u8文件链接解析为ts视频合并成mp4视频的分析实战
这两天博主在摸鱼时,偶然间接触到了流媒体的概念,一时间来了兴致.再加上之前博主有着七.八年的视频制作经验,深知视频素材获取的不易.因此,打算利用自己所学的python网络爬虫的知识,通过编写代码实现获 ...
- C++模板声明与实现分开--由此想到的编译,链接原理
问题来源:当模板文件的实现与声明分开在不同文件中时,链接时会提示找不到相应模板函数,如下 一,编译和链接的大概原理: 1,编译,遍历工程的所有代码文件,进行文件分析,这里的分析与文件后缀无关,并不是说 ...
- 编译调试 .NET Core 5.0 Preview 并分析 Span 的实现原理
很久没有写过 .NET Core 相关的文章了,目前关店在家休息所以有些时间写一篇新的????.这次的文章主要介绍如何在 Linux 上编译调试最新的 .NET Core 5.0 Preview 与简 ...
- 实验楼 linux内核原理与分析,《Linux内核原理与分析》第一周作业 20189210
实验一 Linux系统简介 这一节主要学习了Linux的历史,Linux有关的重要人物以及学习Linux的方法,Linux和Windows的区别.其中学到了LInux中的应用程序大都为开源自由的软件, ...
最新文章
- Django+Linux+Uwsgi+Nginx项目部署文档
- AB1601编译优化参数引发的问题
- Java图像处理之亮度调整
- python读取上一级文件夹下的图片
- oracle先执行哪个from,Oracle(二)SELECT语句执行顺序
- 小隐隐于野:基于TCP反射DDoS攻击分析
- 使用extract-text-webpack-plugin提取css文件
- 什么,双非学渣唯一的出路是打比赛?
- 游戏程序中的骨骼插件
- 【EJB基础】开发一个简单的EJB应用程序
- SQL基础教程(第2版)读书笔记
- Tecplot 自定义色谱颜色
- 午间一乐:no zuo no die,唱起来
- 2022年茶艺师(初级)考试练习题模拟考试平台操作
- C语言求解一元二次方程组的代码
- 肖 sir_就业课__005项目数据
- 用DIV+CSS技术设计的游戏企业网页(网页制作课作业)
- jQuery实现弹幕效果(鼠标单击和键盘回车键)
- Android混淆技术综述
- 计算机辅助电路与设计试卷,计算机辅助电路设计_习题集(含答案).doc