From fcda4313d9427030f3fbcad5e1cadd2f1955b5dd Mon Sep 17 00:00:00 2001 From: luojh Date: Wed, 5 Mar 2025 18:58:28 +0800 Subject: [PATCH 01/14] Ch1 to Ch3 modifications --- docs/Ch01/index.md | 12 ++++++------ docs/Ch01/supplement.md | 9 +++++++++ docs/Ch02/index.md | 39 ++++++++++++++++++++++++++++++--------- docs/Ch02/solution.md | 4 ++-- docs/Ch03/index.md | 41 +++++++++++++++++++++++++++++------------ docs/Ch04/index.md | 2 +- 6 files changed, 77 insertions(+), 30 deletions(-) diff --git a/docs/Ch01/index.md b/docs/Ch01/index.md index 1953be80..00478b29 100644 --- a/docs/Ch01/index.md +++ b/docs/Ch01/index.md @@ -26,7 +26,7 @@ icon: simple/linux ### 计算机操作系统 {#computer-os} -如果现在提起计算机操作系统,可能多数人的第一反应就是大名鼎鼎的 Windows,此外有些人可能也接触过 macOS 或者 Linux 的各类发行版(如:Ubuntu, Manjaro, CentOS 等),它们都是计算机操作系统。然而计算机最初并没有操作系统。在当时,许多计算机不是通用计算机,它们造出来就是为了某个特定目的而服务的,因此其架构只需要为这个目的而设计即可,无需包括完整的操作系统。另外一个原因是在晶体管时代之前,计算机体积庞大,而性能又十分有限,因此也没有能力承载通用的操作系统。随着计算机性能的提升,人们更加依赖计算机的能力,对计算机的功能要求也日渐复杂。为了能尽可能利用计算机的自动化这一特性,一些操作系统开始成型。在成型的初期,计算机操作系统的目的是为了帮助用户进行批处理操作,不过之后它们也慢慢有了新的功能:进程管理、任务调度、控制输入输出设备等。这样的操作系统逐渐形成了庞大的体系,成为了联络一般用户和计算机底层设备的中介,让用户无需关心绝大多数的底层设备,大大降低了用户的使用学习成本。 +如果现在提起计算机操作系统,可能多数人的第一反应就是大名鼎鼎的 Windows,此外有些人可能也接触过 macOS 或者 Linux 的各类发行版(如:Ubuntu, Fedora, Manjaro, CentOS 等),它们都是计算机操作系统。然而计算机最初并没有操作系统。在当时,许多计算机不是通用计算机,它们造出来就是为了某个特定目的而服务的,因此其架构只需要为这个目的而设计即可,无需包括完整的操作系统。另外一个原因是在晶体管时代之前,计算机体积庞大,而性能又十分有限,因此也没有能力承载通用的操作系统。随着计算机性能的提升,人们更加依赖计算机的能力,对计算机的功能要求也日渐复杂。为了能尽可能利用计算机的自动化这一特性,一些操作系统开始成型。在成型的初期,计算机操作系统的目的是为了帮助用户进行批处理操作,不过之后它们也慢慢有了新的功能:进程管理、任务调度、控制输入输出设备等。这样的操作系统逐渐形成了庞大的体系,成为了联络一般用户和计算机底层设备的中介,让用户无需关心绝大多数的底层设备,大大降低了用户的使用学习成本。 ### 现代操作系统的功能 \* {#modern-os-functions} @@ -76,11 +76,11 @@ Linux 内核并不是一个完整的操作系统,因为它过于精简,单 进入 GNU/Linux 世界,便意味着与 GNU 自由软件打交道。先看看一堆字母 g 开头的应用程序: - - gcc: GNU 的 C 和 C++ 编译器 - - gdb: GNU 程序调试器 - - gzip: gz 格式压缩与解压缩工具 + - `gcc`: GNU 的 C 和 C++ 编译器 + - `gdb`: GNU 程序调试器 + - `gzip`: gz 格式压缩与解压缩工具 - GNOME: 隶属于 GNU 项目的桌面环境 - - gimp: GNU 图像编辑工具 + - `gimp`: GNU 图像编辑工具 它们的首字母 g 都是 GNU 的缩写(当然不是所有以 g 开头的都是 GNU 软件)。许多 Linux 上的系统管理命令虽然未必以 g 开头,但都属于自由软件;还有[更多优秀的软件](https://www.gnu.org/software/),被自由软件爱好者维护、分享……选择 Linux,很大程度上是一种对极客精神与开源文化的认同。 @@ -194,7 +194,7 @@ Windows Server 图标 Android TV 图标 {: .caption } -## 让自己的计算机用上 Linux {#use-linux} +## 让自己的计算机用上 Linux {#use-linux} @@ 有很多尚未接触过 Linux 的读者看到这里可能已经在期待或者计划让自己尽快开始使用 Linux 了。事实上,如果把 Linux 看作一个领域,那它的确是一个重视实践的领域。而且出于学习目的,在阅读本书未来的章节时在手头准备一个随时可用的 Linux 发行版是十分关键和有益的。因此,本书**强烈建议各位读者在本机安装一个属于自己的 Linux 发行版**,以供随时实践。 diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md index e6a5dc93..a32abc3f 100644 --- a/docs/Ch01/supplement.md +++ b/docs/Ch01/supplement.md @@ -398,6 +398,10 @@ ustc@ustclug-linux101:~$ 你可能会在老版本的 Windows 上注意到,在「添加与删除 Windows 组件」的地方,有一个「基于 UNIX 的应用程序子系统」。需要注意的是,这个选项和 WSL 没有任何关系。它也无法直接运行 Linux 或者其他 UNIX 的程序。并且,这个子系统目前也已经停止了开发。 +!!! warning + + 请注意,**WSL 可能将主机的文件系统挂载在子系统的某个位置**。这在通常情况下会使得文件共享更加方便,但也可能导致在子系统中执行文件操作(例如文件删除)时错误地操作了主机上的文件。 + ### WSL 1 {#wsl1} WSL 1 面向 Linux 应用程序提供了一套兼容的内核接口,在 Linux 程序运行的时候,WSL 1 处理(Linux 使用的)ELF 可执行文件格式,将 Linux 的系统调用翻译为 Windows 的系统调用,从而运行 Linux 程序。WSL 1 中可以访问到 Windows 下的文件,也与主机共享网络。 @@ -534,6 +538,11 @@ $ sudo apt-get install ubuntu-desktop 重启虚拟机,在设置中进行分辨率的修改。 +## 使用 Ventoy {#using-ventoy} + +使用 Ventoy 可以简单方便地从 U 盘或者其他移动介质安装各类操作系统(且支持在一个介质中存放多个系统镜像),当然也包括 GNU/Linux。有关如何使用 Ventoy,请参考其网站[^2]。 + ## 引用来源 {#references .no-underline} [^1]: [Apple silicon - Wikipedia](https://en.wikipedia.org/wiki/Apple_silicon) +[^2]: [Ventoy 中文网站](https://www.ventoy.net/cn/index.html) diff --git a/docs/Ch02/index.md b/docs/Ch02/index.md index 9f4716f6..42dd10e2 100644 --- a/docs/Ch02/index.md +++ b/docs/Ch02/index.md @@ -289,14 +289,14 @@ Xfce4-session 是 Xfce 的会话管理器。它的任务是保存桌面的状态 使用命令行操作可以减少鼠标操作,我们经常可以使用一条命令来代替好几次的鼠标单击。例如如果我们想要移动某一个文件,我们要执行下面步骤: -- 打开文件所在的文件夹 `../source/` -- 打开目标文件夹 `../dest/` -- 从 `../source/` 文件夹拖拽文件 `file.txt` 到 `../dest/` 文件夹中 +- 打开文件所在的文件夹 `/path/to/source/` +- 打开目标文件夹 `/path/to/dest/` +- 从 `source` 文件夹拖拽文件 `file.txt` 到 `dest` 文件夹中 然而使用命令行,我们只需要执行一条指令。 ```shell -$ mv ../source/file.txt ../dest/ +$ mv /path/to/source/file.txt /path/to/dest/ ``` 可能在初学者看来,熟记这条指令并不容易,但是从长远上看,熟悉了命令行之后再加上有自动补全的 shell 程序,使用命令行可以节省大量时间。 @@ -322,13 +322,32 @@ $ mv ../source/file.txt ../dest/ 另外,以上的路径都是绝对路径,还有一种「相对路径」: ```shell - ./file.txt # 当前目录下的 file.txt 文件 - ../file.txt # 上一级目录(父目录)下的 file.txt 文件 - ../abc/file.txt # 上一级目录(父目录)下的 abc 文件夹下的 file.txt 文件 + file1.txt # 当前目录下的 file1.txt 文件 + ./file1.txt # 当前目录下的 file1.txt 文件 + ./file2.txt # 当前目录下的 file2.txt 文件 + ../file3.txt # 上一级目录(父目录)下的 file3.txt 文件 + ../abc/file4.txt # 上一级目录(父目录)下的 abc 文件夹下的 file4.txt 文件 + ../../file5.txt # 上上级目录下的 file5.txt + ``` + + 它们的关系是这样的: + + ```plain + 上上级目录/ + |___ file5.txt + |___ 上一级目录/ + |___ file3.txt + |___ 当前目录/ + | |___ file1.txt + | |___ file2.txt + |___ abc/ + |___ file4.txt ``` 每个正在运行中的进程(包括 Shell)都有自己的「当前工作目录」(当前所在的目录),进程可以切换自己的当前工作目录,以上的相对路径都是相对于当前工作目录的。可以发现,不管当前工作目录在哪里,绝对路径对应的文件都是一致的,而相对路径对应的文件就会随着当前工作目录的变化而变化。 + 特别地,用户的主目录(一般是 `/home/<用户名>`)可以被简写为 `~`。 + #### 自动化脚本 {#shell-automation} !!! tip "提示" @@ -357,6 +376,8 @@ gcc main.c -o main.out rm main.out ``` +和其他地方不一样,在 Shell 中运行程序时,程序名(`main.out`)前面必须有 `./`。这是因为因为我们的工作目录不包含在环境变量(`$PATH`)中,故如果不加 `./` 则系统会找不到程序。系统中安装的程序(例如 `gcc`)一般会放在 `$PATH` 环境变量中包含了的路径下,故运行它们不需要使用 `./`。 + 之后我们直接输入 ```shell @@ -375,7 +396,7 @@ $ sh run.sh #### 进行高级的系统维护工作 {#shell-system-maintenance} -一些高级的系统维护任务只能通过命令行来完成,因为相关的程序并没有提供图形界面的控制面板,或者需要手工编写复杂的配置文件。 +一些高级的系统维护任务只能通过命令行来完成,或者需要手工编写复杂的配置文件,因为相关的程序并没有提供图形界面的控制面板。 #### 使用命令行看上去很酷 {#shell-duang} @@ -454,7 +475,7 @@ Desktop Documents Music Pictures Public Templates Videos #### 示例 3 {#shell-commands-example-3} ```shell -$ cd Desktop +$ cd Desktop # 这里的 Desktop 是相对路径,指的就是当前目录下的 Desktop 文件夹 $ ls ``` diff --git a/docs/Ch02/solution.md b/docs/Ch02/solution.md index 4f1e0644..57696fca 100644 --- a/docs/Ch02/solution.md +++ b/docs/Ch02/solution.md @@ -23,6 +23,6 @@ icon: material/tooltip-question ??? info "解答" - 在 Linux 服务器的环境下,桌面环境不是必需品。我们知道,与 Windows 不同,Linux 下桌面环境也只是一个(可选的)软件。服务器中的配置完全可以在命令行中完成。 + 在 Linux 服务器的环境下,桌面环境不是必需品。我们知道,Linux 下桌面环境也只是一个(可选的)软件(Windows Server 中,桌面环境也不是必须安装的)。服务器中的配置完全可以在命令行中完成。 - 并且,安装桌面环境会占用额外的资源,尤其对于性能较低的服务器(例如在各种云服务器厂商上可以购买到的配置最低的机器,或者一些 SoC 嵌入式设备)。同时配置远程连接桌面(如使用 VNC)的过程也是比较麻烦的。 + 并且,安装桌面环境会占用额外的资源,尤其对于性能较低的服务器(例如在各种云服务器厂商上可以购买到的配置最低的机器,或者一些 SoC 嵌入式设备)。同时配置远程连接桌面(如使用 VNC)的过程也是比较麻烦的,且桌面环境也并没有命令行环境简单可靠。 diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index 9958c7ba..80a0d003 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -43,7 +43,7 @@ icon: material/folder-open 有了软件仓库,我们不需要手动下载大量的软件包再通过包管理器安装。只需要知道软件在软件仓库中的名称,即可让包管理器从网络中抓取到相应的软件包到本地,自动进行安装。 -但是与应用商店相比,使用包管理器安装需要预先知道所需软件在软件仓库中的对应包名,和应用商店相比无法进行模糊搜索(不过你也可以在包管理器官网上进行查找包名,再通过包管理器安装)。 +但是与应用商店相比,使用包管理器安装需要预先知道所需软件在软件仓库中的对应包名,和应用商店相比无法进行模糊搜索(不过你也可以在包管理器官网或者通过包管理器的命令行前端查找包名,再通过包管理器安装)。 包管理系统有很多,比如管理 Debian (.deb) 软件包的 `dpkg` 以及它的前端 `apt`(用于 Debian 系的发行版);`rpm` 包管理器以及它的前端 `dnf`(用于 Fedora 和新版的 CentOS 和 RHEL)、前端 `yum`(用于 CentOS 7 和 RHEL 7 等);`pacman` 包管理器(用于 Arch Linux 和 Manjaro)等等。 @@ -85,7 +85,7 @@ firefox/bionic-updates,bionic-security,now 72.0.2+build1-0ubuntu0.18.04.1 amd64 #### 安装 {#installation} -在确定了软件包的包名后,可以通过 `apt install <包名>` 进行安装。 +在确定了软件包的包名后,可以通过 `apt install <包名>` 安装软件包。如果需要一次性安装多个包,可以用 `apt install <包名1> <包名2> ...` 的写法。 下面是 `apt install firefox` 安装火狐浏览器的输出结果示例。 @@ -148,6 +148,13 @@ Do you want to continue? [Y/n] 具体有关权限的知识点将在[第五章](../Ch05/index.md)展开。 +!!! tip "不确认安装" + 如果不希望 `apt` 询问是否安装,可以使用 + + ```bash + apt install -y <软件包> + ``` + #### 官方软件源镜像 {#software-sources} 通过 apt 安装的软件都来源于相对应的软件源,每个 Linux 发行版一般都带有官方的软件源,在官方的软件源中已经包含了丰富的软件,apt 的软件源列表在 `/etc/apt/sources.list` 下。 @@ -211,7 +218,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 $ sudo sed -i 's|//.*archive.ubuntu.com|//mirrors.ustc.edu.cn|g' /etc/apt/sources.list ``` - 当然也可以直接使用 vim、nano 等文本编辑器进行修改。 + 当然也可以直接使用 `vim`、`nano` 等文本编辑器进行修改。 #### 第三方软件源 {#third-party-software-sources} @@ -228,7 +235,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 1. 安装需要的的软件包 ```shell - $ sudo apt-get update + $ sudo apt-get update # 更新本地的包列表 $ sudo apt-get install \ ca-certificates \ @@ -444,14 +451,10 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 (Output omitted) ``` - 这个目录下的 `clang` 和 `clang++` 就类似于我们比较熟悉的 `gcc` 和 `g++`。这两个是可以直接运行进行编译源代码的可执行文件。 - - 当然,我们不能每次在需要编译程序的时候输入如此长的路径找到 `clang` 和 `clang++`,而更希望的是能够像 `apt` 那样在任何地方都可以直接运行。 - - 我们可以这样做: + 这个目录下的 `clang` 和 `clang++` 就类似于我们比较熟悉的 `gcc` 和 `g++`。这两个是可以直接运行进行编译源代码的可执行文件。当然,我们不能每次在需要编译程序的时候输入如此长的路径找到 `clang` 和 `clang++`,而更希望的是能够像 `apt` 那样在任何地方都可以直接运行。我们可以这样做: ```shell - $ # 将 clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04 目录下的所有内容复制到 /usr/local/ 下 + $ # 将 clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04 目录下的所有内容复制到 /usr/local/ 下。 $ sudo cp -R * /usr/local/ ``` @@ -466,13 +469,16 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 在上面的复制过程中,源目录和目标目录的两个 `bin` 目录会相互合并,`clang` 和 `clang++` 两个可执行文件也就被复制到了 `/usr/local/bin/` 目录中。这样子也就达到了我们希望能够在任意地方调用我们的可执行文件的目的。此外,在复制的时候 lib、doc 等文件夹也会和 `/usr/local` 下的对应目录合并,将 clang 的库和文档加到系统当中。 +!!! warning "有关手工获取的软件" + 对于手工从 Internet 或者其他来源获取到的软件,在使用前务必注意检查其完整性(例如检查压缩文件的 hash 和官方网站上提供的是否一致)和安全性。运行有问题的程序,或者特别是安装有问题的程序(例如上面那样安装到 `/usr/local`),会导致系统安全受到损害。如非必要,请尽可能使用包管理器从官方软件源中安装软件。 + ### 更多用法 {#more-usage} 关于软件包管理器的更多用法可查看 [Pacman/Rosetta](https://wiki.archlinuxcn.org/wiki/Pacman/Rosetta) 页面,该页展示了一些流行的 Linux 发行版包管理器命令以及命令操作内容的对应关系。 ### 使用源代码编译安装 {#compiling-installation} -此部分内容请见拓展阅读:[编译安装](supplement.md)。 +此部分内容请见拓展阅读:[编译安装](supplement.md#compiling-installation)。 ## 操作文件与目录 {#operate-files-and-dirs} @@ -535,7 +541,7 @@ $ less FILE ### 编辑文件内容 {#nano} -Nano 是在很多机器上自带的命令行文本编辑器,相比于 vim 和 emacs 来说,对新手更加友好,不需要提前记忆复杂的键位。 +Nano 是在很多机器上自带的命令行文本编辑器,相比于 vim 和 emacs 来说,对新手更加友好,不需要提前记忆复杂的键位。如果 Nano 没有被默认安装,则可以通过 `apt` 来安装。 ```shell $ nano file.txt # 使用 nano 编辑 file.txt 文件(如果没有则创建) @@ -629,6 +635,9 @@ $ mv [OPTION] SOURCE... DIRECTORY | `-f`, `--force` | 覆盖目标地址同名文件 | | `-u`, `--update` | 仅当源文件比目标文件新才进行移动 | +!!! tip "重命名" + `mv` 命令可以作为对文件或目录重命名的方式。例如,`mv oldname newname` 可以将 `oldname` 的文件或目录重命名为 `newname`。 + ### 删除文件和目录 {#rm} ```shell @@ -665,6 +674,14 @@ $ rm [OPTION] FILE... $ rm -rf test1/ test2/ file1.txt ``` +!!! warning "注意目录拼写" + 使用 `rm` 删除时,请务必注意目录拼写。例如: + + ```shell + $ rm -rf /home/ustc/folder # 删除 folder + $ rm -rf / home/ustc/folder # 删除根目录下的所有文件和 home/ustc/folder 及其中的文件:这很危险! + ``` + ### 创建目录 {#mkdir} ```shell diff --git a/docs/Ch04/index.md b/docs/Ch04/index.md index eaaf615d..b391d4de 100644 --- a/docs/Ch04/index.md +++ b/docs/Ch04/index.md @@ -30,7 +30,7 @@ icon: material/chip ## 进程 {#process} -在导言中提到的「桌面环境、浏览器、聊天软件、办公软件、游戏、终端,以及后台运行着的系统服务」,它们都是进程。简单而不太严谨地来说,进程就是正在运行的程序:当我们启动一个程序的时候,操作系统会从硬盘中读取程序文件,将程序内容加载入内存中,之后 CPU 就会执行这个程序。 +在导言中提到的「桌面环境、浏览器、聊天软件、办公软件、游戏、终端,以及后台运行着的系统服务」,它们都是进程。简单而不太严谨地来说,进程就是已被载入的程序:当我们启动一个程序的时候,操作系统会从硬盘中读取程序文件,将程序内容加载入内存中,之后 CPU 就会执行这个程序,也就能看到一个“进程”。 进程是现代操作系统中必不可少的概念。在 Windows 中,我们可以使用「任务管理器」查看系统运行中的进程;Linux 中同样也有进程的概念。下面我们简单介绍 Linux 中的进程。 From 45bb77fead48b774fd1345e27667434d3c30bbfa Mon Sep 17 00:00:00 2001 From: luojh Date: Wed, 5 Mar 2025 19:03:16 +0800 Subject: [PATCH 02/14] prettier fix --- docs/Ch03/index.md | 10 +++++----- package-lock.json | 17 ++++++++++------- package.json | 15 +++++++-------- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index 80a0d003..c4e22fd9 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -149,7 +149,7 @@ Do you want to continue? [Y/n] 具体有关权限的知识点将在[第五章](../Ch05/index.md)展开。 !!! tip "不确认安装" - 如果不希望 `apt` 询问是否安装,可以使用 +如果不希望 `apt` 询问是否安装,可以使用 ```bash apt install -y <软件包> @@ -470,7 +470,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 在上面的复制过程中,源目录和目标目录的两个 `bin` 目录会相互合并,`clang` 和 `clang++` 两个可执行文件也就被复制到了 `/usr/local/bin/` 目录中。这样子也就达到了我们希望能够在任意地方调用我们的可执行文件的目的。此外,在复制的时候 lib、doc 等文件夹也会和 `/usr/local` 下的对应目录合并,将 clang 的库和文档加到系统当中。 !!! warning "有关手工获取的软件" - 对于手工从 Internet 或者其他来源获取到的软件,在使用前务必注意检查其完整性(例如检查压缩文件的 hash 和官方网站上提供的是否一致)和安全性。运行有问题的程序,或者特别是安装有问题的程序(例如上面那样安装到 `/usr/local`),会导致系统安全受到损害。如非必要,请尽可能使用包管理器从官方软件源中安装软件。 +对于手工从 Internet 或者其他来源获取到的软件,在使用前务必注意检查其完整性(例如检查压缩文件的 hash 和官方网站上提供的是否一致)和安全性。运行有问题的程序,或者特别是安装有问题的程序(例如上面那样安装到 `/usr/local`),会导致系统安全受到损害。如非必要,请尽可能使用包管理器从官方软件源中安装软件。 ### 更多用法 {#more-usage} @@ -636,7 +636,7 @@ $ mv [OPTION] SOURCE... DIRECTORY | `-u`, `--update` | 仅当源文件比目标文件新才进行移动 | !!! tip "重命名" - `mv` 命令可以作为对文件或目录重命名的方式。例如,`mv oldname newname` 可以将 `oldname` 的文件或目录重命名为 `newname`。 +`mv` 命令可以作为对文件或目录重命名的方式。例如,`mv oldname newname` 可以将 `oldname` 的文件或目录重命名为 `newname`。 ### 删除文件和目录 {#rm} @@ -675,8 +675,8 @@ $ rm [OPTION] FILE... ``` !!! warning "注意目录拼写" - 使用 `rm` 删除时,请务必注意目录拼写。例如: - +使用 `rm` 删除时,请务必注意目录拼写。例如: + ```shell $ rm -rf /home/ustc/folder # 删除 folder $ rm -rf / home/ustc/folder # 删除根目录下的所有文件和 home/ustc/folder 及其中的文件:这很危险! diff --git a/package-lock.json b/package-lock.json index e685da07..28c02b3f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,27 +9,30 @@ "version": "0.0.1", "license": "CC BY-SA 4.0", "devDependencies": { - "prettier": "^2.5.1" + "prettier": "^2.8.8" } }, "node_modules/prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } } }, "dependencies": { "prettier": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz", - "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true } } diff --git a/package.json b/package.json index fa42e291..2c4f9be3 100644 --- a/package.json +++ b/package.json @@ -3,20 +3,19 @@ "version": "0.0.1", "description": "Prettier package.json for ustclug Linux 101 website", "scripts": { - "check": "prettier . --check", - "fix": "prettier . --write" + "check": "prettier . --check", + "fix": "prettier . --write" }, "repository": { - "type": "git", - "url": "git+https://github.com/ustclug/Linux101-docs.git" + "type": "git", + "url": "git+https://github.com/ustclug/Linux101-docs.git" }, "license": "CC BY-SA 4.0", "bugs": { - "url": "https://github.com/ustclug/Linux101-docs/issues" + "url": "https://github.com/ustclug/Linux101-docs/issues" }, "homepage": "https://101.lug.ustc.edu.cn", "devDependencies": { - "prettier": "^2.5.1" + "prettier": "^2.8.8" } - } - \ No newline at end of file +} From 59b4495182fb96182d2816c441cf5d580b285049 Mon Sep 17 00:00:00 2001 From: luojh Date: Wed, 5 Mar 2025 19:11:37 +0800 Subject: [PATCH 03/14] Fix indent by prettier --- docs/Ch03/index.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index c4e22fd9..e5d04b81 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -149,7 +149,8 @@ Do you want to continue? [Y/n] 具体有关权限的知识点将在[第五章](../Ch05/index.md)展开。 !!! tip "不确认安装" -如果不希望 `apt` 询问是否安装,可以使用 + + 如果不希望 `apt` 询问是否安装,可以使用 ```bash apt install -y <软件包> @@ -470,7 +471,8 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 在上面的复制过程中,源目录和目标目录的两个 `bin` 目录会相互合并,`clang` 和 `clang++` 两个可执行文件也就被复制到了 `/usr/local/bin/` 目录中。这样子也就达到了我们希望能够在任意地方调用我们的可执行文件的目的。此外,在复制的时候 lib、doc 等文件夹也会和 `/usr/local` 下的对应目录合并,将 clang 的库和文档加到系统当中。 !!! warning "有关手工获取的软件" -对于手工从 Internet 或者其他来源获取到的软件,在使用前务必注意检查其完整性(例如检查压缩文件的 hash 和官方网站上提供的是否一致)和安全性。运行有问题的程序,或者特别是安装有问题的程序(例如上面那样安装到 `/usr/local`),会导致系统安全受到损害。如非必要,请尽可能使用包管理器从官方软件源中安装软件。 + + 对于手工从 Internet 或者其他来源获取到的软件,在使用前务必注意检查其完整性(例如检查压缩文件的 hash 和官方网站上提供的是否一致)和安全性。运行有问题的程序,或者特别是安装有问题的程序(例如上面那样安装到 `/usr/local`),会导致系统安全受到损害。如非必要,请尽可能使用包管理器从官方软件源中安装软件。 ### 更多用法 {#more-usage} @@ -636,7 +638,8 @@ $ mv [OPTION] SOURCE... DIRECTORY | `-u`, `--update` | 仅当源文件比目标文件新才进行移动 | !!! tip "重命名" -`mv` 命令可以作为对文件或目录重命名的方式。例如,`mv oldname newname` 可以将 `oldname` 的文件或目录重命名为 `newname`。 + + `mv` 命令可以作为对文件或目录重命名的方式。例如,`mv oldname newname` 可以将 `oldname` 的文件或目录重命名为 `newname`。 ### 删除文件和目录 {#rm} @@ -675,7 +678,8 @@ $ rm [OPTION] FILE... ``` !!! warning "注意目录拼写" -使用 `rm` 删除时,请务必注意目录拼写。例如: + + 使用 `rm` 删除时,请务必注意目录拼写。例如: ```shell $ rm -rf /home/ustc/folder # 删除 folder From 7d52cd5dd57ae027d46b8b132c3425765918b9c4 Mon Sep 17 00:00:00 2001 From: luojh Date: Thu, 6 Mar 2025 10:30:23 +0800 Subject: [PATCH 04/14] Fix taoky's PR suggestions. Add fix to ch04. --- docs/Ch01/index.md | 11 +++++------ docs/Ch01/supplement.md | 2 +- docs/Ch02/index.md | 8 ++++++-- docs/Ch03/index.md | 12 +++++++----- docs/Ch04/index.md | 18 ++++++++++-------- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/Ch01/index.md b/docs/Ch01/index.md index 00478b29..0ee08899 100644 --- a/docs/Ch01/index.md +++ b/docs/Ch01/index.md @@ -76,11 +76,10 @@ Linux 内核并不是一个完整的操作系统,因为它过于精简,单 进入 GNU/Linux 世界,便意味着与 GNU 自由软件打交道。先看看一堆字母 g 开头的应用程序: - - `gcc`: GNU 的 C 和 C++ 编译器 - - `gdb`: GNU 程序调试器 - - `gzip`: gz 格式压缩与解压缩工具 - - GNOME: 隶属于 GNU 项目的桌面环境 - - `gimp`: GNU 图像编辑工具 + - GCC: GNU 的 C 和 C++ 编译器 + - GDB: GNU 程序调试器 + - Gzip: gz 格式压缩与解压缩工具 + - GIMP: GNU 图像编辑工具 它们的首字母 g 都是 GNU 的缩写(当然不是所有以 g 开头的都是 GNU 软件)。许多 Linux 上的系统管理命令虽然未必以 g 开头,但都属于自由软件;还有[更多优秀的软件](https://www.gnu.org/software/),被自由软件爱好者维护、分享……选择 Linux,很大程度上是一种对极客精神与开源文化的认同。 @@ -194,7 +193,7 @@ Windows Server 图标 Android TV 图标 {: .caption } -## 让自己的计算机用上 Linux {#use-linux} @@ +## 让自己的计算机用上 Linux {#use-linux} 有很多尚未接触过 Linux 的读者看到这里可能已经在期待或者计划让自己尽快开始使用 Linux 了。事实上,如果把 Linux 看作一个领域,那它的确是一个重视实践的领域。而且出于学习目的,在阅读本书未来的章节时在手头准备一个随时可用的 Linux 发行版是十分关键和有益的。因此,本书**强烈建议各位读者在本机安装一个属于自己的 Linux 发行版**,以供随时实践。 diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md index a32abc3f..151d19d0 100644 --- a/docs/Ch01/supplement.md +++ b/docs/Ch01/supplement.md @@ -400,7 +400,7 @@ ustc@ustclug-linux101:~$ !!! warning - 请注意,**WSL 可能将主机的文件系统挂载在子系统的某个位置**。这在通常情况下会使得文件共享更加方便,但也可能导致在子系统中执行文件操作(例如文件删除)时错误地操作了主机上的文件。 + 请注意,**WSL 可能将主机的文件系统挂载在子系统的某个位置 (例如将主机的 `C:\` 挂载在 `/mnt/c/`)**。这在通常情况下会使得主机和 WSL 之间的文件共享更加方便,但也可能导致在子系统中执行文件操作(例如文件删除)时错误地操作了主机上的文件。 ### WSL 1 {#wsl1} diff --git a/docs/Ch02/index.md b/docs/Ch02/index.md index 42dd10e2..33e71437 100644 --- a/docs/Ch02/index.md +++ b/docs/Ch02/index.md @@ -305,7 +305,7 @@ $ mv /path/to/source/file.txt /path/to/dest/ 对于不太熟悉命令行的用户来说,路径的概念可能会在最开始带来一些困惑。这里做一些简单的介绍。 - 在 Windows 系统下,路径是以反斜杠 `\` 分隔的,例如: + 在 Windows 系统下,路径是以反斜杠 `\` 分隔的(Windows 系统也可以使用 `/` 分隔路径),例如: ``` C:\Windows\explorer.exe @@ -346,7 +346,7 @@ $ mv /path/to/source/file.txt /path/to/dest/ 每个正在运行中的进程(包括 Shell)都有自己的「当前工作目录」(当前所在的目录),进程可以切换自己的当前工作目录,以上的相对路径都是相对于当前工作目录的。可以发现,不管当前工作目录在哪里,绝对路径对应的文件都是一致的,而相对路径对应的文件就会随着当前工作目录的变化而变化。 - 特别地,用户的主目录(一般是 `/home/<用户名>`)可以被简写为 `~`。 + 特别地,用户的主目录(一般是 `/home/<用户名>`)可以被简写为 `~`。例如,`~/work/test.c` 可能是 `/home/ustc/work/test.c` 的缩写。 #### 自动化脚本 {#shell-automation} @@ -378,6 +378,10 @@ rm main.out 和其他地方不一样,在 Shell 中运行程序时,程序名(`main.out`)前面必须有 `./`。这是因为因为我们的工作目录不包含在环境变量(`$PATH`)中,故如果不加 `./` 则系统会找不到程序。系统中安装的程序(例如 `gcc`)一般会放在 `$PATH` 环境变量中包含了的路径下,故运行它们不需要使用 `./`。 +!!! tip "为何需要加上 `./`" + + 一个简单的原因是,如果像 Windows 那样直接输入可执行文件的名称就能运行程序的话,攻击者可能将恶意代码写入到用户工作目录下以一些常见的命令(例如 `ls` 和 `cat`)为名称的文件中,并加入执行(`x`)权限。不知情的用户执行这些命令就会导致恶意代码的运行。而 Linux 系统下不加 `./` 运行的是 `PATH` 环境变量中列出的目录下的可执行文件,这些位置一般只有 `root` 用户能写入,避免了上面的问题。此外另一个原因是,这还避免了用户的程序和系统中安装的程序因为重名而冲突。 + 之后我们直接输入 ```shell diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index e5d04b81..4dec645e 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -148,14 +148,16 @@ Do you want to continue? [Y/n] 具体有关权限的知识点将在[第五章](../Ch05/index.md)展开。 -!!! tip "不确认安装" +!!! tip "跳过安装确认" - 如果不希望 `apt` 询问是否安装,可以使用 + 如果不希望 `apt` 询问是否安装,可以使用: ```bash apt install -y <软件包> ``` + 这在编写无交互的**自动化脚本**时特别好用(例如那些能自动安装一系列依赖包的安装脚本)。但是,在这些脚本中,建议使用 `apt-get`,因为相对古老的 `apt-get` 的命令行参数比较稳定,而 `apt` 则有可能会变化,这对脚本的向后兼容性是不利的。 + #### 官方软件源镜像 {#software-sources} 通过 apt 安装的软件都来源于相对应的软件源,每个 Linux 发行版一般都带有官方的软件源,在官方的软件源中已经包含了丰富的软件,apt 的软件源列表在 `/etc/apt/sources.list` 下。 @@ -661,19 +663,19 @@ $ rm [OPTION] FILE... * 删除 `file1.txt` 文件: - ``` + ```shell $ rm file1.txt ``` * 删除 `test` 目录及其下的所有文件: - ``` + ```shell $ rm -r test/ ``` * 删除 `test1/`、`test2/`、`file1.txt` 这些文件、目录。其中,这些文件或者目录可能不存在、写保护或者没有权限读写: - ``` + ```shell $ rm -rf test1/ test2/ file1.txt ``` diff --git a/docs/Ch04/index.md b/docs/Ch04/index.md index b391d4de..98412fad 100644 --- a/docs/Ch04/index.md +++ b/docs/Ch04/index.md @@ -30,7 +30,7 @@ icon: material/chip ## 进程 {#process} -在导言中提到的「桌面环境、浏览器、聊天软件、办公软件、游戏、终端,以及后台运行着的系统服务」,它们都是进程。简单而不太严谨地来说,进程就是已被载入的程序:当我们启动一个程序的时候,操作系统会从硬盘中读取程序文件,将程序内容加载入内存中,之后 CPU 就会执行这个程序,也就能看到一个“进程”。 +在导言中提到的「桌面环境、浏览器、聊天软件、办公软件、游戏、终端,以及后台运行着的系统服务」,它们都是进程。简单而不太严谨地来说,进程就是已被载入的程序:当我们启动一个程序的时候,操作系统会从硬盘中读取程序文件,将程序内容加载入内存中,之后 CPU 就会执行这个程序,也就能看到一个「进程」。 进程是现代操作系统中必不可少的概念。在 Windows 中,我们可以使用「任务管理器」查看系统运行中的进程;Linux 中同样也有进程的概念。下面我们简单介绍 Linux 中的进程。 @@ -38,7 +38,7 @@ icon: material/chip #### htop {#htop} -Htop 可以简单方便查看当前运行的所有进程,以及系统 CPU、内存占用情况与系统负载等信息。 +htop 可以简单方便查看当前运行的所有进程,以及系统 CPU、内存占用情况与系统负载等信息。 使用鼠标与键盘都可以操作 htop。Htop 界面的最下方是一些选项,使用鼠标点击或按键盘的 ++"F1"++ 至 ++"F10"++ 功能键可以选择这些功能,常用的功能例如搜索进程(++"F3"++, Search)、过滤进程(++"F4"++, Filter,使得界面中只有满足条件的进程)、切换树形结构/列表显示(++"F5"++, Tree/List)等等。 @@ -79,7 +79,7 @@ root 14 0.0 0.0 0 0 ? S 02:33 0:00 [migration/0] 按照 PID 排序时,我们可以观察系统启动的过程。Linux 系统内核从引导程序接手控制权后,开始内核初始化,随后变为 **init\_task**,初始化自己的 PID 为 0。随后创建出 1 号进程(init 程序,目前一般为 systemd)衍生出用户空间的所有进程,创建 2 号进程 kthreadd 衍生出所有内核线程。随后 0 号进程成为 idle 进程,1 号、2 号并非特意预留,而是产生进程的自然顺序使然。 - 由于 kthreadd 运行于内核空间,故需按大写 K(++"Shift"++ + ++"k"++)键显示内核进程后才能看到。然而无论如何也不可能在 htop 中看到 0 号进程本体,只能发现 1 号和 2 号进程的 PPID 是 0。 + 由于 kthreadd 运行于内核空间,故需按大写 K(++"Shift"++ + ++"k"++)键显示内核进程后才能看到。然而无论如何也不可能在 htop 中看到 0 号进程本体,只能发现 1 号和 2 号进程的 PPID (Parent PID) 是 0。 ### 进程优先级与状态 {#process-priority-and-stat} @@ -87,7 +87,7 @@ root 14 0.0 0.0 0 0 ? S 02:33 0:00 [migration/0] #### 优先级与 nice 值 {#nice} -有了进程,谁先运行?谁给一点时间就够了,谁要占用大部分 CPU 时间?这又是如何决定的?这些问题之中体现着优先权的概念。如果说上面所介绍的的那些进程属性描述了进程的控制信息,那么**优先级**则反映操作系统调度进程的手段。在 htop 的显示中有两个与优先级有关的值:Priority(PRI)和 **nice(NI)**。以下主要介绍用户层使用的 nice 值。 +有了进程,谁先运行?谁给一点时间就够了,谁要占用大部分 CPU 时间?这又是如何决定的?这些问题之中体现着优先权的概念。如果说上面所介绍的的那些进程属性描述了进程的控制信息,那么**优先级**则反映操作系统调度进程的手段。在 htop 的显示中有两个与优先级有关的值:**Priority(PRI)** 和 **nice(NI)**。以下主要介绍用户层使用的 nice 值。 Nice 值越高代表一个进程对其它进程越 "nice"(友好),对应的优先级也就更低。Nice 值最高为 19,最低为 -20。通常,我们运行的程序的 nice 值为 0。我们可以打开 htop 观察与调整每个进程的 nice 值。 @@ -114,7 +114,9 @@ $ renice -n 10 -p 12345 # 设置 PID 为 12345 的进程的 nice 值为 10 在实际的 Linux 系统中,进程的状态分类要稍微复杂一些。在 htop 中,按下 H 键到帮助页,可以看到对进程状态的如下描述: - Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep +``` +Status: R: running; S: sleeping; T: traced/stopped; Z: zombie; D: disk sleep +``` 其中 R 状态对应上文的运行和就绪态(即表明该程序可以运行),S 和 D 状态对应上文阻塞态。 @@ -345,7 +347,7 @@ $ tmux 在没有使用 tmux 时,我们无法将命令行界面状态保留下一次登录。这其中最关键的矛盾在于,只要终端关闭,当前 session 下所有进程默认结束(当然也可以像上面实验那样不响应 SIGHUP)。解决这个问题的思路之一便是在 SSH 断开时保证终端的存在。而 tmux 即可做到这一点。 - tmux 做了什么呢?它把在上面运行的所有 shell 托管在一个单独的会话中,与当前终端脱离。并且每一个 shell 有不同的 pty。而当前终端下的 tmux,仅仅是一个客户端,需要连接哪个 session,就使用 attach 命令让客户端与服务程序通信,把客户端所在终端的输入定向到由服务端掌控的被绿框框选的特定终端中,从而完成对各个 pane 的交互。 + tmux 做了什么呢?它把在上面运行的所有 shell 托管在一个单独的会话中,与当前终端脱离。并且每一个 shell 有不同的 pty (pseudoterminal)。而当前终端下的 tmux,仅仅是一个客户端,需要连接哪个 session,就使用 attach 命令让客户端与服务程序通信,把客户端所在终端的输入定向到由服务端掌控的被绿框框选的特定终端中,从而完成对各个 pane 的交互。 ## 服务 {#service} @@ -401,7 +403,7 @@ $ systemctl status !!! tip "Less 翻页器" - 当我们在终端中使用 systemd 组件时,如果输出内容较多,systemd 会使用 less 作为翻页器(Pager),方便我们阅读。 + 当我们在终端中使用 systemd 组件时,如果输出内容较多,systemd 会使用 `less` 作为翻页器(Pager),方便我们阅读。 上面命令所列出的是系统中正在运行的服务,若想了解全部服务内容,可以运行 `systemctl list-units` 来查看。该命令将显示所有 systemd 管理的单元,同时右面还会附上一句注释来表明该服务的任务。 @@ -614,7 +616,7 @@ crontab 的配置格式很简单,对于配置文件的每一行,前半段为 # 每天凌晨 3 点 05 分将查询到的公网 ip 发送到自己的邮箱 (假设半夜 3 点重新拨号) ``` -如果这里解释得尚不清楚,可以访问 ,该网站可以将配置文件中的时间字段翻译为日常所能理解的时间表示。 +如果这里解释得尚不清楚,可以访问 ,该网站可以将配置文件中的时间字段翻译为日常所能理解的时间表示。此外,还可以查看 crontab 的 man 文档(`man 5 crontab`)。 ![crontab](images/crontab.gif) From 2fe652104f91b504443bf658099d58b67587a247 Mon Sep 17 00:00:00 2001 From: luojh Date: Thu, 6 Mar 2025 11:05:51 +0800 Subject: [PATCH 05/14] Ch05 to Ch06 (partial) modifications, and add some content --- docs/Ch03/index.md | 2 +- docs/Ch05/index.md | 12 +++++++++--- docs/Ch05/solution.md | 29 +++++++++++++++++++++++++++-- docs/Ch06/index.md | 8 ++++++++ 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index 4dec645e..5197ab9b 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -441,7 +441,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 bin include lib libexec share ``` - 一般而言,软件的可执行文件都位于 bin 目录下: + 一般而言,软件的可执行文件都位于 `bin` 目录下: ```shell $ cd bin diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index ca6cd6df..7a91b9d5 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -64,7 +64,7 @@ icon: material/account-group !!! danger "谨慎使用 `root` 用户权限执行命令!" - 我们知道,`root` 用户可以对系统做极其危险的操作。当使用 `root` 权限执行命令时(如使用 `sudo`),一定要**小心、谨慎,理解命令的含义之后再按下回车**。**请不要复制网络上所谓的「Linux 优化命令」等**,以 `root` 权限执行,否则**可能会带来灾难性的后果**。 + 我们知道,`root` 用户可以对系统做极其危险的操作。当使用 `root` 权限执行命令时(如使用 `sudo`),一定要**小心、谨慎,理解命令的含义之后再按下回车**。**请不要复制网络上所谓的「Linux 优化命令」等**,以 `root` 权限执行,否则**可能会带来灾难性的后果**。除了复制外,直接通过 `curl` 等工具获取脚本然后通过管道传给 `sh` 执行也是非常危险的操作。运行脚本前,请务必先仔细检查要执行的脚本内容。 以下是一些会对系统带来毁灭性破坏的例子。 **再重复一遍,不要执行下面的命令!** @@ -126,7 +126,7 @@ uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) ??? example "修改 `sudo` 配置的例子:无密码执行 `sudo` (\*)" - `sudo` 的配置存储在 `/etc/sudoers` 文件中,仅 `root` 用户有权查看和修改。**不要直接修改此文件。**对这个文件的任何修改,都应该使用 `visudo` 这个命令去做。 + `sudo` 的配置存储在 `/etc/sudoers` 文件中,仅 `root` 用户有权查看和修改。**不要直接修改此文件:对这个文件的任何修改,都应该使用 `visudo` 这个命令完成**。 默认的 Ubuntu 配置中,安装时创建的用户在 `sudo` 用户组(下文会提到这个概念)中。在 `sudoers` 文件中,它的配置像这样: @@ -311,6 +311,8 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder (可以执行了) ``` + 再次强调,**在运行任何来自网络的程序或脚本前,请先检查其内容**,特别是使用高权限的用户执行时。 + ## 文件系统层次结构 {#fhs} 相信到现在你应该已经发现了:Linux 下文件系统的结构和 Windows 的很不一样。在 Windows 中,分区以盘符的形式来标识(如「C 盘」、「D 盘」),各个分区的分界线是很明确的。在系统所在的分区(一般为 C 盘)中,存储着程序文件 (`Program Files`),系统运行需要的文件 (`Windows`),用户文件 (`Users`) 等。这种组织形式源于 DOS 和早期的 Windows,并一直传承下来。 @@ -414,7 +416,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder : 存储会发生变化的程序相关文件。例如下面的目录: - `/var/log`:存储程序的日志文件。 - - `/var/lib`:存储程序自身的状态信息(如 lock file)。 + - `/var/lib`:存储程序自身的状态信息(如 lock file)。这个目录和 `library` 的关系并不大。 - `/var/run`:存储程序运行时的数据(部分发行版会将该目录符号链接到 `/run` 目录)。 - `/var/spool`:存储「等待进一步处理」的程序数据。 @@ -440,6 +442,10 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder 当需要浏览仅 `root` 用户可查看的目录时,很多人的第一反应是 `sudo cd xxx`,但最终失败了。尝试解释这样做不可行的原因。 +!!! question "普通用户运行 `reboot`" + + 前面说过,`reboot` 这类程序只能由 `root` 用户运行。为何普通用户在 Shell 中直接输入 `reboot` 不行? + ## 引用来源 {#references .no-underline} - [维基百科上的 Passwd 词条(英语)](https://en.wikipedia.org/wiki/Passwd) diff --git a/docs/Ch05/solution.md b/docs/Ch05/solution.md index 5410e25e..c9c97bba 100644 --- a/docs/Ch05/solution.md +++ b/docs/Ch05/solution.md @@ -22,7 +22,7 @@ icon: material/tooltip-question ??? info "解答" - ``` + ```shell $ /usr/sbin/nologin This account is currently not available. $ /bin/false @@ -62,7 +62,7 @@ icon: material/tooltip-question 如果你真的去执行 `sudo cd`,那么会看到: - ``` + ```shell $ sudo cd a sudo: cd: command not found ``` @@ -70,3 +70,28 @@ icon: material/tooltip-question 这是因为,`cd` 是 shell 的**内建命令**,而不是某个具体的程序,而 `sudo` 的功能,是以其他用户 (一般是 root) 的身份执行程序。 那么 `cd` 可以实现成(外置的)程序吗?答案是不能:因为切换工作目录的系统调用 (`chdir()`) 只能切换当前的程序的工作目录。如果实现成了外置的程序,那么切换完退出之后,shell 的工作目录仍然不会变化。 + +## 普通用户运行 `reboot` + +??? info "解答" + + 这里可不止权限不足的问题。事实上,用普通用户执行 `reboot`,你会看到: + + ```shell + $ reboot + -bash: reboot: command not found + ``` + + 这是为什么呢?这是因为,`reboot` 存在于 `/sbin` 下,而这个目录并不在普通用户登录后默认的 `PATH` 环境变量中。也就是说,Shell 并不会去 `/sbin` 中查找 `reboot`,自然就会提示 `command not found`。如果执行 + + ```shell + $ /sbin/reboot + ``` + + 或者 + + ```shell + $ systemctl reboot -i # 另一种重启的方法 + ``` + + 就会因为有其他用户已登录,或者权限不足而失败。其他的命令也是类似的原因,只能由 `root` 执行。 diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md index 63f5051d..b6606c81 100644 --- a/docs/Ch06/index.md +++ b/docs/Ch06/index.md @@ -166,6 +166,10 @@ cURL (`curl`) 是一个利用 URL 语法在命令行下工作的文件传输工 $ curl -I "http://cn.bing.com" ``` +!!! warning "关于从 Internet 获取的脚本" + + 直接通过 `curl` 或者 `wget` 等工具从 Internet 获取脚本然后通过管道传给 `sh` 执行是非常危险的操作。运行脚本前,请确保脚本是从正确的地址下载的,并仔细检查要执行的脚本内容。 + ### 其他 {#download-others} 除了 Wget、cURL,还有 mwget(多线程版本 wget)、Axel、Aria2(支持 BT 协议、支持 JSON-RPC 和 XML-RPC 接口远程调用)之类下载工具,其中 Aria2 在 Windows 下使用也很广泛。 @@ -334,6 +338,10 @@ drwxr-xr-x 2 ustc ustc 4096 11月 17 20:45 模板/ 部分 shell 会自带一些 alias,例如 [fish 中的 `ll` 就是 `ls -lh` 的别名](https://github.com/fish-shell/fish-shell/blob/daf96a35b57f52eea19302f615283e7c1486ab8c/share/functions/ll.fish#L5)。特别地,Windows 自带的 PowerShell 中的 alias 存在一些争议,例如其对 `curl` 的 alias 实际上是 `Invoke-WebRequest`,而这个命令和上文介绍的 curl 的行为完全不同,给用户带来了困惑。 +!!! warning "alias 可能带来的问题" + + 如果将常见命令(例如 `cat`)通过 alias 映射到包含恶意代码的可执行文件上,则可能导致这些恶意代码被意外地执行。 + ### Bash 脚本的运行 {#run-bash-script} 可以使用几种方法运行 Bash 脚本: From 0a91da8c57609c1fe57bf32c48fa6e678ae3c100 Mon Sep 17 00:00:00 2001 From: luojh Date: Sun, 9 Mar 2025 20:10:35 +0800 Subject: [PATCH 06/14] Fix that in @taoky's PR. Also add something in sudo --- docs/Ch01/supplement.md | 4 ++-- docs/Ch05/index.md | 6 +++--- docs/Ch05/solution.md | 4 ++-- docs/Ch06/index.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md index 151d19d0..4195281f 100644 --- a/docs/Ch01/supplement.md +++ b/docs/Ch01/supplement.md @@ -398,9 +398,9 @@ ustc@ustclug-linux101:~$ 你可能会在老版本的 Windows 上注意到,在「添加与删除 Windows 组件」的地方,有一个「基于 UNIX 的应用程序子系统」。需要注意的是,这个选项和 WSL 没有任何关系。它也无法直接运行 Linux 或者其他 UNIX 的程序。并且,这个子系统目前也已经停止了开发。 -!!! warning +!!! warning "WSL 对宿主机文件系统的挂载" - 请注意,**WSL 可能将主机的文件系统挂载在子系统的某个位置 (例如将主机的 `C:\` 挂载在 `/mnt/c/`)**。这在通常情况下会使得主机和 WSL 之间的文件共享更加方便,但也可能导致在子系统中执行文件操作(例如文件删除)时错误地操作了主机上的文件。 + 请注意,**WSL 可能将主机的文件系统挂载在子系统的某个位置(例如将主机的 `C:\` 挂载在 `/mnt/c/`)**。这在通常情况下会使得主机和 WSL 之间的文件共享更加方便,但也可能导致在子系统中执行文件操作(例如文件删除)时错误地操作了主机上的文件。 ### WSL 1 {#wsl1} diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index 7a91b9d5..3491a68f 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -135,7 +135,7 @@ uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) %sudo ALL=(ALL:ALL) ALL ``` - 将配置行修改成以下即可。 + 将配置行修改成以下即可。注意,`%sudo` 的后面是一个制表符(TAB),不是一系列空格。 ``` %sudo ALL=(ALL:ALL) NOPASSWD:ALL @@ -311,7 +311,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder (可以执行了) ``` - 再次强调,**在运行任何来自网络的程序或脚本前,请先检查其内容**,特别是使用高权限的用户执行时。 + ## 文件系统层次结构 {#fhs} @@ -444,7 +444,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder !!! question "普通用户运行 `reboot`" - 前面说过,`reboot` 这类程序只能由 `root` 用户运行。为何普通用户在 Shell 中直接输入 `reboot` 不行? + 前面说过,`reboot` 这类程序只能由 `root` 用户运行。为何普通用户在 Shell 中直接输入 `reboot` 不能重启系统? ## 引用来源 {#references .no-underline} diff --git a/docs/Ch05/solution.md b/docs/Ch05/solution.md index c9c97bba..fa2f6fa0 100644 --- a/docs/Ch05/solution.md +++ b/docs/Ch05/solution.md @@ -75,14 +75,14 @@ icon: material/tooltip-question ??? info "解答" - 这里可不止权限不足的问题。事实上,用普通用户执行 `reboot`,你会看到: + 这里可能不止权限不足的问题。事实上,在 Debian 系统上,用普通用户执行 `reboot`,你会看到: ```shell $ reboot -bash: reboot: command not found ``` - 这是为什么呢?这是因为,`reboot` 存在于 `/sbin` 下,而这个目录并不在普通用户登录后默认的 `PATH` 环境变量中。也就是说,Shell 并不会去 `/sbin` 中查找 `reboot`,自然就会提示 `command not found`。如果执行 + 这是为什么呢?这是因为,`reboot` 存在于 `/sbin` 下,而这个目录并不在普通用户登录后默认的 `PATH` 环境变量中(但 Ubuntu 下则不一样:`/sbin` 也在普通用户的 `PATH` 环境变量中)。也就是说,Shell 并不会去 `/sbin` 中查找 `reboot`,自然就会提示 `command not found`。如果执行 ```shell $ /sbin/reboot diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md index b6606c81..997f7e7a 100644 --- a/docs/Ch06/index.md +++ b/docs/Ch06/index.md @@ -168,7 +168,7 @@ cURL (`curl`) 是一个利用 URL 语法在命令行下工作的文件传输工 !!! warning "关于从 Internet 获取的脚本" - 直接通过 `curl` 或者 `wget` 等工具从 Internet 获取脚本然后通过管道传给 `sh` 执行是非常危险的操作。运行脚本前,请确保脚本是从正确的地址下载的,并仔细检查要执行的脚本内容。 + 直接通过 `curl` 或者 `wget` 等工具从 Internet 获取脚本然后通过管道传给 `sh` 等 Shell 执行是非常危险的操作。运行脚本前,请确保脚本是从正确的地址下载的,并仔细检查要执行的脚本内容。 ### 其他 {#download-others} From 4989efaba291946f1b188654ef6e9647c5bb77b3 Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 15 Mar 2025 19:22:13 +0800 Subject: [PATCH 07/14] Ch08: Redirect registry mirror guide to yeasy gitbook --- docs/Ch08/index.md | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index 628a36cb..8bae742e 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -74,39 +74,9 @@ $ sudo adduser 用户名 docker ### 配置 Registry Mirror(可选,推荐) {#setup-registry-mirror} -!!! warning "本节内容可能随时过时" +!!! tip "本节操作请参考其他文档" - 维护公共使用的 Docker Hub pull-through cache (registry mirror) 需要**非常高的运维成本**,因而有很多服务在之前可以使用,但是之后被迫关闭或转为非公开。你可以参考 获取目前可能可以使用的 registry mirror(镜像加速器)。 - -Docker 默认从 Docker Hub 上拖取所需要的镜像。但由于网络原因,拖取的过程可能会比较慢。一些服务在中国提供了 Docker Hub 的镜像(反代缓存)。以下内容以网易云与百度云为例。 - -为了使用这些 Docker Hub 镜像,在 Debian/Ubuntu 上,可以编辑 `/etc/docker/daemon.json` 文件(如果文件不存在,请新建一个),写入以下内容。 - -```json -{ - "registry-mirrors": [ - "https://hub-mirror.c.163.com", - "https://mirror.baidubce.com" - ] -} - -``` - -使用 `sudo systemctl restart docker` 命令重启 Docker 服务后,再次运行 `docker info` 命令,可以看到如下输出: - -```text - Registry Mirrors: - https://hub-mirror.c.163.com/ - https://mirror.baidubce.com/ -``` - -如果你看到了上面的输出,说明你的 Docker Registry Mirror 已经配置好了。 - -!!! info "如果你是科大校园网用户" - - 科大镜像站的 Docker Hub registry mirror 目前仅对校园网开放,地址为 `https://docker.mirrors.ustc.edu.cn/`。如果在使用以上获取的 registry mirror 时遇到问题,可以切换。需要注意由于 2020 年 11 月之后 Docker Hub 的访问速率限制,使用时可能会出现间歇性的问题。 - - 详细信息见科大镜像站 [Docker Hub 源使用帮助](https://mirrors.ustc.edu.cn/help/dockerhub.html)。 + 你可以参考 获取目前可能可以使用的 registry mirror。 ### 使用 Hello World 测试 Docker 安装 {#verify-docker-setup} From 9f885be3c76dc274e6ae0cf39efc67d112031637 Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 22:40:50 +0800 Subject: [PATCH 08/14] Change code block lang (shell -> console) for interactive commands --- docs/Ch01/supplement.md | 4 +-- docs/Ch02/index.md | 4 +-- docs/Ch02/supplement.md | 12 +++---- docs/Ch03/index.md | 76 ++++++++++++++++++++--------------------- docs/Ch04/index.md | 4 +-- docs/Ch04/solution.md | 12 +++---- docs/Ch05/index.md | 2 +- docs/Ch05/solution.md | 10 +++--- docs/Ch06/index.md | 30 ++++++++-------- docs/Ch06/solution.md | 2 +- docs/Ch07/supplement.md | 2 +- docs/Ch09/index.md | 2 +- 12 files changed, 80 insertions(+), 80 deletions(-) diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md index 4195281f..3ec966ad 100644 --- a/docs/Ch01/supplement.md +++ b/docs/Ch01/supplement.md @@ -520,7 +520,7 @@ $ sudo apt-get install ubuntu-desktop * 使用 Ubuntu 22.04 或 22.10:目前只有部分 daily build 版本可用。 * 在 Ubuntu 20.04 上**禁用 Wayland**: - ```bash + ```console $ sudo nano /etc/gdm3/custom.conf ``` @@ -532,7 +532,7 @@ $ sudo apt-get install ubuntu-desktop 接下来自行通过 HWE 升级 Ubuntu 20.04 的内核至 5.15: - ```bash + ```console $ sudo apt install --install-recommends linux-generic-hwe-20.04 ``` diff --git a/docs/Ch02/index.md b/docs/Ch02/index.md index 33e71437..9fcd7f25 100644 --- a/docs/Ch02/index.md +++ b/docs/Ch02/index.md @@ -412,7 +412,7 @@ $ sh run.sh 使用以下命令安装(软件的安装将在[第三章](../Ch03/index.md)详细介绍): - ```shell + ```console $ sudo apt install cmatrix ``` @@ -552,7 +552,7 @@ $ sudo bash wordpress.sh 在本节之前的版本中,以上的命令是: - ```shell + ```console $ curl -fsSL https://101.lug.ustc.edu.cn/Ch02/wordpress.sh | sudo bash ``` diff --git a/docs/Ch02/supplement.md b/docs/Ch02/supplement.md index f5bc678f..d8e57e5b 100644 --- a/docs/Ch02/supplement.md +++ b/docs/Ch02/supplement.md @@ -42,7 +42,7 @@ $ sudo reboot 同理,如果你喜欢 KDE plasma 桌面,只需要执行 - ```shell + ```console $ sudo apt install kde-plasma-desktop $ sudo reboot ``` @@ -156,7 +156,7 @@ $ gnome-tweaks 再安装本地连接器: - ```shell + ```console $ sudo apt install chrome-gnome-shell ``` @@ -202,7 +202,7 @@ $ gnome-tweaks 命令行进入下载好的安装包所在文件夹,输入以下命令。注意替换「下载的包」为你的安装包名,例如如果下载的安装包名为 `ocs-url_3.1.0-0ubuntu1_amd64.deb`,则 `install` 后面的参数为 `./ocs-url_3.1.0-0ubuntu1_amd64.deb`。 - ```shell + ```console $ sudo apt install ./下载的包.deb ``` @@ -258,7 +258,7 @@ $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/t 如果遇到了网络连通性问题,可以使用以下替换命令: - ```shell + ```console $ REMOTE=https://mirrors.tuna.tsinghua.edu.cn/git/ohmyzsh.git sh -c "$(curl -fsSL https://mirrors.ustc.edu.cn/misc/ohmyzsh-install.sh)" ``` @@ -299,7 +299,7 @@ $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/t 当我们登录用户成功时: - ```shell + ```console $ sudo login ``` @@ -340,7 +340,7 @@ $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/t 然后: - ```shell + ```console $ sudo chmod +x /etc/update-motd.d/99-test ``` diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index 5197ab9b..c3411c00 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -217,7 +217,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 可以使用如下命令: - ```shell + ```console $ sudo sed -i 's|//.*archive.ubuntu.com|//mirrors.ustc.edu.cn|g' /etc/apt/sources.list ``` @@ -237,7 +237,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 1. 安装需要的的软件包 - ```shell + ```console $ sudo apt-get update # 更新本地的包列表 $ sudo apt-get install \ @@ -251,7 +251,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 这一步将 GPG Key 添加到系统目录中。GPG Key 用于验证软件源的完整性,如果下载的文件被篡改,GPG 签名验证会失败,从而系统不会继续进行安装操作,防止有问题的软件包进入系统。 - ```shell + ```console $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg ``` @@ -259,7 +259,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 为了方便维护,第三方的 APT 软件源一般都放在 `/etc/apt/sources.list.d/` 目录下(而非直接编辑 `/etc/apt/sources.list`)。 - ```shell + ```console $ echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null @@ -271,13 +271,13 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 首先需要从第三方源更新软件列表。 - ```shell + ```console $ sudo apt update ``` 之后便可以直接安装 `docker-ce` 以及相关的软件包。 - ```shell + ```console $ sudo apt install docker-ce docker-ce-cli containerd.io ``` @@ -285,7 +285,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 Docker 是作为一个服务运行在系统的后台的,要查看 Docker 是否安装完成并确定 Docker 已经启动,可以通过如下方式: - ```shell + ```console $ sudo systemctl status docker ``` @@ -315,7 +315,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 这时候,我们可以通过 `systemctl` 命令启动 Docker 服务: - ```shell + ```console $ sudo systemctl start docker ``` @@ -397,7 +397,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 如果不小心执行了 `dpkg -i` 导致系统出现依赖问题,可以尝试通过如下的方式调用 `apt` 帮助修复依赖管理: - ```shell + ```console $ sudo apt -f install ``` @@ -421,7 +421,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 在 LLVM 的 [Prebuilt 下载页面](https://releases.llvm.org/download.html) 中下载需要的版本以及自己的发行版所对应的二进制文件(Pre-Built Binaries)。在 “LLVM 10.0.0” 栏目下找到 “Pre-Built Binaries:”,对于 Ubuntu 和 Xubuntu 只有 Ubuntu 18.04 的预编译二进制文件。 - ```shell + ```console $ # 下载二进制的压缩文件存档 $ wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz @@ -436,14 +436,14 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 在进入解压得到的目录后,可以查看当前的目录下有什么内容: - ```shell + ```console $ ls bin include lib libexec share ``` 一般而言,软件的可执行文件都位于 `bin` 目录下: - ```shell + ```console $ cd bin $ ls (Output omitted) @@ -456,7 +456,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 这个目录下的 `clang` 和 `clang++` 就类似于我们比较熟悉的 `gcc` 和 `g++`。这两个是可以直接运行进行编译源代码的可执行文件。当然,我们不能每次在需要编译程序的时候输入如此长的路径找到 `clang` 和 `clang++`,而更希望的是能够像 `apt` 那样在任何地方都可以直接运行。我们可以这样做: - ```shell + ```console $ # 将 clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04 目录下的所有内容复制到 /usr/local/ 下。 $ sudo cp -R * /usr/local/ ``` @@ -465,7 +465,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 通过这个命令可以看到当前的 PATH 环境变量有哪些目录。 - ```shell + ```console $ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ``` @@ -501,13 +501,13 @@ $ cat [OPTION] FILE * 输出 file.txt 的全部内容 - ```shell + ```console $ cat file.txt ``` * 查看 file1.txt 与 file2.txt 连接后的内容 - ```shell + ```console $ cat file1.txt file2.txt ``` @@ -578,17 +578,17 @@ $ cp [OPTION] SOURCE... DIRECTORY !!! example "复制示例" * 将 `file1.txt` 复制一份到同目录,命名为 `file2.txt` - ```shell + ```console $ cp file1.txt file2.txt ``` * 将 `file1.txt`、`file2.txt` 文件复制到同目录下的 `file` 目录中 - ```shell + ```console $ cp file1.txt file2.txt ./file/ ``` * 将 `dir1` 文件夹及其所有子文件复制到同目录下的 `test` 文件夹中 - ```shell + ```console $ cp -r dir1 ./test/ ``` @@ -615,7 +615,7 @@ $ cp [OPTION] SOURCE... DIRECTORY `ln` 命令也可以用来创建硬链接和软链接。 - ```shell + ```console $ ln -s file symlink # 创建指向文件 file 的软链接 symlink $ ln file hardlink # 创建指向文件 file 的硬链接 hardlink ``` @@ -663,19 +663,19 @@ $ rm [OPTION] FILE... * 删除 `file1.txt` 文件: - ```shell + ```console $ rm file1.txt ``` * 删除 `test` 目录及其下的所有文件: - ```shell + ```console $ rm -r test/ ``` * 删除 `test1/`、`test2/`、`file1.txt` 这些文件、目录。其中,这些文件或者目录可能不存在、写保护或者没有权限读写: - ```shell + ```console $ rm -rf test1/ test2/ file1.txt ``` @@ -683,7 +683,7 @@ $ rm [OPTION] FILE... 使用 `rm` 删除时,请务必注意目录拼写。例如: - ```shell + ```console $ rm -rf /home/ustc/folder # 删除 folder $ rm -rf / home/ustc/folder # 删除根目录下的所有文件和 home/ustc/folder 及其中的文件:这很危险! ``` @@ -705,13 +705,13 @@ $ mkdir [OPTION] DIR_NAME... * 创建两个目录,名字分别为 `test1`、`test2`: - ```shell + ```console $ mkdir test1 test2 ``` * 创建路径 `test1/test2/test3/`: - ```shell + ```console $ mkdir -p test1/test2/test3/ ``` @@ -736,7 +736,7 @@ $ touch FILE_NAME... `stat` 命令可以显示文件的属性信息,可以来看看 touch 对已有文件的操作: - ```shell + ```console $ touch test # 创建文件 test $ stat test # 查看信息 File: test @@ -781,19 +781,19 @@ $ find [OPTION] PATH [EXPRESSION] * 在当前目录搜索名为 report.pdf 的文件: - ```shell + ```console $ find . -name 'report.pdf' ``` * 全盘搜索大于 1G 的文件: - ```shell + ```console $ find / -size +1G ``` * 在用户目录搜索所有名为 node_modules 的文件夹: - ```shell + ```console $ find ~/ -name 'node_modules' -type d ``` @@ -862,37 +862,37 @@ $ tar [OPTIONS] FILE... * 将 `file1`、`file2`、`file3` 打包为 `target.tar`: - ```shell + ```console $ tar -c -f target.tar file1 file2 file3 ``` * 将 `target.tar` 中的文件提取到 `test` 目录中: - ```shell + ```console $ tar -x -f target.tar -C test/ ``` * 将 `file1`、`file2`、`file3` 打包,并使用 gzip 算法压缩,得到压缩文件 `target.tar.gz` : - ```shell + ```console $ tar -cz -f target.tar.gz file1 file2 file3 ``` * 将压缩文件 `target.tar.gz` 解压到 `test` 目录中: - ```shell + ```console $ tar -xz -f target.tar.gz -C test/ ``` * 将 `archive1.tar`、`archive2.tar`、`archive3.tar` 三个存档文件中的文件追加到 `archive.tar` 中 - ```shell + ```console $ tar -Af archive.tar archive1.tar archive2.tar archive3.tar ``` * 列出 `target.tar` 存档文件中的内容 - ```shell + ```console $ tar -t -f target.tar $ # 打印出文件的详细信息 @@ -903,7 +903,7 @@ $ tar [OPTIONS] FILE... 与大部分 Linux 命令相同,tar 命令允许将多个单字母(使用单个 `-` 符号的)选项组合为一个参数,便于用户输入。例如,以下命令是等价的: - ```shell + ```console $ tar -c -z -v -f target.tar test/ $ tar -czvf target.tar test/ $ tar -f target.tar -czv test/ @@ -1080,7 +1080,7 @@ https://www.gnu.org/software/tar 在 2020 年初撰写本章时,“第三方软件源”中安装 Docker 的示例中使用了 `apt-key` 添加信任的 GPG Key,如下所示: - ```shell + ```console $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - ``` diff --git a/docs/Ch04/index.md b/docs/Ch04/index.md index 98412fad..25e13327 100644 --- a/docs/Ch04/index.md +++ b/docs/Ch04/index.md @@ -449,7 +449,7 @@ Control the systemd system and service manager. 可以通过 `service --status-all` 查看目录 `/etc/init.d` 下的服务。 - ```shell + ```console $ service --status-all [ - ] atftpd [ - ] avahi-daemon @@ -516,7 +516,7 @@ Control the systemd system and service manager. 将写好的配置文件保存为 `/etc/systemd/system/jupyter.service`,然后运行 `systemctl daemon-reload`,就可以使用 `systemctl` 命令来管理这个服务了,例如: - ```shell + ```console $ systemctl start jupyter $ systemctl stop jupyter $ systemctl enable jupyter # enable 表示标记服务的开机自动启动 diff --git a/docs/Ch04/solution.md b/docs/Ch04/solution.md index b8da47b7..1c53e85e 100644 --- a/docs/Ch04/solution.md +++ b/docs/Ch04/solution.md @@ -68,13 +68,13 @@ icon: material/tooltip-question 在启动 tmux 时,可以为启动的会话命名: - ```shell + ```console $ tmux new -s session-a # 启动名为 session-a 的 tmux 会话 ``` 脱离 tmux 之后如果还需要再进入这个会话,使用以下命令即可: - ```shell + ```console $ tmux a -t session-a ``` @@ -92,7 +92,7 @@ icon: material/tooltip-question `journalctl` 的 `-u` 参数可以指定 unit,例子如下: - ```shell + ```console $ sudo journalctl -u ssh # 查看 ssh 服务的日志 ``` @@ -100,7 +100,7 @@ icon: material/tooltip-question 在第一条的基础上,可以指定 `-f` 参数,以获取正在输出的日志: - ```shell + ```console $ sudo journalctl -u ssh -f ``` @@ -108,7 +108,7 @@ icon: material/tooltip-question 3. 系统**正在**输出的日志 - ```shell + ```console $ sudo journalctl -f ``` @@ -116,7 +116,7 @@ icon: material/tooltip-question 4. 上一次启动到关机的所有日志 - ```shell + ```console $ sudo journalctl -b -1 ``` diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index 3491a68f..6e862e16 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -228,7 +228,7 @@ $ sudo adduser 用户名 组名 除了可以通过 `visudo` 命令编辑 `sudoers` 文件外,还可以直接通过将新的用户加入到 `sudo` 用户组,以能够使用 `sudo` 命令。 - ```shell + ```console $ sudo adduser ustc sudo ``` diff --git a/docs/Ch05/solution.md b/docs/Ch05/solution.md index fa2f6fa0..c30b0979 100644 --- a/docs/Ch05/solution.md +++ b/docs/Ch05/solution.md @@ -22,7 +22,7 @@ icon: material/tooltip-question ??? info "解答" - ```shell + ```console $ /usr/sbin/nologin This account is currently not available. $ /bin/false @@ -62,7 +62,7 @@ icon: material/tooltip-question 如果你真的去执行 `sudo cd`,那么会看到: - ```shell + ```console $ sudo cd a sudo: cd: command not found ``` @@ -77,20 +77,20 @@ icon: material/tooltip-question 这里可能不止权限不足的问题。事实上,在 Debian 系统上,用普通用户执行 `reboot`,你会看到: - ```shell + ```console $ reboot -bash: reboot: command not found ``` 这是为什么呢?这是因为,`reboot` 存在于 `/sbin` 下,而这个目录并不在普通用户登录后默认的 `PATH` 环境变量中(但 Ubuntu 下则不一样:`/sbin` 也在普通用户的 `PATH` 环境变量中)。也就是说,Shell 并不会去 `/sbin` 中查找 `reboot`,自然就会提示 `command not found`。如果执行 - ```shell + ```console $ /sbin/reboot ``` 或者 - ```shell + ```console $ systemctl reboot -i # 另一种重启的方法 ``` diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md index 997f7e7a..0cbae86f 100644 --- a/docs/Ch06/index.md +++ b/docs/Ch06/index.md @@ -108,13 +108,13 @@ sbin 批量下载 filelist.txt 中给出的链接: - ```shell + ```console $ wget -i filelist.txt ``` 安装 oh-my-zsh: - ```shell + ```console $ sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)" ``` @@ -138,31 +138,31 @@ cURL (`curl`) 是一个利用 URL 语法在命令行下工作的文件传输工 输出必应主页的代码: - ```shell + ```console $ curl "http://cn.bing.com" ``` 使用重定向把必应页面保存至 `bing.html` 本地: - ```shell + ```console $ curl "http://cn.bing.com" > bing.html ``` 也可以使用 `-o` 选项指定输出文件: - ```shell + ```console $ curl -o bing.html "http://cn.bing.com" ``` 下载 USTCLUG 的 logo: - ```shell + ```console $ curl -O "https://ftp.lug.ustc.edu.cn/misc/logo-whiteback-circle.png" ``` 只展示 HTTP 响应头内容: - ```shell + ```console $ curl -I "http://cn.bing.com" ``` @@ -199,7 +199,7 @@ $ wc file `wc` 在统计中文文本时,会出现一些问题,比如: - ```shell + ```console $ echo '中文测试' | wc 1 1 13 ``` @@ -208,7 +208,7 @@ $ wc file 对于字符数统计结果,可以使用 `wc -m` 命令要求 `wc` 考虑宽字符: - ```shell + ```console $ echo '中文测试' | wc -m 5 ``` @@ -348,13 +348,13 @@ drwxr-xr-x 2 ustc ustc 4096 11月 17 20:45 模板/ - 在指定的 Shell 下执行,将脚本程序名作为 Shell 的第一个参数: - ```shell + ```console $ bash show.sh [option] ``` - 将脚本设置为可执行,然后像外部命令一样执行: - ```shell + ```console $ chmod a+x show.sh $ ./show.sh [option] ``` @@ -392,7 +392,7 @@ Bash 也支持在同一个行中安排多个命令: ??? example "组命令示例" - ```shell + ```console $ pwd # 当前在家目录 /home/ustc $ (cd /tmp; pwd;) @@ -551,7 +551,7 @@ Shell 中还有一组有 shell 定义和设置的特殊变量,用户只能引 !!! example "特殊字符示例" - ```shell + ```console $ ls /mnt/c/Program Files/ ls: cannot access /mnt/c/Program: No such file or directory ls: cannot access Files/: No such file or directory @@ -634,7 +634,7 @@ $ # 所以为了正常显示,需要在结尾补上 \n ??? example "`(( 表达式 ))` 的返回值" - ```shell + ```console $ (( 1 + 1 )) $ echo $? # 结果为 2,所以返回值为 0 0 @@ -647,7 +647,7 @@ $ # 所以为了正常显示,需要在结尾补上 \n ??? example "`expr` 和 `let` 使用示例" - ```shell + ```console $ expr length "ustclug" 7 $ let a=0 diff --git a/docs/Ch06/solution.md b/docs/Ch06/solution.md index 3bb4ce3b..7a7ad050 100644 --- a/docs/Ch06/solution.md +++ b/docs/Ch06/solution.md @@ -8,7 +8,7 @@ icon: material/tooltip-question ??? info "解答" - ```shell + ```console $ wc -l file 427 file $ wc -l < file diff --git a/docs/Ch07/supplement.md b/docs/Ch07/supplement.md index d8a9f6ea..c54dbca2 100644 --- a/docs/Ch07/supplement.md +++ b/docs/Ch07/supplement.md @@ -173,7 +173,7 @@ getaddrinfo.c:(.text+0xd2): warning: Using 'getaddrinfo' in statically linked ap 近年来,musl libc 开始流行,并且它也是 Alpine Linux 的 C 运行时库。它的特点是轻量、快速、对静态链接友好。我们也可以来试一下: - ```shell + ```console $ sudo apt install musl-tools # musl-tools 提供了 musl-gcc 等方便的编译工具 $ musl-gcc -o hello-static-musl hello.c -static # 静态链接 musl libc $ ls -lha hello hello-static hello-static-musl diff --git a/docs/Ch09/index.md b/docs/Ch09/index.md index 88a85b85..3a759af8 100644 --- a/docs/Ch09/index.md +++ b/docs/Ch09/index.md @@ -73,7 +73,7 @@ $ sort -n numbers 在使用 sort 时,一个比如容易忽视的问题是当前的本地化配置对结果的影响。 - ```shell + ```console $ echo -e 'a b\naa' | LC_ALL=C sort a b aa From 882552b30045243f1d2d5259d10d88d80b47042d Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:05:48 +0800 Subject: [PATCH 09/14] Ch05: Fix new quiz Linux 101 is not Debian-based, so this must be modified. --- docs/Ch05/index.md | 32 +++++++++++++++++++++++++++----- docs/Ch05/solution.md | 23 ++--------------------- 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index 6e862e16..6e2c5a53 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -311,8 +311,6 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder (可以执行了) ``` - - ## 文件系统层次结构 {#fhs} 相信到现在你应该已经发现了:Linux 下文件系统的结构和 Windows 的很不一样。在 Windows 中,分区以盘符的形式来标识(如「C 盘」、「D 盘」),各个分区的分界线是很明确的。在系统所在的分区(一般为 C 盘)中,存储着程序文件 (`Program Files`),系统运行需要的文件 (`Windows`),用户文件 (`Users`) 等。这种组织形式源于 DOS 和早期的 Windows,并一直传承下来。 @@ -384,7 +382,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder `/sbin` -: 存储用于系统管理,以及仅允许 `root` 用户使用的程序。如 `fsck`(文件系统修复程序)、`reboot`(重启系统)等。 +: 存储用于系统管理,以及仅允许 `root` 用户使用的程序。如 `fsck`(文件系统修复程序)、`reboot`(重启系统)、`useradd`(添加用户)等。 `/srv` @@ -442,9 +440,33 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder 当需要浏览仅 `root` 用户可查看的目录时,很多人的第一反应是 `sudo cd xxx`,但最终失败了。尝试解释这样做不可行的原因。 -!!! question "普通用户运行 `reboot`" +!!! question "Debian 与 Ubuntu 的区别之一:普通用户运行 `useradd` 等命令" + + 提示:可以在按照[第八章](../Ch08/index.md)配置 Docker 后使用如下命令体验 Debian: + + ```console + $ sudo docker run -it --rm debian:bookworm + ``` + + 在进入容器后,使用 `useradd`(`adduser` 也可以)创建一个新用户并进入: + + ```console + # useradd -m test + # su - test + $ useradd + -sh: 1: useradd: not found + ``` + + 而相同的操作在 Ubuntu 容器(`ubuntu:noble`)中可以找到 `useradd` 这个命令: + + ```console + $ useradd + Usage: useradd [options] LOGIN + useradd -D + useradd -D [options] + ``` - 前面说过,`reboot` 这类程序只能由 `root` 用户运行。为何普通用户在 Shell 中直接输入 `reboot` 不能重启系统? + 虽然说 `useradd` 这种程序只能 root 运行,但是以上差异是为什么呢? ## 引用来源 {#references .no-underline} diff --git a/docs/Ch05/solution.md b/docs/Ch05/solution.md index c30b0979..a855cb1f 100644 --- a/docs/Ch05/solution.md +++ b/docs/Ch05/solution.md @@ -71,27 +71,8 @@ icon: material/tooltip-question 那么 `cd` 可以实现成(外置的)程序吗?答案是不能:因为切换工作目录的系统调用 (`chdir()`) 只能切换当前的程序的工作目录。如果实现成了外置的程序,那么切换完退出之后,shell 的工作目录仍然不会变化。 -## 普通用户运行 `reboot` +## Debian 与 Ubuntu 的区别之一:普通用户运行 `useradd` 等命令 ??? info "解答" - 这里可能不止权限不足的问题。事实上,在 Debian 系统上,用普通用户执行 `reboot`,你会看到: - - ```console - $ reboot - -bash: reboot: command not found - ``` - - 这是为什么呢?这是因为,`reboot` 存在于 `/sbin` 下,而这个目录并不在普通用户登录后默认的 `PATH` 环境变量中(但 Ubuntu 下则不一样:`/sbin` 也在普通用户的 `PATH` 环境变量中)。也就是说,Shell 并不会去 `/sbin` 中查找 `reboot`,自然就会提示 `command not found`。如果执行 - - ```console - $ /sbin/reboot - ``` - - 或者 - - ```console - $ systemctl reboot -i # 另一种重启的方法 - ``` - - 就会因为有其他用户已登录,或者权限不足而失败。其他的命令也是类似的原因,只能由 `root` 执行。 + 这里可能不止权限不足的问题。这是因为,`useradd` 存在于 `/sbin` 下,而在 Debian 中,这个目录并不在普通用户登录后默认的 `PATH` 环境变量中(但 Ubuntu 下则不一样:`/sbin` 也在普通用户的 `PATH` 环境变量中)。也就是说,Shell 并不会去 `/sbin` 中查找 `useradd`,自然就会提示 `command not found`。如果改成完整路径(`/sbin/useradd`)就可以了。 From 1dfd7c8acb61056370f4da24e84b9ac43856b0df Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:06:04 +0800 Subject: [PATCH 10/14] Ch06: Change warning to tip about checking alias --- docs/Ch06/index.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md index 0cbae86f..e1633dd0 100644 --- a/docs/Ch06/index.md +++ b/docs/Ch06/index.md @@ -338,9 +338,14 @@ drwxr-xr-x 2 ustc ustc 4096 11月 17 20:45 模板/ 部分 shell 会自带一些 alias,例如 [fish 中的 `ll` 就是 `ls -lh` 的别名](https://github.com/fish-shell/fish-shell/blob/daf96a35b57f52eea19302f615283e7c1486ab8c/share/functions/ll.fish#L5)。特别地,Windows 自带的 PowerShell 中的 alias 存在一些争议,例如其对 `curl` 的 alias 实际上是 `Invoke-WebRequest`,而这个命令和上文介绍的 curl 的行为完全不同,给用户带来了困惑。 -!!! warning "alias 可能带来的问题" +!!! tip "检查命令是否被 alias" - 如果将常见命令(例如 `cat`)通过 alias 映射到包含恶意代码的可执行文件上,则可能导致这些恶意代码被意外地执行。 + 如果发现某些命令的行为不符合预期,可以使用 `type` 命令检查该命令是否被 alias 了: + + ```console + $ type ls + ls is aliased to `ls --color=auto' + ``` ### Bash 脚本的运行 {#run-bash-script} From 2155301e423bec7983fc4f650153693fa86b9f8f Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:07:16 +0800 Subject: [PATCH 11/14] Ch05: Fix prettier --- docs/Ch05/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index 6e2c5a53..24b69905 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -463,7 +463,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder $ useradd Usage: useradd [options] LOGIN useradd -D - useradd -D [options] + useradd -D [options] ``` 虽然说 `useradd` 这种程序只能 root 运行,但是以上差异是为什么呢? From d239aad483dc2c5d06124d9da23c3473d1c1a31a Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:12:13 +0800 Subject: [PATCH 12/14] More code block language (console) update --- docs/Appendix/distribution.md | 8 ++++---- docs/Ch01/supplement.md | 16 ++++++++-------- docs/Ch02/index.md | 18 +++++++++--------- docs/Ch02/supplement.md | 32 ++++++++++++++++---------------- docs/Ch03/index.md | 26 +++++++++++++------------- docs/Ch03/solution.md | 8 ++++---- docs/Ch03/supplement.md | 32 ++++++++++++++++---------------- docs/Ch04/index.md | 18 +++++++++--------- docs/Ch04/supplement.md | 4 ++-- docs/Ch05/index.md | 24 ++++++++++++------------ docs/Ch05/supplement.md | 6 +++--- docs/Ch06/index.md | 14 +++++++------- docs/Ch07/supplement.md | 8 ++++---- docs/Ch08/index.md | 4 ++-- docs/Ch08/supplement.md | 4 ++-- docs/Ch09/index.md | 18 +++++++++--------- 16 files changed, 120 insertions(+), 120 deletions(-) diff --git a/docs/Appendix/distribution.md b/docs/Appendix/distribution.md index 983c3bf4..25dab9cb 100644 --- a/docs/Appendix/distribution.md +++ b/docs/Appendix/distribution.md @@ -18,7 +18,7 @@ Ubuntu 基于 Debian,并且相比 Debian 而言更加新手友好。而 Debian 简单使用: -```shell +```console $ sudo dnf install audacity # 安装 audacity $ sudo dnf remove firefox # 卸载 firefox $ dnf search thunderbird # 搜索 thunderbird @@ -51,7 +51,7 @@ SELinux 添加了额外的「强制访问控制」安全措施:系统中所有 Arch 使用的默认软件包管理器是 `pacman`。以下是一些常用的命令。 -```shell +```console $ sudo pacman -Syu # 更新系统所有软件包 $ sudo pacman -S firefox # 安装 Firefox $ sudo pacman -Rs chromium # 卸载 Chromium 和它的所有依赖 @@ -86,7 +86,7 @@ openSUSE 使用 RPM 作为其软件包格式,但是与 Fedora、CentOS 等不 以下是一些常用的命令: -```shell +```console $ sudo zypper update # 更新系统所有软件包 $ sudo zypper install firefox # 安装 Firefox $ sudo zypper remove chromium # 卸载 Chromium 和它的所有依赖 @@ -118,7 +118,7 @@ Gentoo 的软件包管理器是 Portage。其对应最常用的 CLI 工具是 `e 以下是一些常用的命令: -```shell +```console $ sudo emerge --sync # 更新软件包索引 $ sudo emerge --update --ask @world # 更新已安装的程序(不包含依赖) $ sudo emerge -a firefox # 安装 Firefox diff --git a/docs/Ch01/supplement.md b/docs/Ch01/supplement.md index 3ec966ad..b5958682 100644 --- a/docs/Ch01/supplement.md +++ b/docs/Ch01/supplement.md @@ -53,7 +53,7 @@ SELinux 有 3 种工作模式: 使用 `sestatus` 命令查看 SELinux 状态: -``` +```console $ sestatus SELinux status: enabled SELinuxfs mount: /sys/fs/selinux @@ -220,13 +220,13 @@ $ sudo resize2fs /dev/sda2 在服务器上首先安装 `openssh-server` 软件包,它提供了 SSH 服务器的功能。 -``` +```console $ sudo apt install openssh-server ``` 启动并检查 SSH 服务状态: -``` +```console $ sudo systemctl start ssh $ sudo systemctl status ssh ● ssh.service - OpenBSD Secure Shell server @@ -248,7 +248,7 @@ $ sudo systemctl status ssh 我们可以使用 `ssh` 命令直接连接到本地(localhost)的 SSH 服务器。其中 `@` 符号前的是登录的用户名,后面的是服务器的域名或 IP 地址。 -``` +```console $ ssh ustc@localhost The authenticity of host 'localhost (127.0.0.1)' can't be established. ECDSA key fingerprint is SHA256:czt1KYx+RIkFTpSPQOLq+GqLbLRLZcD1Ffkq4Z3ZR2U. @@ -321,7 +321,7 @@ ustc@ustclug-linux101:~$ 首先在自己的机器上使用 `ssh-keygen` 生成密钥: - ``` + ```console $ ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/home/ustc/.ssh/id_rsa): @@ -349,7 +349,7 @@ ustc@ustclug-linux101:~$ 在本地使用 `ssh-copy-id` 命令将公钥拷贝到服务器上: - ``` + ```console $ ssh-copy-id ustc@localhost /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys @@ -377,7 +377,7 @@ ustc@ustclug-linux101:~$ 然后让 SSH 服务器重新加载配置: - ``` + ```console $ sudo systemctl reload ssh ``` @@ -500,7 +500,7 @@ Featured Server Snaps 一样可以选择不安装,可以之后自行配置。 如果你需要带图形界面的虚拟机,只需要安装 `ubuntu-desktop` 即可。 -```bash +```console $ sudo apt-get install ubuntu-desktop ``` diff --git a/docs/Ch02/index.md b/docs/Ch02/index.md index 9fcd7f25..934d1e5c 100644 --- a/docs/Ch02/index.md +++ b/docs/Ch02/index.md @@ -295,7 +295,7 @@ Xfce4-session 是 Xfce 的会话管理器。它的任务是保存桌面的状态 然而使用命令行,我们只需要执行一条指令。 -```shell +```console $ mv /path/to/source/file.txt /path/to/dest/ ``` @@ -384,7 +384,7 @@ rm main.out 之后我们直接输入 -```shell +```console $ sh run.sh ``` @@ -454,7 +454,7 @@ $ sh run.sh #### 示例 1 {#shell-commands-example-1} -```shell +```console $ pwd ``` @@ -466,7 +466,7 @@ $ pwd #### 示例 2 {#shell-commands-example-2} -```shell +```console $ ls ``` @@ -478,7 +478,7 @@ Desktop Documents Music Pictures Public Templates Videos #### 示例 3 {#shell-commands-example-3} -```shell +```console $ cd Desktop # 这里的 Desktop 是相对路径,指的就是当前目录下的 Desktop 文件夹 $ ls ``` @@ -517,7 +517,7 @@ WordPress 是一个以 PHP 和 MySQL 为平台的自由开源的博客软件和 下载脚本要使用 `curl` 命令,我们要先安装 curl。 -```shell +```console $ sudo apt install curl ``` @@ -536,7 +536,7 @@ $ sudo apt install curl 打开终端并运行: -```shell +```console $ curl -fsSL https://101.lug.ustc.edu.cn/Ch02/wordpress.sh > wordpress.sh $ # 可以阅读 wordpress.sh 了解其运行的命令,检查代码无误后执行: $ sudo bash wordpress.sh @@ -571,13 +571,13 @@ Jekyll 是一个将纯文本转化为静态博客和网站的工具。 我们只需要通过命令行安装它。 -```shell +```console $ sudo apt install jekyll ``` 再输入几行命令用于创建网站: -```shell +```console $ jekyll new my-awesome-site $ cd my-awesome-site $ jekyll serve diff --git a/docs/Ch02/supplement.md b/docs/Ch02/supplement.md index d8e57e5b..8fe6a107 100644 --- a/docs/Ch02/supplement.md +++ b/docs/Ch02/supplement.md @@ -16,7 +16,7 @@ icon: material/puzzle 安装 `ubuntu-gnome-desktop` 软件: -```shell +```console $ sudo apt install ubuntu-gnome-desktop ``` @@ -28,7 +28,7 @@ $ sudo apt install ubuntu-gnome-desktop 安装完成后输入: -```shell +```console $ sudo reboot ``` @@ -56,7 +56,7 @@ $ sudo reboot 在 GNOME 桌面下用户可以轻松更换主题。 首先安装 `gnome-tweaks` 软件: -```shell +```console $ sudo apt install gnome-tweaks ``` @@ -72,7 +72,7 @@ $ sudo apt install gnome-tweaks 解压后放到 `~/.themes` 文件夹,若不存在该文件夹则创建一个。 -```shell +```console $ mkdir ~/.themes ``` @@ -84,7 +84,7 @@ $ mkdir ~/.themes 输入: -```shell +```console $ gnome-tweaks ``` @@ -104,7 +104,7 @@ GNOME 支持很多扩展,并且有一个专门用于扩展的网站。https:// 要使用 GNOME 扩展,我们要先安装 `gnome-shell-extensions`。 -```shell +```console $ sudo apt install gnome-shell-extensions ``` @@ -116,7 +116,7 @@ Caffeine: 允许用户停用系统屏幕保护和自动休眠。 先来查看我们正在使用的 GNOME 版本: -```shell +```console $ gnome-shell --version ``` @@ -136,7 +136,7 @@ $ gnome-shell --version 打开 `gnome-tweaks`。 -```shell +```console $ gnome-tweaks ``` @@ -218,7 +218,7 @@ $ gnome-tweaks 在此之前我们可以通过: -```shell +```console $ echo $SHELL ``` @@ -228,13 +228,13 @@ $ echo $SHELL 首先通过 apt 安装 `zsh`: -```shell +```console $ sudo apt install zsh ``` 将 zsh 设定为默认 shell: -```shell +```console $ chsh -s /bin/zsh ``` @@ -250,7 +250,7 @@ $ chsh -s /bin/zsh oh-my-zsh 是一个管理 zsh 配置的框架,评价也非常好。 -```shell +```console $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" ``` @@ -352,7 +352,7 @@ $ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/t ### WordPress 的手动配置 -```shell +```console $ sudo apt install -y wordpress php libapache2-mod-php mysql-server php-mysql ``` @@ -378,7 +378,7 @@ Alias /blog /usr/share/wordpress 保存后输入命令来重启 `apache2`: -```shell +```console $ sudo a2ensite wordpress $ sudo a2enmod rewrite $ sudo service apache2 reload @@ -386,7 +386,7 @@ $ sudo service apache2 reload 再配置数据库相关内容: -```shell +```console $ sudo mysql -u root ``` @@ -452,7 +452,7 @@ define('WP_CONTENT_DIR', '/usr/share/wordpress/wp-content'); 然后输入: -```shell +```console $ sudo service mysql start ``` diff --git a/docs/Ch03/index.md b/docs/Ch03/index.md index a96b958b..09af7936 100644 --- a/docs/Ch03/index.md +++ b/docs/Ch03/index.md @@ -492,7 +492,7 @@ Ubuntu 官方源位于国外,往往会有速度与延迟上的限制,可以 #### cat {#cat} -```shell +```console $ # 输出 FILE 文件的全部内容 $ cat [OPTION] FILE ``` @@ -519,7 +519,7 @@ $ cat [OPTION] FILE less 和 cat 的区别在于,cat 会一次性打印全部内容到终端中并退出,而 less 一次只显示一页,且支持向前/后滚动、搜索等功能。如果要在一个大文件中(例如 man page)查找一部分内容,less 通常要比 cat 方便得多。 -```shell +```console $ # 在可交互的窗口内输出 FILE 文件的内容 $ less FILE ``` @@ -547,7 +547,7 @@ $ less FILE Nano 是在很多机器上自带的命令行文本编辑器,相比于 vim 和 emacs 来说,对新手更加友好,不需要提前记忆复杂的键位。如果 Nano 没有被默认安装,则可以通过 `apt` 来安装。 -```shell +```console $ nano file.txt # 使用 nano 编辑 file.txt 文件(如果没有则创建) ``` @@ -557,7 +557,7 @@ Nano 启动后,用户可以直接开始输入需要的内容,使用方向键 ### 复制文件和目录 {#cp} -```shell +```console $ # 将 SOURCE 文件拷贝到 DEST 文件,拷贝得到的文件即为 DEST $ cp [OPTION] SOURCE DEST @@ -624,7 +624,7 @@ $ cp [OPTION] SOURCE... DIRECTORY `mv` 与 `cp` 的使用方式相似,效果类似于 Windows 下的剪切。 -```shell +```console $ # 将 SOURCE 文件移动到 DEST 文件 $ mv [OPTION] SOURCE DEST @@ -645,7 +645,7 @@ $ mv [OPTION] SOURCE... DIRECTORY ### 删除文件和目录 {#rm} -```shell +```console $ # 删除 FILE 文件,FILE 可以为多个文件。 $ # 如果需要删除目录,需要通过 -r 选项递归删除目录 $ rm [OPTION] FILE... @@ -690,7 +690,7 @@ $ rm [OPTION] FILE... ### 创建目录 {#mkdir} -```shell +```console $ # 创建一个目录,名为 DIR_NAME $ mkdir [OPTION] DIR_NAME... ``` @@ -717,7 +717,7 @@ $ mkdir [OPTION] DIR_NAME... ### 创建文件 {#touch} -```shell +```console $ # 创建一个文件,名为 FILE_NAME $ touch FILE_NAME... ``` @@ -726,7 +726,7 @@ $ touch FILE_NAME... 创建两个文件,名字分别为 `file1`、`file2`: - ``` + ```console $ touch file1 file2 ``` @@ -763,7 +763,7 @@ $ touch FILE_NAME... ### 搜索文件和目录 {#find} -```shell +```console $ # 在 PATH(路径)中根据 EXPRESSION(表达式)搜索文件 $ find [OPTION] PATH [EXPRESSION] ``` @@ -833,7 +833,7 @@ $ find [OPTION] PATH [EXPRESSION] 通常,可以使用其自带的 gzip 或 bzip2 算法进行压缩,生成压缩文件: -```shell +```console $ # 命令格式如下,请参考下面的使用样例了解使用方法 $ tar [OPTIONS] FILE... ``` @@ -940,7 +940,7 @@ $ tar [OPTIONS] FILE... 大部分软件在安装时会将它的软件手册安装在系统的特定目录, `man` 命令就是读取并展示这些手册的命令。在软件手册中,会带有软件的每一个参数的含义、退出值含义、作者等内容,大而全。但一般较少带有使用样例,需要根据自身需要拼接软件参数。 -```shell +```console $ # 调出 tar 命令和 ls 命令的文档 $ man tar $ man ls @@ -991,7 +991,7 @@ DESCRIPTION 在 Debian 系下,可以直接通过 `apt` 进行安装: -```shell +```console $ sudo apt install tldr $ # 更新 tldr pages $ tldr --update diff --git a/docs/Ch03/solution.md b/docs/Ch03/solution.md index 57270fde..13637adc 100644 --- a/docs/Ch03/solution.md +++ b/docs/Ch03/solution.md @@ -26,7 +26,7 @@ icon: material/tooltip-question 一个例子: - ``` + ```console $ apt-file search libc++.so libc++-7-dev: /usr/lib/llvm-7/lib/libc++.so libc++-7-dev: /usr/lib/x86_64-linux-gnu/libc++.so @@ -52,14 +52,14 @@ icon: material/tooltip-question 软链接的判断非常简单。如果是软链接的话,`ls -l` 对应的文件会明确写出其指向的文件。 - ``` + ```console $ ls -l /usr/bin/vim lrwxrwxrwx 1 root root 21 Jul 21 2019 /usr/bin/vim -> /etc/alternatives/vim ``` 那么如何判断硬链接呢?我们可以试一下。 - ``` + ```console $ touch file $ ln file hardfile $ touch other # 无硬链接的文件 @@ -74,7 +74,7 @@ icon: material/tooltip-question 也可以使用 `stat` 来查看。 - ``` + ```console $ stat hardfile File: hardfile Size: 0 Blocks: 0 IO Block: 4096 regular empty file diff --git a/docs/Ch03/supplement.md b/docs/Ch03/supplement.md index a8908214..8a0b4ef0 100644 --- a/docs/Ch03/supplement.md +++ b/docs/Ch03/supplement.md @@ -26,7 +26,7 @@ icon: material/puzzle - PCRE2 - 用于支持正则表达式。 -```shell +```console $ wget https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.tar.gz $ tar -zxf pcre2-10.42.tar.gz $ cd pcre2-10.42 @@ -41,7 +41,7 @@ $ sudo make install - zlib - 用于支持 HTTP 头部压缩。 -```shell +```console $ wget https://zlib.net/zlib-1.2.13.tar.gz $ tar -zxf zlib-1.2.13.tar.gz $ cd zlib-1.2.13 @@ -52,7 +52,7 @@ $ sudo make install - OpenSSL - 用于支持 HTTPS 协议。 -```shell +```console $ wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz $ tar -zxf openssl-1.1.1c.tar.gz $ cd openssl-1.1.1c @@ -67,7 +67,7 @@ $ sudo make install ### 下载 Nginx 源代码 {#download-source} -```shell +```console $ wget https://nginx.org/download/nginx-1.23.3.tar.gz $ tar -zxf nginx-1.23.3.tar.gz $ cd nginx-1.23.3 @@ -77,7 +77,7 @@ $ cd nginx-1.23.3 #### 配置编译选项 {#configure} -```shell +```console $ ./configure \ --sbin-path=/usr/local/nginx/nginx \ --conf-path=/usr/local/nginx/nginx.conf \ @@ -95,7 +95,7 @@ $ ./configure \ #### 编译并安装 {#make-install} -```shell +```console $ make $ sudo make install ``` @@ -146,7 +146,7 @@ Vim 被誉为「编辑器之神」,但是其陡峭的学习曲线也让人望 使用 `stat` 工具可以看到一个文件有四个时间戳,分别为 Access,Modify,Change 和 Birth: -```shell +```console $ stat test File: test Size: 0 Blocks: 0 IO Block: 4096 regular empty file @@ -178,7 +178,7 @@ Birth: 2022-02-25 18:12:28.403981478 +0800 访问时间(atime)和创建(Birth, btime)时间很好理解,但是 Modify(mtime)和 Change(ctime)有什么区别呢?可以来试一下: -```shell +```console $ stat test File: test Size: 0 Blocks: 0 IO Block: 4096 regular empty file @@ -228,7 +228,7 @@ unar 是 macOS 上的软件 [The Unarchiver](https://theunarchiver.com/) 的命 Ubuntu 上直接使用 apt 安装即可: -```shell +```console $ sudo apt install unar ``` @@ -236,7 +236,7 @@ $ sudo apt install unar 安装之后会得到两个命令:`unar` 和 `lsar`,分别用来解压存档文件以及浏览存档文件内容: -```shell +```console $ unar archive.zip -o output # 将存档文件提取到 output 文件夹中 $ lsar archive.zip # 浏览存档文件内容 $ lsar -l archive.zip # 查看详细信息 @@ -247,13 +247,13 @@ $ lsar -L archive.zip # 查看特别详细的信息 `zip` 和 `unzip` 工具分别负责 ZIP 压缩包的压缩与解压缩,使用以下命令安装: -```shell +```console $ sudo apt install zip unzip ``` 以下提供一些命令例子,更多的功能需要查看对应的文档: -```shell +```console $ zip -r archive.zip path/file1 path/dir1 # (递归地)压缩文件和目录 $ zip archive.zip path/file2 # 添加文件到已有的压缩包 $ unzip archive.zip # 解压缩 @@ -265,7 +265,7 @@ $ unzip -l archive.zip # 浏览压缩包内容 `rar` 和 `unrar` 工具分别负责 RAR 压缩包的压缩与解压缩,使用以下命令安装: -```shell +```console $ sudo apt install rar unrar ``` @@ -275,7 +275,7 @@ $ sudo apt install rar unrar 例子如下: -```shell +```console $ rar a archive.rar path/file1 path/dir1 # 压缩文件和目录/添加文件和目录到压缩包 $ unrar x archive.rar # 解压缩 $ unrar x archive.rar path/ # 解压缩到指定目录 @@ -288,7 +288,7 @@ RARLAB 仅提供了 Linux 下命令行界面的 RAR 压缩包处理工具。但 Ubuntu 下 `p7zip-full` 包提供了 `7z` 等工具处理 7z 包(以及其他各种压缩格式): -``` +```console $ sudo apt install p7zip-full ``` @@ -304,7 +304,7 @@ $ sudo apt install p7zip-full 以下给出 `7z` 命令行工具的一些例子: -```shell +```console $ 7z a archive.7z path/file1 path/dir1 # 压缩文件和目录/添加文件和目录到压缩包 $ 7z x archive.7z # 解压缩 $ 7z x archive.7z -opath/ # 解压缩到 path/ 目录下 diff --git a/docs/Ch04/index.md b/docs/Ch04/index.md index 25e13327..607e4be6 100644 --- a/docs/Ch04/index.md +++ b/docs/Ch04/index.md @@ -46,7 +46,7 @@ htop 可以简单方便查看当前运行的所有进程,以及系统 CPU、 ps(**p**rocess **s**tatus)是常用的输出进程状态的工具。直接调用 `ps` 仅会显示本终端中运行的相关进程。如果需要显示所有进程,对应的命令为 `ps aux`。 -```shell +```console $ ps PID TTY TIME CMD 1720 pts/0 00:00:00 bash @@ -93,7 +93,7 @@ Nice 值越高代表一个进程对其它进程越 "nice"(友好),对应 用户可以使用 `nice` 命令在运行程序时指定优先级,而 `renice` 命令则可以重新指定优先级。当然,若想调低 nice 值,还需要 `sudo`(毕竟不能随便就把自己的优先级设置得更高,不然对其他的用户不公平)。 -```shell +```console $ nice -n 10 vim # 以 10 为 nice 值运行 vim $ renice -n 10 -p 12345 # 设置 PID 为 12345 的进程的 nice 值为 10 ``` @@ -156,7 +156,7 @@ Zombie 是僵尸进程,该状态下进程已经结束,只是仍然占用一 默认情况下,在 shell 中运行的命令都在前台运行,如果需要在后台运行程序,需要在最后加上 `&`: -```shell +```console $ ./matmul & # 例子:运行耗时的计算同时进行其他操作 $ ps PID TTY TIME CMD @@ -197,7 +197,7 @@ htop 中自带向进程发送信号的功能。按下 K 键,在左侧提示栏 如前所述,Linux 上最常用的发送信号的程序就是 kill。 -```shell +```console $ kill -l # 显示所有信号名称 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 @@ -258,7 +258,7 @@ $ kill -l # 显示所有信号名称 nohup,字面含义,就是「不要被 SIGHUP 影响」。 -```shell +```console $ nohup ping 101.lug.ustc.edu.cn & [1] 19258 nohup: ignoring input and appending output to '/home/ustc/nohup.out' @@ -282,7 +282,7 @@ tmux 由会话(session),窗口(window),面板(pane)组织起每 下面先行讲解这一工具的用法: -```shell +```console $ sudo apt install tmux $ tmux ``` @@ -363,7 +363,7 @@ $ tmux 要管理服务,首先我们要清楚系统内有哪些服务。可以通过 `systemctl status` 命令一览系统服务运行情况。 -```shell +```console $ systemctl status ● ustclug-linux101 State: running @@ -467,7 +467,7 @@ Control the systemd system and service manager. 以下是 tldr 给出的 `service` 常见命令的列表: - ``` + ```console $ tldr service service Manage services by running init scripts. @@ -560,7 +560,7 @@ at 命令负责单次计划任务,当前许多发行版中,并没有预装 所以该命令的基本用法示例如下: -```shell +```console $ at now + 1min > echo "hello" > (按下 Ctrl + D) diff --git a/docs/Ch04/supplement.md b/docs/Ch04/supplement.md index 93bf7924..8df900e9 100644 --- a/docs/Ch04/supplement.md +++ b/docs/Ch04/supplement.md @@ -89,7 +89,7 @@ DESCRIPTION 注意 strace 会输出到标准错误 (stderr),需要将输出重定向到标准输出之后通过管道后才能使用 grep 等工具。关于重定向、管道等内容,可以查看[第六章](../Ch06/index.md#redirection-and-pipe)。 -```shell +```console $ strace ps ... openat(AT_FDCWD, "/proc/1/stat", O_RDONLY) = 6 @@ -106,7 +106,7 @@ close(6) 可以大致猜测,ps 通过打开 `/proc/1` 文件夹下的 `stat` 和 `status` 文件,获得 1 号进程的信息。我们也可以试着打开它: -```shell +```console $ cat /proc/1/stat # 由于用户权限不同,是否添加 sudo 会导致读取出不同内容 1 (systemd) S 0 1 1 0 -1 4194560 113722 4652720 87 2258 79 670 19018 28647 \ 20 0 1 0 4 231030784 2252 18446744073709551615 1 1 0 0 0 0 671173123 4096 1260 \ diff --git a/docs/Ch05/index.md b/docs/Ch05/index.md index 24b69905..c493190c 100644 --- a/docs/Ch05/index.md +++ b/docs/Ch05/index.md @@ -99,7 +99,7 @@ icon: material/account-group 你是否常常忘记敲 `sudo`,结果还要把后面的整条命令重新敲一遍?在发现权限不足之后有一个方便的「补救方案」:`sudo !!`,效果如下: - ``` + ```console $ apt update Reading package lists... Done E: Could not open lock file /var/lib/apt/lists/lock - open (13: Permission denied) @@ -117,7 +117,7 @@ icon: material/account-group 那么,如何以 `root` 之外的用户的身份执行命令呢?加上 `-u 用户名` 的参数即可。 -``` +```console $ sudo -u nobody id uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) ``` @@ -149,7 +149,7 @@ uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) 在读完上面这句话之后,你可能会尝试切换到 `root`,但是却失败了: -``` +```console $ su Password: (密码?什么密码?输我自己的密码试试?) @@ -159,7 +159,7 @@ $ 这是因为,如 Ubuntu 等 Linux 发行版默认禁止了 `root` 用户的密码登录,只允许通过 `sudo` 提高权限。但是,我们可以用 `sudo` 运行 `su`,来得到一个为 `root` 用户权限的 shell。 -``` +```console $ sudo su Password: (没错,是我自己的密码) @@ -175,7 +175,7 @@ $ 用户组是用户的集合。通过用户组机制,可以为一批用户设置权限。可以使用 `groups` 命令,查看自己所属的用户组。 -``` +```console $ groups ustc adm cdrom sudo dip plugdev lxd ``` @@ -200,19 +200,19 @@ ustc adm cdrom sudo dip plugdev lxd `adduser` 是 Debian 及其衍生发行版中附带的一个方便的用户管理脚本。它可以用来向系统添加用户、添加组,以及将用户加入组。输入: -```shell +```console $ sudo adduser 用户名 ``` 即可添加此用户。而输入 -```shell +```console $ sudo adduser --group 组名 ``` 即可添加此用户组。将用户加入指定用户组也非常简单: -``` +```console $ sudo adduser 用户名 组名 ``` @@ -243,7 +243,7 @@ $ sudo adduser 用户名 组名 在 Linux 中,每个文件和目录都有自己的权限。可以使用 `ls -l` 查看当前目录中文件的详细信息。 -``` +```console $ ls -l total 8 -rwxrw-r-- 1 ustc ustc 40 Feb 3 22:37 a_file @@ -262,7 +262,7 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder 而对于目录来说,拥有执行权限,你就可以访问这个目录下的文件的内容。以下是一个例子: - ``` + ```console $ ls -l total 8 -rwxrw-r-- 1 ustc ustc 40 Feb 3 22:37 a_file @@ -298,14 +298,14 @@ drwxrwxr-x 2 ustc ustc 4096 Feb 3 22:38 a_folder 有时候,我们会从网上下载一些二进制的程序,或者根据网络的教程编写脚本程序,但当你想执行的时候却发现: - ``` + ```console $ ./program -bash: ./program: Permission denied ``` 大多数情况下,这说明这个文件缺少执行 (`x`) 权限。可以使用 `chmod +x` 命令添加执行权限。 - ``` + ```console $ chmod +x program $ ./program (可以执行了) diff --git a/docs/Ch05/supplement.md b/docs/Ch05/supplement.md index 11c104f7..01c26c98 100644 --- a/docs/Ch05/supplement.md +++ b/docs/Ch05/supplement.md @@ -22,7 +22,7 @@ icon: material/puzzle 我们可以看一下,`/usr/bin/passwd` 的文件权限设置: -```shell +```console $ ls -l /usr/bin/passwd -rwsr-xr-x 1 root root 67992 Aug 29 2019 /usr/bin/passwd ``` @@ -31,7 +31,7 @@ $ ls -l /usr/bin/passwd 同样,`su` 和 `sudo` 也有 `setuid` 权限位: -``` +```console $ ls -l /usr/bin/su -rwsr-xr-x 1 root root 67816 Jan 9 02:59 /usr/bin/su $ ls -l /usr/bin/sudo @@ -69,7 +69,7 @@ $ ls -l /usr/bin/sudo 一般地,「登录 Shell」会额外加载 `profile` 文件(文件名根据你使用的 Shell 的不同而有区别),且它的 `argv[0][0] == '-'`(相信你已经学过 C 语言了)。可以用以下方法验证: -```shell +```console $ echo $0 # 查看当前 Shell 的 argv[0] 的值 -bash $ # 是 Login shell diff --git a/docs/Ch06/index.md b/docs/Ch06/index.md index e1633dd0..caa21ea1 100644 --- a/docs/Ch06/index.md +++ b/docs/Ch06/index.md @@ -190,7 +190,7 @@ cURL (`curl`) 是一个利用 URL 语法在命令行下工作的文件传输工 `wc` 是文本统计的常用工具,它可以输出文本的行数、单词数与字符(字节)数。 -```shell +```console $ wc file 427 2768 20131 file ``` @@ -221,7 +221,7 @@ $ wc file diff 工具用于比较两个文件的不同,并列出差异。 -```shell +```console $ echo hello > file1 $ echo hallo > file2 $ diff file1 file1 @@ -277,7 +277,7 @@ $ grep -R 'hello' . # 递归查找当前目录下内容包含 hello 的文件 `sed` 命令可以替换文本中的字符串: -```shell +```console $ sed 's/hello/world/g' file # 将文件 file 中的 hello 全局(global)替换为 world 后输出 $ sed 's/hello/world/' file # 将文件 file 的每一行第一个出现的 hello 替换为 world 后输出 $ echo 'helloworld' | sed 's/hello/world/g' # 管道也是可以的 @@ -287,7 +287,7 @@ $ sed -i.bak 's/hello/world/g' file # 当然,也可以让 sed 帮你备份到 对于大多数用户来说,最常用 `sed` 的场合是替换软件源的时候。在阅读了上面的示例之后,以下例子就很简单了: -```shell +```console $ sudo sed -i 's/cn.archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list $ sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list $ sudo sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list @@ -313,7 +313,7 @@ Bash 允许用户定制环境以满足自己需要。通过修改环境文件 `. 此外,bash 也支持使用 `alias` 别名代替命令关键字(`alias name='命令'`)。输入 `alias`,可以查看目前存在的别名: -```shell +```console $ alias alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"' alias egrep='egrep --color=auto' @@ -491,7 +491,7 @@ Bash 也支持在同一个行中安排多个命令: 可以使用 `export` 命令来定义环境变量。在同一个 shell 中使用 `export` 定义之后,这个环境变量会一直保留,直到这个 shell 退出。 -```shell +```console $ export A=1 $ env | grep A= A=1 @@ -499,7 +499,7 @@ A=1 此外,也可以在命令前加上环境变量的定义。此时只有这一条命令的环境变量出现变化。 -```shell +```console $ B=1 env | grep B= B=1 $ env | grep B= diff --git a/docs/Ch07/supplement.md b/docs/Ch07/supplement.md index c54dbca2..e25a410a 100644 --- a/docs/Ch07/supplement.md +++ b/docs/Ch07/supplement.md @@ -86,7 +86,7 @@ $ conda env create -f environment.yml 在大部分情况下,我们编译的程序都是动态链接的。动态链接在这里指程序文件还依赖其他库文件,可以使用 `ldd` 命令确认: -```shell +```console $ cat hello.c #include @@ -113,7 +113,7 @@ $ ldd ./hello 我们在编写程序时,有时需要使用到第三方的库,此时需要加上 `-l` 参数指定在**链接**时链接到的库。 -```shell +```console $ gcc -o thread thread.c -lpthread # 编译一个依赖于 pthread 线程库的应用 $ ldd ./thread # 可以看到多出了 libpthread.so.0 的动态链接依赖 linux-vdso.so.1 (0x00007ffe6ad93000) @@ -141,7 +141,7 @@ $ ./MegaCli64 # 缺少 libncurses.so.5,从而无法执行 而静态链接则将依赖的库全部打包到程序文件中。 -```shell +```console $ gcc -o hello-static hello.c -static # 编译一个静态链接的应用 $ ldd ./hello-static # 没有动态链接库的依赖 not a dynamic executable @@ -151,7 +151,7 @@ $ ldd ./hello-static # 没有动态链接库的依赖 但是静态链接也存在一些问题。首先是程序大小,比较一下前面编译的 hello-static 和 hello 的大小吧: -```shell +```console $ ls -l hello hello-static -rwxrwxr-x 1 ustc ustc 17K Feb 28 14:43 hello -rwxrwxr-x 1 ustc ustc 852K Feb 28 14:39 hello-static diff --git a/docs/Ch08/index.md b/docs/Ch08/index.md index 8bae742e..8f45b937 100644 --- a/docs/Ch08/index.md +++ b/docs/Ch08/index.md @@ -66,7 +66,7 @@ Docker 可以在 Windows, Linux 和 macOS 上安装。下面我们讨论内容 在安装完成后,可以使用 -```shell +```console $ sudo adduser 用户名 docker ``` @@ -324,7 +324,7 @@ COPY ./app /app Docker Compose 是一个方便的小型容器编排工具。如果前面安装的是 `docker.io` 软件包,那么系统中可能未安装 `docker-compose`,使用以下命令安装: -```shell +```console $ sudo apt install docker-compose ``` diff --git a/docs/Ch08/supplement.md b/docs/Ch08/supplement.md index 55fac889..fd79e531 100644 --- a/docs/Ch08/supplement.md +++ b/docs/Ch08/supplement.md @@ -10,14 +10,14 @@ icon: material/puzzle 对于 Debian/Ubuntu 用户,由于其不在官方软件源中,需要手动下载 deb 包安装: -```shell +```console $ wget https://github.com/wagoodman/dive/releases/download/v0.9.2/dive_0.9.2_linux_amd64.deb $ sudo apt install ./dive_0.9.2_linux_amd64.deb ``` 之后直接使用即可: -```shell +```console $ dive ubuntu:20.04 # 查看 Ubuntu 20.04 镜像中的内容 ``` diff --git a/docs/Ch09/index.md b/docs/Ch09/index.md index 3a759af8..576a5166 100644 --- a/docs/Ch09/index.md +++ b/docs/Ch09/index.md @@ -25,7 +25,7 @@ sort 用于文本的行排序。默认排序方式是升序,按每行的字典 - `-o [file]` 指定输出文件 - `-n` 用于数值排序,否则“15”会排在“2”前 -```shell +```console $ echo -e "snake\nfox\nfish\ncat\nfish\ndog" > animals $ sort animals cat @@ -94,7 +94,7 @@ uniq 也可以用来排除重复的行,但是仅对连续的重复行生效。 通常会和 sort 一起使用: -```shell +```console $ sort animals | uniq ``` @@ -102,13 +102,13 @@ $ sort animals | uniq `uniq -d` 可以用于仅输出重复行: -```shell +```console $ sort animals | uniq -d ``` `uniq -c` 可以用于统计各行重复次数: -```shell +```console $ sort animals | uniq -c ``` @@ -192,7 +192,7 @@ grep 默认使用 BRE,要使用 ERE 可以使用 `grep -E` 或 egrep。 - `-v`:显示不被匹配到的行 - `-i`:忽略字符大小写 -```shell +```console $ ls /bin | grep -n "^man$" # 搜索内容仅含 man 的行,并且显示行号 $ ls /bin | grep -v "[a-z]\|[0-9]" # 搜索不含小写字母和数字的行 $ ls /bin | grep -iv "[A-Z]\|[0-9]" # 搜索不含字母和数字的行 @@ -206,7 +206,7 @@ sed 默认使用 BRE,要使用 ERE 可以 sed -E。 命令格式: -```shell +```console $ sed [OPTIONS] 'command' file(s) $ sed [OPTIONS] -f scriptfile file(s) ``` @@ -221,7 +221,7 @@ $ sed [OPTIONS] -f scriptfile file(s) - a 当前行下插入文本 - i 当前行上插入文本 -```shell +```console $ echo -e "seD\nIS\ngOod" > sed_demo $ cat sed_demo seD @@ -252,7 +252,7 @@ awk 逐行处理文本,对符合的 patthern 执行 action。需要注意的 一些示例: -```shell +```console $ cat awk_demo Beth 4.00 0 Dan 3.75 0 @@ -272,7 +272,7 @@ Susie 76.5 awk 语言是「图灵完全」的,这意味着理论上它可以做到和其他语言一样的事情。这里我们不仅可以对每行进行操作,还可以定义变量,将前面处理的状态保存下来,以下是一个求和的例子: -```shell +```console $ awk 'BEGIN { sum = 0 } { sum += $2 * $3 } END { print sum }' awk_demo 337.5 ``` From 9883b956a7d8b6e17212bff76e3f55e049aa2968 Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:12:47 +0800 Subject: [PATCH 13/14] Add markdownlint from Linux 201 Though we're not going to immediately use markdownlint here yet... Just for writers' reference. --- .markdownlint.jsonc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .markdownlint.jsonc diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc new file mode 100644 index 00000000..6ddd90df --- /dev/null +++ b/.markdownlint.jsonc @@ -0,0 +1,20 @@ +{ + "MD007": { // Unordered list indentation + "indent": 4 + }, + "MD013": false, // Line length + "MD033": { // Inline HTML + "allowed_elements": [ + "br", // Useful in tables + "figure", "figcaption", + "s", "del" // Python-Markdown parsing issue with CJK + ] + }, + "MD046": false, // Use fenced code block style, too many false positives + "MD051": false, // Link fragments should be valid, false positives + "MD052": false, // Reference link should be defined and used, false positives with includes/man.md + "MD010": false, // Some command output contains hard tabs + "MD024": { // Allow multiple headers with the same content, if they are not siblings + "siblings_only": true + } +} From 91d156e8cb11f55f3f45a3c9685e1fa78c164651 Mon Sep 17 00:00:00 2001 From: taoky Date: Sat, 12 Apr 2025 23:14:17 +0800 Subject: [PATCH 14/14] Prettier for .markdownlint.jsonc --- .markdownlint.jsonc | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc index 6ddd90df..1dda4b77 100644 --- a/.markdownlint.jsonc +++ b/.markdownlint.jsonc @@ -1,20 +1,25 @@ { - "MD007": { // Unordered list indentation - "indent": 4 - }, - "MD013": false, // Line length - "MD033": { // Inline HTML - "allowed_elements": [ - "br", // Useful in tables - "figure", "figcaption", - "s", "del" // Python-Markdown parsing issue with CJK - ] - }, - "MD046": false, // Use fenced code block style, too many false positives - "MD051": false, // Link fragments should be valid, false positives - "MD052": false, // Reference link should be defined and used, false positives with includes/man.md - "MD010": false, // Some command output contains hard tabs - "MD024": { // Allow multiple headers with the same content, if they are not siblings - "siblings_only": true - } + "MD007": { + // Unordered list indentation + "indent": 4 + }, + "MD013": false, // Line length + "MD033": { + // Inline HTML + "allowed_elements": [ + "br", // Useful in tables + "figure", + "figcaption", + "s", + "del" // Python-Markdown parsing issue with CJK + ] + }, + "MD046": false, // Use fenced code block style, too many false positives + "MD051": false, // Link fragments should be valid, false positives + "MD052": false, // Reference link should be defined and used, false positives with includes/man.md + "MD010": false, // Some command output contains hard tabs + "MD024": { + // Allow multiple headers with the same content, if they are not siblings + "siblings_only": true + } }