Contents

读取源代码的shell命令

1. 概述

我们不妨阅读我们的 Linux 工具的源代码以了解它们的工作原理。这可能是因为我们需要编写类似的东西,或者希望为 Linux 源代码做出贡献。

因为大多数常用命令和工具都是开源的,所以很多源代码都可以在线获得。

在本教程中,我们将了解如何从不同的资源中查找、阅读和理解 shell 命令的源代码。

2. 找到源代码

有几种不同的方法可以找到源代码。首先,我们应该识别命令并在合适的参考中找到它。主要要求是发行版或命令行工具是开源的。

2.1. 识别命令

首先,我们需要确定命令的类型。它可能是 shell 命令、内置命令、别名、可执行文件等。我们可以使用typewhichhelpmaninfo 等命令获取有关它的信息。

type命令指示命令是别名关键字函数内置命令、磁盘文件还是未找到。例如,它可能显示有两个可用的echo命令实例:

$ type -a echo
echo is a shell builtin
echo is /usr/bin/echo

which命令打印 shell 命令的完整路径,帮助我们找出它在我们的文件系统中的位置。它搜索环境变量 PATH 中列出的目录。**我们需要which命令的输出,即命令路径,以使用包管理器下载源代码。

$ which echo
/usr/bin/echo

help命令显示内置命令的简短摘要。

$ help help
help: help [-dms] [pattern ...]
Display information about builtin commands.
...
$ help echo
echo: echo [-neE] [arg ...]
Write arguments to the standard output.
...

要查看系统参考手册,我们可以使用man命令。这提供了比帮助命令更多的信息:

$ man echo
...

如果我们希望阅读 Info 格式的文档,可以使用info 命令。

$ info '(echo)'
...

2.2. 寻找起源

找出命令的类型后,下一步就是找到它的来源。在大多数情况下,我们可以在手册中找到网址

让我们以查找xdotool 命令的来源为例。首先,我们需要看一下它的手册:

$ man xdotool

然后向下滚动手册页,我们可以在页面末尾看到该项目的网站和有用的参考资料:

SEE ALSO
       xprop(1), xwininfo(1),
       Project site: <http://www.semicomplete.com/projects/xdotool>
       Source code and Issues: <https://github.com/jordansissel/xdotool>
       EWMH specification: <http://standards.freedesktop.org/wm-spec/wm-spec-1.3.html>

在其GitHub 存储库中,我们可以看到包含源代码的xdotool.c 文件。

如果项目的站点不在文档中,谷歌搜索工具的名称也可以帮助我们找到它的来源。

3. 使用包管理器

我们可以使用包管理器来获取有关已安装命令的信息。这可以包括命令的源代码。**第一步是找出这些命令在哪个包中。**稍后我们可以使用包管理器下载它们的源代码。

因为 Linux 发行版可能会做出自己的更改,所以使用包管理器是查找和下载已安装工具源代码的最佳方式。

让我们看一下基于 Debian 和基于 Red Hat 的系统,这是两个更流行的发行版。

3.1. 基于 Debian 的系统

**在基于 Debian 的系统上,*我们可以使用dpkg -S command path*来查找包名:

$ dpkg -S /bin/echo
coreutils: /bin/echo

然后我们使用*apt-get source package name*下载源码到当前目录:

$ apt-get source coreutils
Reading package lists... Done
Need to get 5,401 kB of source archives.
Get:1 <a href="http://archive.ubuntu.com/ubuntu" target="_blank" rel="noopener noreferrer" data-saferedirecturl="https://www.google.com/url?q=http://archive.ubuntu.com/ubuntu&source=gmail&ust=1602420084996000&usg=AFQjCNEvfOswG2s3CI6iAIvG6HBAxTvwmQ">http://archive.ubuntu.com/ubuntu</a> focal/main coreutils 8.30-3ubuntu2 (dsc) [2,048 B]
Get:2 <a href="http://archive.ubuntu.com/ubuntu" target="_blank" rel="noopener noreferrer" data-saferedirecturl="https://www.google.com/url?q=http://archive.ubuntu.com/ubuntu&source=gmail&ust=1602420084996000&usg=AFQjCNEvfOswG2s3CI6iAIvG6HBAxTvwmQ">http://archive.ubuntu.com/ubuntu</a> focal/main coreutils 8.30-3ubuntu2 (tar) [5,360 kB]
Get:3 <a href="http://archive.ubuntu.com/ubuntu" target="_blank" rel="noopener noreferrer" data-saferedirecturl="https://www.google.com/url?q=http://archive.ubuntu.com/ubuntu&source=gmail&ust=1602420084996000&usg=AFQjCNEvfOswG2s3CI6iAIvG6HBAxTvwmQ">http://archive.ubuntu.com/ubuntu</a> focal/main coreutils 8.30-3ubuntu2 (diff) [39.6 kB]
Fetched 5,401 kB in 25s (212 kB/s)..

