在Ubuntu环境下载、查看和修改源代码



简介

本实验想要实现的目的如下:
(1)下载并查看 “ls” 命令的源代码;
(2)对命令的源代码进行小的修改并尝试运行;
(3)将修改的源代码安装到系统上。
本博文是记录课程作业实现过程而撰写的实验报告,为后面复习或者给有需要的人提供一点帮助而发布。


实验过程

1、先在下载中勾选源代码处的选项,并更新源

在设置中找到下载的相关选项,勾选“源代码”(默认没有勾选)
在这里插入图片描述
更新源

sudo apt update

操作如下
在这里插入图片描述

2、用 which 命令查找 ls 命令所在的位置,并用 dpkg 命令查看命令所在的软件包

(1)发现没有相匹配的路径
在这里插入图片描述
(2)尝试加上 -a 查看所有的匹配项,发现有两个路径
在这里插入图片描述
(3)在根目录下查看,发现 /bin 目录其实是一个链接
在这里插入图片描述
(4)对 /bin 链接下的 ls 用 dpkg 命令查找,可以得到对应的软件包(coreutils)
在这里插入图片描述
  后来发现原因是 20.04 版本的 Ubuntu(本人用的版本)与 18.04 版本的文件系统不太一样,而大部分 Linux 系统默认使用的文件系统与 18.04 版本一样,因此采用 /bin 目录下的 ls。

3、通过apt命令获取源代码

apt source coreutils

在这里插入图片描述
运行 apt 命令之后源代码即下载到当前目录下。

4、运行./configure配置文件并编译

(1)查看 ./configure 配置文件
进入源代码所在的目录,用 “ll” 命令查看配置文件 configure
在这里插入图片描述
右上角的 ‘*’ 表示为可执行文件
在这里插入图片描述
(2)运行 ./configure 配置文件并用 make 编译

./configure && make

在这里插入图片描述
(3)运行一段时间之后出现报错,显示的是make的错误
  提示 ‘aclocal-1.15’ 不存在于系统中,运行多次仍然出现下面的报错。
在这里插入图片描述
(4)由于并不理解该报错信息,于是将其在网络上查找,找到这篇博文。大概是由于版本问题,根据其提示运行代码:

autoreconf -f -i

发现需要额外安装包autoconf,根据要求,操作如下:
在这里插入图片描述
(5)安装之后继续运行命令,发现仍然报错,提示没有找到相关文件,借助这篇博文的帮助,提示还需要再安装一个软件包 autopoint ,运行如下代码:

sudo apt install -y autopoint

如下:
在这里插入图片描述
(6)安装之后,autoreconf -f -i 代码即可正常运行,如下:
在这里插入图片描述
(7)由于之前配置文件已经运行,直接用 make 编译即可
在这里插入图片描述
编译成功,可以在 /src 目录下看到新增了一系列可执行文件,截图如下:
在这里插入图片描述
调用本地的./ls可执行文件也可以成功运行,部分截图如下:
在这里插入图片描述

5、对 ls 命令的源代码进行修改

(1)修改目标
  将 ls 的 ‘-l’ 选项修改为 ‘-z’ 。
  没有改变实际功能,只是单纯的修改输入的命令选项,即改用 “ls -z” 命令来实现 “ls -l” 的功能,列出当前目录下所有文件的详细信息。
(2)进入 ls 命令源代码所在的 src 文件夹。经过查看,ls 命令的源代码主要写在 ls.c 文件中,于是进入该文件寻找目标代码。
在这里插入图片描述
(3)由于想要修改的命令和 ‘-l’ 相关,因此用vim的查找功能直接查找 ‘-l’ 。经过逐个筛选,锁定到了如下的一行注释中:该注释对应的是一个C语言中的枚举 enum,其中’-l’所在的注释对应的是第一个元素 “long_format” 。
在这里插入图片描述
(3)查找的关键词的选择
  由上述的查询结果可见 “long_format” 是一个重要的关键词。
  由于ls命令的每个选项前都有 ‘-’(如 ‘-l’、‘-a’ 等),因此程序在对输入的’ls’命令后面的选项进行识别的过程中对’-'字符进行判别的概率较小,而若单单使用一个单词 ’l’ 来查找则很容易查到许多无关的匹配项(可能许多单词包含’l’字母),因此改用 “long_format” 关键词来查找很有利于提高查找效率。
(4)于是利用vim查找 “long_format” 。又经过不断的筛选,在几千行代码中找到了一片非常有结构性的代码块——switch-case 语句,由于ls命令有许多的选项,很容易让人联想到可以用 switch-case 语句来实现,如下:
在这里插入图片描述
仔细一看,果然再次发现了关键词—— ‘l’
在这里插入图片描述
(5)直接将其改为我们想要的选项—— ’z’,如下:
在这里插入图片描述
(6)回到上一级目录,再用make编译一下
在这里插入图片描述
(7)回到 ls.c 文件所在的目录下运行./ls -l和./ls -z,发现都无法实现,如下:
在这里插入图片描述
(8)问题分析
  ./ls -l 无法运行说明之前所作的修改的位置正确,而 ./ls -z 无法运行说明选项的修改不完全,还有其他地方需要修改。
  而且发现运行 ./ls -l 命令时只是提示通过 help 来获取帮助,而运行 ./ls -z 时还提示 ls 并没有 -z 的选项,说明各个选项可能还存放在某个类似于数组的数据结构中,用于判断输入的选项是否合法。
  由于之前只在 switch_case 结构中修改了输出的标志 long_format(猜测),并没有在哪个数组中将其删去,而修改为 -z 时并没有将 -z 添加到所谓的数组中,因此导致运行时出现如上的 -z 为不适用的选项的提示。(几千行的代码怎么可能没有其他的依赖,只需要修改一个地方)
(9)经过不断的查找,在 switch_case 结构的前几十行找到了下面的代码,刚开始并没有太多的注意,但是后来发现如下的字符串中的字符可能是按某种顺序进行排列,而且并不是连续的字典序abcde…
在这里插入图片描述
  于是重新翻到 switch_case 结构处。如下(截取片段),发现 switch_case 结构中选项的顺序恰好与上述的字符串的子串相匹配。
在这里插入图片描述
  于是大胆猜测该段字符串就是之前假设的所谓的存储选项的数组,于是将字符串中的 ‘l’ 改为 ‘z’ ,如下:
在这里插入图片描述
(10)再返回上级目录进行编译,并尝试运行
在这里插入图片描述
使用./ls -z命令可以正常使用,如下:
在这里插入图片描述
而./ls -l命令已经不能使用了
在这里插入图片描述
成功!!!目标达成

6、将修改的源代码安装到系统上

运行代码

make install

  由于安装后会修改系统上的程序,为了防止存在的存在隐藏的BUG,本人没有尝试运行安装程序。


总结

  对于系统命令源代码的修改,原本个人想法是想修改ls命令本身的一些功能,比如添加一个选项,使ls能都递归地进行调用,遍历当前目录及以下的所有文件并显示出来。但是当我打开 ls.c 文件之后我的这种幻想被打破了,我从头往后翻,发现几百行的代码全是enum、struct等的定义,而全部代码足足有上千行。由于较大的修改需要先读懂大部分的代码,想想还是放弃了。
  原本以为改个选项名称会容易一点,后面发现在几千行代码中进行关键词的筛选也不是一件容易的事儿。
  通过本次实验,大致掌握了软件包的编译下载,通过对系统命令源代码的阅读使得对代码的开发有了一定的了解,同时也意识到关键词查找的必要性和便捷性,即使本次实验的实现在开发上并没有实际性的意义。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