{出处1 《Linux/Unix 设计思想》 — Mike Gancarz}
核心思想:KISS (Keep it simple, stupid)2 https://en.wikipedia.org/wiki/KISS_principle。
Zettelkasten3 https://en.wikipedia.org/wiki/Zettelkasten 为德语,翻译为英文为 slip box,亦即卡片盒。
发明人:德国社会学家 Niklas Luhmann(尼克拉斯·卢曼)4 https://en.wikipedia.org/wiki/Niklas_Luhmann,毕业后当公务员,业余爱好社会学,依靠此方法成为了大学教授、出版了 70 本专著、400 篇学术文章。
将各种来源的想法、内容写在卡片上,放进盒子里,彼此建立连接。
两种主要的拓扑结构:中介(mediator)拓扑和代理(broker)拓扑。
主要考虑两个方面:核心系统和插件模块。
插件和核心系统的通信规范包含标准规范和自定义规范。
3 种常见拓扑结构:
专门为了解决伸缩性和并发问题而设计。
两个主要模块:处理单元和虚拟化中间件。
5 种软件架构模式比较
{出处11 《写给大家看的设计书》 — Robin Williams}
相近的元素以视觉单元的形式出现。
每种要有视觉上的联系。
视觉元素要重复出现。
即要避免页面上的元素太过相似。
应用设计原则前
应用设计原则后
遗忘曲线
一种轻量级标记语言,由约翰·格鲁伯创建。20 https://en.wikipedia.org/wiki/Markdown允许人们使用易读易写的纯文本格式编写文档,然后转换成 HTML。
主要用于统计分析、绘图以及数据挖掘的编程语言。21 https://en.wikipedia.org/wiki/R_(programming_language)
两大特点:
方法一:
$ sudo apt install r-base
$ R
install.packages("rmarkdown")
方法二:
$ docker pull toyland/bookdown
$ docker run --rm -v $PWD:/work toyland/bookdown
---
title: "R Markdown:动态生成文档利器"
author: "徐小东"
date: "2022-12-05"
header-includes:
- \usepackage{ctex}
output:
beamer_presentation:
theme: default
latex_engine: xelatex
---
## Markdown
一种轻量级标记语言,由约翰·格鲁伯创建。
---(snip)---
$ Rscript -e 'rmarkdown::render("rmd.Rmd", "all")'
输出为 rmd.pdf
。
```{bash}
ls *.Rmd
```
ls *.Rmd
## arch-share.Rmd
## book-guide.Rmd
## encrypted-squashfs.Rmd
## fapolicyd.Rmd
## font-render.Rmd
## ide-solution.Rmd
## ide-tech.Rmd
## ide.Rmd
## initrd.Rmd
## linux-dm.Rmd
## oemid.Rmd
## oemid_old.Rmd
## oemscan.Rmd
## pipewire.Rmd
## rmd.Rmd
## time-man.Rmd
## wm.Rmd
knitr::kable(iris[1:5, ], caption = 'A caption')
A caption
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | setosa |
4.9 | 3.0 | 1.4 | 0.2 | setosa |
4.7 | 3.2 | 1.3 | 0.2 | setosa |
4.6 | 3.1 | 1.5 | 0.2 | setosa |
5.0 | 3.6 | 1.4 | 0.2 | setosa |
#plot(cars, pch = 18)
WM 即 window manager,亦即窗口管理器,它主要用于控制窗口的布局和外观。一般来说,WM 是桌面环境的一部分,但它也可以独立使用。
堆叠式
平铺式
二者的主要区别如下:
类型 | 布局 | 内容 | 改变行为 |
---|---|---|---|
堆叠式 | 特定顺序(层) | 会重叠 | 鼠标 |
平铺式 | 水平/垂直平铺 | 不会重叠 | 键盘 |
平铺式相比堆叠式的窗口管理方法具有下列优点:
使用多显示器
ALSA28 https://alsa-project.org/ 是 Advanced Linux Sound Architecture 的简称,它主要包含两部分:
PulseAudio29 https://www.freedesktop.org/wiki/Software/PulseAudio/ 是一个具备网络能力的声音服务器,它作为接口引擎介于应用程序和 ALSA 之间。
Linux API
PulseAudio 的后台 daemon 从一个或多个源(进程、捕捉设备等)接收声音输入,然后将这些声音源重定向到 sinks(声卡、远端 PulseAudio 服务器、其它进程)。
PulseAudio 主要包括以下部分:
JACK30 https://jackaudio.org/ 是 JACK Audio Connection Kit 的简称,它是一个专业级的声音服务器,在音频和 MIDI 数据间提供实时、低延迟的连接。从 2002 年起,JACK 是 Linux 上专业音频软件的关键基础架构和默认标准。
JACK 包括:
PipeWire31 https://pipewire.org 由 Wim Taymans(Red Hat 工程师,同时也是 GStreamer 的创建者)所开发,它是 Linux 上用于处理音频及视频流的服务器。PipeWire 提供统一的框架访问多媒体设备,而上层应用则通过 PipeWire 的 API 来使用硬件,其主要特点包括:
The multimedia stack
PipeWire
PipeWire 主要包括:
针对桌面及专业级音频使用场景提供统一的音频基础架构,终结碎片化的音频现状。
PipeWire 采用 MIT 许可授权。
显示管理器的英文全称为 display manager,也叫 X display manager,意指在 X 服务器上启动登录会话的图形化登录管理器。
login
程序/etc/passwd
看帐号是否存在/etc/shadow
看密码是否匹配login
程序 fork 子进程创建登录 shell文本模式登录过程
XDM(X Display Manager):X11 的默认显示管理器,但功能极少。
GDM33 https://wiki.gnome.org/Projects/GDM(GNOME Display Manager):用于 GNOME 桌面环境,支持 X11 和 Wayland,用户能选择会话类型,使用定制主题。
SDDM34 https://github.com/sddm/sddm(Simple Desktop Display Manager):用于 KDE Plasma 桌面环境,功能上跟 GDM 类似。
LightDM35 https://github.com/canonical/lightdm:由 Ubuntu 背后的公司所开发,是一个跨桌面的显示管理器,支持不同的显示技术(X11、Wayland),兼容标准(PAM、logind),能使用各种前端来绘制用户界面(Greeters):
Greeter | OS |
---|---|
GTK | Xubuntu |
Unity | Ubuntu |
Deepin | Deepin |
Pantheon | elementary OS |
Slick | Linux Mint |
是包含有一套字形与字符的电子数据文件,常分为:
setfont
FONT
(/etc/default/console-setup
)用来将字符栅格化并映射成位图以及提供其他字体相关业务的支持,它提供了一个简单、易用并统一的接口来访问字体文件的内容。37 https://www.freetype.org
用于文字塑形的软件开发库,亦即用于转换 Unicode 文本到字形指标及方位的过程。38 https://github.com/harfbuzz/harfbuzz
用于配置、定制全系统的字体,或将字体提供给应用程序使用。39 https://www.freedesktop.org/wiki/Software/fontconfig/
/etc/fonts
)fc-list
、fc-match
、fc-cache
等Linux 图形栈
DRI40 https://dri.freedesktop.org/ 即 Direct Rendering Infrastructure,在 X11 下以安全、高效的方式直接访问图形硬件的框架。DRI 实现分散在 X 服务器及其相关的客户端库、Mesa 和 DRM 内核子系统中。
DRM41 https://dri.freedesktop.org/wiki/DRM/ 即 Direct Rendering Manager,Linux 内核中负责显卡 GPU 的接口子系统。DRM 暴露 API,用户空间程序可以使用它向 GPU 发送命令和数据,并执行一些操作,比如配置显示器的模式设置。用户空间程序可以使用 DRM API 命令 GPU 进行 3D 硬件加速渲染和视频解码,以及 GPGPU 计算。
/dev/dri/card0
KMS 即 kernel mode-setting,激活计算机显示控制器的显示模式(屏幕分辨率、颜色深度和刷新率)。
DRM 的用户空间库,便于用户空间程序与 DRM 子系统交互。
也叫 Mesa3D42 https://mesa3d.org/,OpenGL、Vulkan 和其他图形 API 规范的开源软件实现。Mesa 将这些规范转换为特定于供应商的图形硬件驱动程序。除了游戏等 3D 应用程序,现代化显示服务器使用 OpenGL/EGL。因此,所有图形通常都经过 Mesa。
主要分为两部分:
xserver-xorg-video-*
。GNU Emacs43 https://www.gnu.org/software/emacs/:可扩展、可定制、完全自由的文本编辑器。
Org-mode44 https://orgmode.org/:适用于 GNU Emacs 的文本编辑模式,由 Carsten Dominik 在 2003 年开发,常用于:
很多人用它管理自己的整个数字生活。
随着 Org-mode 的成功及流行,它已被移植到其他编辑器,如:
.org
Org mode 示例
Org mode 表格
Org mode 计划
内核是硬件与软件之间的一个中间层。作用是将应用程序的请求传递给硬件,并充当底层驱动程序,对系统中的各种设备和组件进行寻址。
Kernel 架构类型
Linux kernel 是自由开源、单体、模块化、多任务、类 Unix 的操作系统内核。
Linux kernel 代码行数
Kernel 的组成部分
问题:
这两个任务是称之为调度器的内核子系统的职责。
解决方案:
抢占式多任务处理(preemptive multitasking),各个进程都分配到一定的时间段执行,但重要的进程会比次要的得到更多的 CPU 时间。
CFS 调度器
所有的可运行进程都按时间在一个红黑树中排序,所谓时间即其等待时间。等待 CPU 时间最长的进程是最左侧的项,调度器下一次会考虑该进程。等待时间稍短的进程在该树上从左至右排序。
从进程的角度来看,Linux 将虚拟地址空间划分为两个部分,分别称为内核空间和用户空间。
虚拟地址空间
大多数情况下,单个虚拟地址空间就比系统中可用的物理内存要大。内核和 CPU 必须考虑如何将实际可用的物理内存映射到虚拟地址空间的区域。
虚拟和物理地址
可取的方法是用页表来为物理地址分配虚拟地址。虚拟地址关系到进程的用户空间和内核空间,而物理地址则用来寻址实际可用的内存。
分配虚拟地址
多级分页:为减少页表的大小并容许忽略不需要的区域,计算机体系结构的设计会将虚拟地址划分为多个部分。
伙伴系统
伙伴系统:快速检测内存中的连续区域,供内核分配连续页。
slab 分配器
slab 缓存:分配比页帧小的内存块,并缓存频繁使用的小对象。
内核必须处理 3 方面的问题:
外设寻址的分层模型
内核与外设通信的方法:
设备文件:用于访问扩展设备,这些文件建立了与某个设备驱动程序的连接,以支持与扩展设备的通信。
I/O 调度:内核采用的各种用于调度和重排 I/O 操作的算法,称之为 I/O 调度器。
虚拟文件系统:为支持各种本机文件系统,且同时允许访问其他操作系统的文件,Linux 内核在用户进程(或 C 标准库)和文件系统实现之间引入了一个抽象层。该抽象层称之为虚拟文件系统(Virtual File System),简称 VFS。
Ext 文件系统族:Ext2/3/4
硬盘上的启动扇区和块组
每个文件系统都由大量块组组成,在硬盘上相继排布。
Ext2 文件系统的块组
块组是 Ext2 文件系统的核心要素。
Ext3:提供了一种日志(journal)特性,记录了对文件系统数据所进行的操作。在发生系统崩溃之后,该机制有助于缩短 fsck 的运行时间。
Ext4:大型文件系统(单文件最大支持 16 TiB,卷最大支持 1 EiB)、持久预分配、日志校验和、透明加密等。
问题:
从程序员的视角来看,程序如何访问网络功能?
解决方案:
网卡的运作方式与普通的块设备和字符设备完全不同,使得经典的 UNIX 箴言“万物皆文件”不再完全适用。
将一种称为套接字的特殊结构用作到网络实现的接口,这种方案现在已经成为工业标准。
内核中分层模型的实现
内核网络子系统的实现与 TCP/IP 参考模型非常相似。
/sys/class/net
)系统调用用于从用户应用程序调用内核例程,以利用内核的一些专门的功能。
strace
。用来创建 GUI 的跨平台 widget 工具包。其架构如图所示:
GTK 架构
由 GNOME 维护,用 C 编写的低级系统库。开始为 GTK 的一部分,后从非 GUI 部分剥离而成。它包含下列组件:
libgio-2.0
,但与 GLib 一起打包。GIO 与 GVfs
gvfsd
: 后台 daemon,管理器及消息路由,由 GIO
客户端启动gvfsd-fuse
: FUSE daemon,由 gvfsd
启动gvfsd-metadata
: 元数据存储,由 GIO 客户端启动gvfs-*-volume-monitor
: 卷监视器gvfsd-{sftp,smb,http}
: mount 后端gio
: GIO 命令行工具initial ramdisk,它是一种将临时的根文件系统载入内存的方案,主要用于 Linux 的启动过程。也叫 early user space (早期用户空间),在 Linux kernel 2.5.46 引入。从出现至今存在以下两种方案:
initrd 在 Linux 引导过程中的作用
从根本上说:
其他次要的因素:
存储:initrd 镜像必须存储在 Linux bootloader 或引导固件可访问的位置,包括根文件系统本身、光盘上的引导镜像、本机磁盘上的小分区 (引导分区,一般为 ext2 或 FAT 文件系统) 等。
载入:bootloader 将载入内核和 initrd 镜像到内存,然后启动内核,并传递镜像的内存地址,内核检测镜像的格式,要么是 initrd,要么是 initramfs 方案。
initrd 通过特殊的块设备 (/dev/ram) 进行挂载,有些使用 ext2 文件系统镜像,有些使用 cramfs 镜像 (Debian)。内核执行其中的 /linuxrc 作为第一个进程,退出后执行 /sbin/init 开始正常的引导过程。
initramfs 镜像是 cpio 存档 (为节省空间可压缩),该存档由内核解包到特殊的 tmpfs 上。相比 initrd 的优势,不需要将中间文件系统或块驱动编译到内核中。内核执行 /init 作为第一个进程。
挂载准备:Debian 生成定制的 initrd 镜像,只包含必要的 ATA、SCSI、文件系统内核模块。Fedora、Ubuntu 生成更通用的 initrd 镜像。
mkdir --parents /usr/src/initramfs/{bin,dev,etc,lib,lib64,mnt/root,proc,root,sbin,sys}
cp --archive /dev/{null,console,tty,sda1} /usr/src/initramfs/dev/ # 设备节点
应用程序:拷贝想要在引导时执行的二进制程序及库,可用 busybox 替代。
编写 init 脚本:
#!/bin/busybox sh
# Mount the /proc and /sys filesystems.
mount -t proc none /proc
mount -t sysfs none /sys
# Do your stuff here.
echo "This script just mounts and boots the rootfs, nothing else!"
# Mount the root filesystem.
mount -o ro /dev/sda1 /mnt/root
# Clean up.
umount /proc
umount /sys
# Boot the real thing.
exec switch_root /mnt/root /sbin/init
find . -print0 | cpio --null --create --verbose --format=newc | gzip --best > /boot/custom-initramfs.cpio.gz
配置 GRUB:
initrd custom-initramfs.cpio.gz # /boot/grub/grub.cfg
问题:因为一个用户可以拥有一个文件,所以他能够读取、写入,甚至删除该文件。那么,对于系统上的其他用户来说,他们被允许做什么?
资源与所有权
32 位数字值,Linux 通过 UID 标识用户,用户属于一个或多个组 (GID)。
使用简单的基于文件的接口。
/etc/passwd
用户数据库
/etc/group
/etc/shadow
/etc/gshadow
Linux 访问资源的核心概念。
类型或权限范围
访问类型
访问类型
cd
) 或列出内容 ( ls
)。从进程的视角来看,相关的权限是什么。
与 root 关联的传统权限分解成可独立分配给每个线程的不同单元。
CAP_NET_ADMIN
:允许各种网络相关操作。
CAP_SYS_ADMIN
:允许系统管理操作。
CAP_SYS_PTRACE
:允许使用 strace 来调试进程。
能力一般仅与系统级任务相关。
查看能力: capsh --print
。
管理能力: getcap
、 setcap
。
seccomp
来限制进程可用的系统调用。为 Linux
内核提供沙箱能力。{作者 David J.Agans50 https://book.douban.com/subject/5376270/}
理解系统
理解系统的基本方法就是阅读手册,逐字逐句阅读整个手册,避免跳读,问题的线索可能就隐藏在被略过的那些章节中。知道工作流程,尝试寻找 bug 时,必须知道要查找的路线。了解工具,调试工具是用来观察系统的眼和耳,必须选择正确的工具,正确地使用工具,并正确地解释得到的结果。
制造失败
原因是可以观察它,可以专心查找原因,可以判断是否已修复问题。从头开始,引发失败。
不要想,而要看
观察失败,一定要亲眼看到实际错误是如何发生的,观察往往比猜测能够更快地找到问题。查看细节,一直观察,直到把问题的原因锁定在几种可能性之内。猜测只是为了确定搜索的重点目标。
分而治之
调试的核心。缩小搜索范围,从有问题的支路开始查找问题。
一次只改一个地方
使用步枪,而不要用散弹枪。与正常系统进行比较。追问:自从上一次能够正常工作以来你更改了什么?
保持审计跟踪
记下你的每步操作、顺序和结果。魔鬼隐藏在细节中,描述事情的时候要具体且一致。
检查插头
敢于怀疑自己的假设,从头开始检查。
获得全新观点
要想重新理清一个案子的头绪,最好的方法就是把它将给别人听 — 福尔摩斯
寻求帮助,询问专家,借鉴别人的经验。
如果你不修复 bug,它将依然存在
bug 从来不会自己消失,要从根本上解决问题。
它能有效的支持你的当下和未来的工作,告诉你信息都被放在了哪里,以及当你需要的时候就能快速找到,并且不会被工具所束缚。
别让你的信息变成坟场!
PARA 方法由个人生产力专家 Tiago Forte51 https://fortelabs.co/about-forte-labs/ 提出,同时他也是《Building a Second Brain》一书的作者。PARA 是以下 4 个单词的首字母缩写:
项目,具有明确目标及时间范围的一系列任务,例如:完成应用原型、开发项目计划、写博文等。
领域,日常需要精进的领域,可以是你的兴趣,也可以是你想建立的习惯、长期目标,例如:产品开发、写作、生产力等。
资源,感兴趣的题目或主题,支撑领域的外部知识储备,例如:项目管理、习惯养成、在线市场等。
存档,上述 3 类之外不活动的内容,也许对未来有用,例如:已完成的项目、不再维护的领域、不再感兴趣的资源。
如上图,领域:Product Development,项目:product X launch,任务:write first draft of blog post。任务与项目相关联。项目总是归属于某个领域。
PARA 方法为我们提供了一种组织数字信息的思路,其核心是根据数字信息的可操作性程度,对信息进行聚焦或转移。它不是硬性地把信息锁定在某个类目上,而是按信息的使用程度来显示它们目前的状态。
PARA 里的信息是可以流动的:
会否付诸实际行动,是 PARA 方法的关键。
项目代表当下,而领域更加关注未来。创建一个清晰的项目清单,能让你知道你的能力边界。而一旦界定了边界,你就可以有意识地、战略性地决定做或者不做,如何弥补还是尽快放弃。
理清你的领域
理清领域最难的地方在于,你要坦然面对自己的内心。停下来问问自己想要成为什么样的人(而不是别人希望我们成为的人),那么可以把这件事当做一切的起点。
先定义项目清单
核心问题是定义你的项目,而工具只是一个解决手段。与其寻找 「一个万能的通用工具」,不如制定你的项目列表,然后将这个列表复制到你现在和将来使用的每一个工具上。
建立项目清单
收集完整的清单是获得控制权的第一步。创建一个清晰的项目清单,让你有信心对新的承诺说是或不是。
和过去告别
如果从未使用过 PARA 方法,那么可以这样重新开始。不如和过去的信息告别,将它们束之高阁,当需要的时候,通过搜索还是能找到它们。所谓近年流行的讲法“断舍离”。
Container (容器):使用 Linux namespace (名字空间)、cgroups (控制组)、及 CoW (写时拷贝) 文件系统来提供应用级依赖管理的 Linux 进程组。
使用场景包括本地测试和开发、分布式生产环境,如:Kubernetes。
一般通过容器镜像和人类友好的用户接口这种标准化的方式来定义打包。OCI (Open Container Initiative) 规范定义和分发容器镜像、执行容器。
容器具有 immutability (不可变性)。
Linux 本来有资源的全局视图,为了允许进程有资源的局部视图 (如:文件系统、网络、甚至用户等),于是 Linux 引入了名字空间。
Linux 名字空间是有关资源可见性的内容,且可以用来隔离操作系统资源的不同方面。
创建名字空间的系统调用:
clone
:用于创建子进程,该子进程可以与父进程共享其部分执行上下文unshare
:用于从现有的进程移除共享的执行上下文setns
:用于将现有的进程合并到现有的名字空间查看名字空间: sudo lsns
一种管理进程组的机制,可用来控制系统资源占用,如:CPU、内存、I/O 等。
内核提供两个 cgroups 版本:
cgroups 包含 CPU、内存、I/O、PID、device 等控制器。
systemctl status
systemd-cgtop
Copy-on-Write (写时拷贝) 文件系统用来提升 I/O 速度,同时减少使用空间。
原文件 File 1 由 A、B、C 块组成,拷贝的文件叫 File 2。代替拷贝实际的块,只拷贝元数据 (块的指针)。
当 File 2 修改时 (假定 C 块更改),只拷贝 C 块:新的 C’ 块被创建,而 File 2 仍然指向未修改的 A 和 B 块。
union mounts (联合挂载):将多个目录组合 (挂载) 到一个位置,这样,对于最终目录的用户来说,该目录包含所有参与目录的组合内容。
实现包括:
在容器中,CoW 用于构建时,将应用及所有依赖打包成可分发的单一、自包含文件。通常将 CoW 文件系统与绑定挂载结合使用,以一种有效的方式将不同依赖项的内容层放在彼此之上。
在谈及 Linux 命令行时,有时会遇到控制台、终端、终端模拟器、以及 Shell 这几个基本概念。有些朋友往往傻傻分不清楚,下面就来做个一一介绍。
控制台(Console),又称为系统控制台(System console)、计算机控制台(Computer console)、根控制台(Root console)、以及操作员控制台(Operator’s console)。事实上,早先的控制台是一种用来操作计算机的硬件,如图所示。52 https://en.wikipedia.org/wiki/System_console#/media/File:IBM_1620_Model_1.jpg从这幅图片中,我们可以看到 IBM 1620 计算机的控制台由左边的操作前面板和右边的打字机组成。通过控制台,操作员将文本数据或待执行的指令录入到计算机,并最终通过计算机读取或执行。
IBM 1620 的控制台
IBM 1620 控制台的操作前面板
随着计算机的发展,控制台从硬件概念变成了一个软件概念。于是,控制台有了新的称呼:虚拟控制台。虚拟控制台正好与物理的控制台硬件相对。通过观察 Linux 系统的启动过程,我们不难发现:在经过计算机硬件自检之后,一旦由引导载入程序接管,不一会儿便会进入系统控制台。在这个过程中,通常会显示如图所示的 Linux 系统引导信息。53 https://en.wikipedia.org/wiki/Linux_console#/media/File:Knoppix-3.8-boot.png
Linux 系统虚拟控制台
跟控制台一样,起初的终端(Terminal)也是一种计算机硬件设备。从外形上看,终端类似于我们今天所看到的显示器和键盘的结合体。通过终端,用户将指令和数据输入到计算机。同时,终端也将计算机执行的结果展示给用户。图中显示的是曾经广为流行的终端 DEC VT100。54 https://en.wikipedia.org/wiki/Computer_terminal#/media/File:DEC_VT100_terminal.jpg
DEC VT100 终端
或许你会产生疑问,为什么会出现终端这种硬件设备呢?以今天的眼光来看,显得似乎有些难以理解。诞生之初的计算机造价相当昂贵,可不像现在人人都能拥有一台那么简单。除了大型商业组织或大学研究机构,很难在别处看到计算机的身影。为了能够共享计算机资源,终端应运而生。然而,伴随着科技的进步,终端最终掉进了历史的黑洞。不过,它后来却以新的形式重生,这就是终端模拟器(Terminal emulator),或称之为虚拟终端。
终端模拟器,即用来模拟终端硬件设备的应用程序。在物理终端中存在的某些显示体系结构,比如用来控制色彩的转义序列、光标位置等在终端模拟器中也得到了支持。下图显示 Linux 中流行的终端程序之一 XTerm。
XTerm 终端模拟器
不管是 Linux 操作系统,还是 macOS 操作系统,乃至 Windows 操作系统,今天都有许多终端模拟器可以选择。以下罗列的是这三个操作系统中比较流行的终端模拟器。
TERM
环境变量的选项外,还包括能够使用其搜索功能来查找 Man pages。Shell 是一种命令解释程序,它负责用户输入命令的读取、解析和执行。现代 Shell 除了具有与用户直接交互的特性之外,通常也包含编程功能,支持变量、数组、函数、循环、条件等编程基本要素。
Shell 之所以如此称呼,是由于它相对 Unix 及 Linux 的核心——内核(Kernel)而言,处于整个操作系统的最外层,就像乌龟的壳一样。也正因为如此,Shell 提供用来访问系统服务的用户界面,扮演着与内核交互的角色,如图所示。
Shell 与内核
在 Unix 及 Linux 的发展过程中,出现了许多种 Shell,其中比较知名的包括:sh、csh、ksh、bash、zsh 等等。
sh,即 Bourne shell,它是 Unix 第 7 版的默认 Shell。Bourne shell 由贝尔实验室的 Stephen Bourne 开发,于 1979 年发布。随着《Unix 编程环境》(Brian Kernighan 与 Rob Pike 著)一书的出版,sh 变得大为流行。
Bourne shell 早已被后来的 Shell 所取代,现代 Linux 系统中的 sh 通常是符号链接的某个兼容 Shell。例如,所用的 Debian 里的 sh 为 dash。
root@toydroid:~# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Jan 24 2017 /bin/sh -> dash
而在另一个系统 Arch Linux 上,sh 则为 bash。
root@codeland:~# ls -l /bin/sh
lrwxrwxrwx 1 root root 4 Feb 7 15:15 /bin/sh -> bash
csh 是 C shell 的简称,它由 Bill Joy 开发,通过 BSD 得到了广泛的分发。在风格上,开发者将 csh 设计得像 C 编程语言一样,因而由此得名。同时,csh 具有很不错的交互使用体验。后来被其它 Shell 所吸收的诸如历史、别名、目录栈、文件名补全、作业控制等特性均出自 csh。
csh 有一个改进版本叫 tcsh,目前是 FreeBSD 的默认 Shell。
ksh 指 Korn Shell,其开发者为 David Korn,在 1983 年公布于世。ksh 遵循 POSIX 标准,能够向下兼容 Bourne shell,整合了来自 C shell 的诸多特性。ksh 的一大亮点是引入了 vi 和 Emacs 风格的命令行编辑模式,使用户完全可以按照自己的按键习惯操作。此外,在 ksh 中还增加了关联数组的特性。
由于 ksh 最初以私有软件的形式进行分发,从而被限制了传播。代之以出现的替代品包括 pdksh(public domain ksh,公有域的 ksh)、mksh(后成为 Android 的默认 Shell)等。
bash 作为理查德·斯托曼 GNU 工程的一部分出现,从它诞生之初就是为了用来取代 Bourne shell。Brian Fox 开发了最初的 bash,首个版本发布于 1989 年。如今,bash 已变得十分流行,它是大多数 Linux 发行版以及 macOS 的默认 Shell。此外,通过 WSL(Windows Subsystem for Linux),在 Windows 10 中也可以安装并使用 bash。
bash 的名称来自于 Bourne-again shell,它也遵循 POSIX 标准,其特性吸收自 sh、csh、ksh 等多种 Shell。
zsh 是 Z shell 的简称,最初的版本由 Paul Falstad 所开发,发布于 1990 年。zsh 极大的扩展了 Bourne shell 的功能,并包含来自 tcsh、ksh、bash 等 Shell 的特性。
在交互用户体验上,zsh 尤其出彩。比如,它支持对命令的选项进行补全、可以设置右提示符等,如图所示。
zsh 的右提示符
OODA 循环(OODA loop)是用于观测场景的一个策略。它提供一种结构化的方法来测试基于假设的观测数据,并据此采取行动。即,一种从信号获得可行动洞见的方法。
例如,应用程序运行缓慢。
每个系统的基本信号类型。
/var/log
以时间序列形式采样的数值。一般通过监视来捕捉系统和应用程序的指标。
显示基本的指标
uptime
:系统运行好久、负载均值free -h
:内存占用vmstat 1
:内存状态iostat -z --human
:监视 I/O 设备ss -atup
:网络套接字统计lsof -i TCP:1-1024
:网络连接集中的性能监视
top
:CPU、内存、进程htop
:top 增强版,具有更好的用户界面atop
:除了 CPU、内存外,还包括 I/O、网络状态glances
:https://nicolargo.github.io/glances/动态收集运行时信息。
跟踪来源
使用场景
strace
:调试程序perf
:性能分析eBPF
:将成为实现跟踪的默认标准Overlay(覆盖)网络指在现有的物理网络之上创建的虚拟或逻辑网络。
Overlay 网络
例子:internet、SDN(software-defined networking)
Nebula 是专注于性能、简洁及安全的可扩展 overlay 网络工具。利用它,可以将世界各地的计算机无缝连接在一起。它支持的系统包括 Linux、FreeBSD、macOS、Windows、iOS 及 Android。Nebula 不仅能用于连接少量计算机,而且也能连接成千上万的计算机。
HTTP(HyperText Transfer Protocol,超文本传输协议)是 WWW(万维网)的基础协议,最初由 Tim Berners-Lee 和他的团队在 1989-1991 年期间开发。HTTP 发生了太多的变化,在保持协议简单性的同时,不断扩展其灵活性。如今,HTTP 已经从一个只在实验室之间交换文件的早期协议进化到了现代复杂的互联网协议。
1989 年,在 CERN 工作时,Tim Berners-Lee 编写了透过英特网构建超文本系统的提案。开始叫 Mesh,后来改为 World Wide Web。透过现有的 TCP 及 IP 协议构建,它由 4 个部分组成:
HTTP 的最初版本没有版本号,后来叫 0.9。HTTP/0.9 非常简单,请求只有一行:
GET /mypage.html
响应也很简单,只有文件本身:
<html>
A very simple HTML page
</html>
HTTP/0.9 很有限,但浏览器和服务器迅速使它功能更多:
此时,一个典型的请求和响应看起来像:
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
<IMG SRC="/myimage.gif">
</HTML>
由服务器和浏览器添加的功能及解决的问题最后形成了 RFC 1945 文档,并定义为 HTTP/1.0。
在实现 HTTP/1.0 的同时,也在并行推进协议的标准化。HTTP 的第一个标准化版本 HTTP/1.1 于 1997 年初发布。HTTP/1.1 引入了许多改进:
一个典型的请求流:
GET /en-US/docs/Glossary/Simple_header HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/en-US/docs/Glossary/Simple_header
200 OK
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html; charset=utf-8
Date: Wed, 20 Jul 2016 10:55:30 GMT
Etag: "547fa7e369ef56031dd3bff2ace9fc0832eb251a"
Keep-Alive: timeout=5, max=1000
Last-Modified: Tue, 19 Jul 2016 00:59:33 GMT
Server: Apache
Transfer-Encoding: chunked
Vary: Cookie, Accept-Encoding
(content)
HTTP/1.1 作为 RFC 2068 发布。
在 HTTP/2 发布之前,HTTP/1.1 稳定运行了超过 15 年,并在下列方面进行了扩展:
网页变得越来越复杂,更多的数据传输意味着更多的 HTTP 请求。2010 年初,Google 实现了一个试验协议 SPDY。SPDY 增加了响应性,并解决了重复数据的传输问题,成为 HTTP/2 的基础。
HTTP/2 与 HTTP/1.1 的差异:
HTTP/2 在 2015 年正式标准化。截止 2022-01,全球大约 46.9% 的网站使用。
HTTP/3 使用 QUIC 协议代替 TCP 协议。截止 2022-10,全球大约 26% 的网站使用。
HTTP/3 于 2022 年在 RFC 9114 中定义。
ZFS 是一个具有卷管理能力的文件系统。最初是 Sun Microsystems Solaris 操作系统的一部分,后来随开源的 OpenSolaris 发布。在 Oracle 收购 Sun Microsystems 后,将其闭源。2005 ~ 2010 年期间,ZFS 的开源版本被移植到 Linux、FreeBSD、Mac OS X。2013 年,OpenZFS 创建来用于协作开源 ZFS 的开发。
存储数据管理一般包括两个方面:
ZFS 与其它文件系统的不同之处在于,它统一了存储系统的这两种角色,既是卷管理器,也是文件系统。ZFS 被设计成确保存储在磁盘上的数据不会因硬件或操作系统的物理错误或错误处理而丢失。ZFS 也包含数据集和池级快照及复制机制。
ZFS 存储池
ZFS 特性非常丰富,以下是几个典型的代表:
ZFS 许可协议为 CDDL,与 GPL 不兼容,故不能随 Linux 内核一起分发。
apt update
apt install zfs-dkms zfsutils-linux
创建存储池,raidz vdev:
# zpool create -f -m /mnt/data bigdata \
raidz \
ata-ST3000DM001-9YN166_S1F0KDGY \
ata-ST3000DM001-9YN166_S1F0JKRR \
ata-ST3000DM001-9YN166_S1F0KBP8 \
ata-ST3000DM001-9YN166_S1F0JTM1
创建数据集:
# zfs create <nameofzpool>/<nameofdataset>