apt-get source命令在 sources.list 中搜索。起初这可能是空的,所以我们第一次可能会遇到一些错误:

$ apt-get source coreutils
Reading package lists... Done
E: You must put some 'deb-src' URIs in your sources.list

为了解决这个问题,我们需要添加一些URI。例如在Ubuntu 20.04 LTS中,我们需要勾选软件&更新设置中的源代码框:

/uploads/read_source_code_shell_commands/1.png

apt-get下载源并将它们放在当前目录中:

$ ls
coreutils_8.30-3ubuntu2.debian.tar.xz Desktop Music snap
coreutils_8.30-3ubuntu2.dsc Documents Pictures Templates
coreutils_8.30.orig.tar.xz Downloads Public Videos

如果我们不确定要使用的包名称*,*Debian 网站提供了一个包列表。

3.2. 基于 Red Hat 的系统

**在基于 Red Hat 的系统上,*我们可以使用rpm -qf command path*来查找包名:

$ rpm -qf /usr/bin/echo
coreutils-single-8.32-4.fc32.1.x86_64

然后我们使用*dnf download –source package name* 下载它。

$ dnf download --source coreutils-single-8.32-4.fc32.1.x86_64
enabling fedora-modular-source repository
...
Last metadata expiration check: 0:05:21 ago on Sun 11 Oct 2020 12:36:12 PM +0330
coreutils-8.32-4.fc32.1.src.rpm 10 kB/s | 5.4 MB 08:47 

对于未安装的命令或包,我们可以使用repoquery 命令代替。然后我们可以使用上面的命令:

$ dnf repoquery -q  clang
clang-0:10.0.0-1.fc32.i686
clang-0:10.0.0-1.fc32.x86_64
clang-0:10.0.1-2.fc32.i686
clang-0:10.0.1-2.fc32.x86_64

我们不必向dnf download –source命令提供完整的包名称。它从命令路径或名称中为我们计算出最可能的来源,并下载最匹配的最新版本:

对于已安装的包,我们使用dnf download –source 命令路径

$ dnf download --source /usr/sbin/fdisk
enabling fedora-modular-source repository
.....
util-linux-2.35.2-1.fc32.src.rpm

对于没有安装的包,我们使用dnf download –source 命令名

$ dnf download --source clang
enabling fedora-modular-source repository
...
clang-10.0.1-2.fc32.src.rpm

我们应该注意,如果有多个包包含我们感兴趣的命令,则此方法可能不完全准确。

最后我们可以在当前目录下看到下载好的包:

$ ls
Music                                  Pictures
clang-10.0.1-2.fc32.src.rpm            Public
coreutils-8.32-4.fc32.1.src.rpm        Templates
Desktop                                Documents
util-linux-2.35.2-1.fc32.src.rpm       Downloads
Videos

4.在线参考

如果我们想在 Web 上浏览 Linux 源代码,有几个主要的起点。因为许多 Linux 工具都起源于 GNU 项目,所以GNU 是一个很好的起点。

4.1. GNU 软件网站

由于大多数 Linux 发行版都使用 GNU 软件包,因此GNU 软件站点 是一个有用的在线参考。在子类别中,*Coreutils *包含 shell 命令和许多主要用 C 编程语言编写的基本工具。因此,我们可以通过cgitgitwebGitHub 浏览源代码。

例如,在GitHub 的 GNU Coreutils 子目录中,我们可以阅读*cat df ls rm echo *等命令的源代码。

4.2. 替代资源

*Util-linux *是一个标准包,由Linux Kernel Organization 发布。这被用作 Linux 操作系统的一部分,并通过GitHubcgit 提供了它的一些源代码。

5. Linux 源代码入门

找到源代码后,我们需要有编程知识才能看懂

Decoded GNU Coreutils 中提供了一个很好的教育资源。在这里,我们将找到帮助新手程序员轻松学习代码的图表和分步指南。例如,在其概述中有很多关于 echo的信息。在每个部分中,还链接了其GitHub 存储库的 源代码。