Linux-终端基础提示和技巧-三-

96 阅读1小时+

Linux 终端基础提示和技巧(三)

原文:Basic Linux Terminal Tips and Tricks

协议:CC BY-NC-SA 4.0

九、硬件详细信息和/dev/

在这一章中,我们将会看到一些有用的命令来检查你正在使用或连接的机器的硬件细节。当通过 SSH 连接到一台机器时,您可能不知道您正在处理哪种硬件的所有细节。即使你使用的是你熟悉的机器或一些嵌入式设备,你也可能不知道所有的细节。此外,如果您完全熟悉设备的硬件,您可能能够通过检查细节来发现硬件问题,以查看它们是否与您预期的相匹配。

运行lshw时,/dev/目录中的文件夹丢失或设备丢失可能会提醒您某些硬件未能安装或已损坏。

用于硬件细节的命令

在这一节中,我们将看看命令和程序,它们可以让您更好地了解您正在使用的系统上的硬件类型。

每个人都知道ls,但是有一个完整的硬件查询命令列表,它们的名字来自这个命令。表 9-1 中列出了一些有助于找出机器底层硬件信息的工具。

表 9-1

获取硬件详细信息的有用命令

|

命令/应用

|

描述

| | --- | --- | | lspci | 列出所有 PCI 设备 | | lsblk(消歧义) | 列出所有块设备 | | sudo fdisk-l | 与lsblk相似,但具有更详细的信息,包括扇区 | | lscpu(中央处理器) | 列出了有关 CPU 架构的信息 | | 断续器 | 硬件详细信息的深入列表。也可以使用-short标志来显示压缩版本 | | ls /dev | Linux 系统上的/dev文件夹 | | ls -l /sys/block | 列出连接的硬盘和总线 ID。您可能还会看到几个名为loop的虚拟设备 | | lsusb(USB) | 显示系统中 USB 总线以及连接到总线的设备的信息 | | cat /proc/cpuinfo | 提供关于处理器的数据 | | 自由 h | 显示空闲内存,-h为人类可读 | | 东风-m | 列出挂载的文件系统 | | ip a | 列出网络接口 | | netstat -i | 用于列出接口的ifconfig的更简洁的替代方法 | | hdparm | 获取/设置 SATA/IDE 设备参数 | | 联名制-r | 显示内核版本 |

/dev/文件夹

另一个可用于深入了解连接硬件的文件夹是/dev文件夹。/dev文件夹包含许多与已安装设备相关的文件和文件夹,以及一些其他具有特殊用例的非硬件文件。表 9-2 显示了可以在/dev文件夹中找到的文件的详细列表。您的系统可能不会拥有所有这些。

Note

所有以类似于js0的数字结尾的文件可以有多个实例;每个后续实例都用递增的数字命名,在本例中为js1js2等等。

表 9-2

/dev/文件夹中的设备示例

|

文件夹/文件

|

描述

| | --- | --- | | /dev/dsp | 数字信号处理器 | | /dev/fd0 | 软盘阅读器 | | /dev/fb0 | 帧缓冲设备 | | /dev/js0 | 模拟操纵杆 | | /dev/lp0 | 并行打印机 | | /dev/usb/lp0 | USB 打印机 | | /dev/cdrom | cd-r om | | /dev/dvd | 数字影碟 | | /dev/rtc | 实时时钟 | | /dev/sda | 硬盘驱动器 | | /dev/ttyS0 | 串行端口 |

这个列表并不完整。本质上,任何可以连接到您的计算机的 I/O 设备都会出现在/dev文件夹中。

/dev/文件夹中的特殊文件

除了物理设备,您还可以在/dev/文件夹中找到一些特殊的文件。这些表示具有一些特殊行为的伪设备。表 9-3 显示了一个流行的列表。

表 9-3

/dev/文件夹中的特殊文件

|

文件夹/文件

|

描述

| | --- | --- | | /dev/null | 一种特殊的文件,可以丢弃任何扔进去的东西 | | /dev/random | 产生随机输出的特殊文件 | | /dev/天王星 | 与random相同,但当系统耗尽熵时不会阻塞 | | /dev/stdin | 流程的标准输入 | | /dev/stdout | 流程的标准输出 | | /dev/stderr | 流程错误的标准输出 | | /dev/zero | 一个返回全零的特殊文件 | | /dev/tty0 | 电传打字机(见下面的注释) | | /dev/loop0 | 使文件可用作块设备的伪设备 |

接下来,我们将更深入地看看这些特殊的文件。

电传打字机

TTY ( 电传打字机)是一种可以通过各种媒介发送和接收文本的设备。这个名字来源于历史上的电传打字机,它出现在基于屏幕的计算机之前。自 20 世纪初以来,贝尔公司普遍使用电传打字机;示例见图 9-1 。贝尔后来在 1971 年创建了 Unix,其中包括一个虚拟电传打字机作为核心概念。

img/494886_1_En_9_Fig1_HTML.jpg

图 9-1

贝尔电话杂志 1921 年电传打字机的历史范例

当在 Unix 终端中输入时,您实际上是将文本输入到一个虚拟或伪 TTY 中,它接受输入并可以返回输出。当然,在屏幕终端的情况下,它是模拟的硬件。在任何时候,您的系统都可能有几个 tty。要查看所有内容,只需运行

ls /dev/ | grep tty

可能太多了,无法手工计算;如果您想知道有多少行,您可以将结果输入到wc -l中并获得行数:

ls /dev/ | grep tty | wc -l

就我而言,我有 98 个。为什么这么多?其中一些 tty 代表正常的终端会话,而另一些则有特殊的用例。例如,tty0是一个特殊的别名 TTY,它总是指向当前终端。tty 也可以用于在后台包含进程或应用。试试跑步

ps ax

这将返回进程列表;注意TTY列,它显示了一些流程的父 TTY。一些进程可能被列为?,这意味着它们没有绑定到终端,在后台运行。

也可以通过按下ctrl+alt+F1将您的屏幕直接连接到这些 tty 中的一些,用相关的端子号( F1、F2、F3 等)替换 F1。)。在很多 OS 上,tty1会用于 X 服务器;因此,移动到另一个终端会导致你的电脑看起来完全离开了操作系统(音乐关闭,看不到应用或系统菜单)。

stdin、stdout 和 stderr

特殊文件stdinstdoutstderr是“标准输入”、“标准输出”和“标准误差”的简称它们更类似于 I/O 流,而不是文件本身,但是因为在 Linux 中(几乎)一切都被表示为文件,所以操作系统的这些方面都有相关的文件。

如果你打开它们,你会发现它们完全是空的,尽管你可以在操作系统的后台直接输入文本,例如:

echo hello > /dev/stderr

有必要知道什么是stdinstdoutstderr。你可能会遇到它们,即使它们的文件名没有直接提到它们。通过流程将“标准输入”转换为“标准输出”和“标准误差”的系统如图 9-2 所示。

img/494886_1_En_9_Fig2_HTML.jpg

图 9-2

将标准输入转换为标准输出和标准误差的流程图

/dev/null

一个常用的特殊设备文件是/dev/null。这个文件就像一个黑洞,你把信息输入进去,但是什么也没有出来。起初这听起来可能没什么用,但实际上它可以用来停止一个进程,否则这个进程会将输出打印到终端或日志文件中。

为了展示一个例子,我们将使用ping命令并将我们的输出重定向到/dev/null。我们可以重定向两种类型的输出,标准输出(由 1 ) 和标准误差(由 2 表示)。

为了测试将标准输出和标准错误重定向到/dev/null,我们将创建一个文件,简单地将一条消息写入标准输出,将另一条消息写入标准错误。我在/tmp/out.sh创建我的:

#!/usr/bin/env bash
echo Working
>&2 echo Error

保存文件后,一定要添加执行权限:

chmod +x /tmp/out.sh

接下来让我们试着运行它:

/tmp/out.sh

接下来,尝试使用以下重定向来运行它:

/tmp/out.sh 1>/dev/null

你现在应该只得到错误,因为标准输出被导向黑盒。让我们做同样的事情,但是把 1 换成 2:

/tmp/out.sh 2>/dev/null

正如您可能预料的那样,现在我们只能看到输出,而看不到错误。也可以一次重定向两者。两者的语法略有不同:

/tmp/out.sh > /dev/null 2>&1

图 9-3 显示了每个命令的预期输出。

img/494886_1_En_9_Fig3_HTML.jpg

图 9-3

重定向到/dev/null

/dev/random 和/dev/urandom

另一个有用的特殊设备是 random 和 urandom。这两者本质上是一回事,因为它们都充当输入完全随机数据的设备。因此,它充当伪随机数发生器。像大多数伪随机数发生器一样,它依靠一些输入来产生熵。

用于输入的熵是系统状态的随机方面的结果,例如鼠标移动、按键和其他设备输入(例如,驱动器的速度)。使用这个熵,在/dev/random/dev/urandom中产生随机字符。

randomurandom的主要区别在于,如果random耗尽了熵,它会阻塞一个依赖它的程序,而urandom不会。一般来说,urandom应该是首选。

为了了解/dev/urandom中的数据类型,让我们使用head获取前 500 个字符:

head -c 500 /dev/urandom

这将返回一长串不可读的字符,如图 9-4 所示。

img/494886_1_En_9_Fig4_HTML.jpg

图 9-4

/dev/urandom 中的示例内容

当然这并不完全有用。但是,它可以用来为程序生成有用的随机数据。例如,假设我们想生成一个随机数用于一个程序。我们可以使用od(八进制转储的缩写)来生成一个人类可读的数字:

od -vAn -N1 -tu1 < /dev/urandom

前面的示例生成一个 1 字节大小的无符号数(0–255)。如果我们想做 2 个字节,我们可以运行

od -vAn -N2 -tu2 < /dev/urandom

/dev/zero

您将在/dev文件夹中找到的另一个特殊文件是zero。读取该文件将返回一串零,这种情况将永远持续下去。为了演示/dev/zero,让我们用 512 字节的空 0 创建一个文件:

dd if=/dev/zero of=/tmp/zero count=1

如果你在这之后打开/tmp/zero,你应该看到类似图 9-5 ( 取决于你的文本编辑器如何解释空字符)。

img/494886_1_En_9_Fig5_HTML.jpg

图 9-5

/dev/zero 的输出示例

这主要用于创建虚拟文件。它也可以用来清空计算机上的内存。当文件在计算机上被删除时,底层内存仍然存在,但它已被标记为可用的空闲空间。

通过创建全为零的大型文件,可以删除这些底层数据,尽管这种方法受到了批评,但人们倾向于使用随机数据而不是零,因为先进的方法仍然可以恢复这些数据。

更彻底的方法是使用shred命令,例如:

shred /dev/sda

这不仅会删除驱动器中的内容,还会使它们难以恢复。

内核是什么?

您可能已经听说过 Linux 内核,但是它到底是什么呢?Linux 内核是所有 Linux 操作系统的核心组件,也是构建其他一切的基础。果仁一词最初指的是坚果或水果的中心。同样,Linux 内核是所有 Linux 系统的核心。

Linux 内核控制系统的物理硬件和内部软件之间的所有通信。许多开发人员和 Linux 用户永远也不会直接与内核交互,但是了解一下这意味着什么是值得的。

Linux 内核负责的事情包括

  • 内存管理

  • 进程管理

  • 设备驱动程序

  • 系统调用

  • 安全

很多这样的事情发生时,用户甚至都没有意识到。硬件、内核和进程的层次结构如图 9-6 所示。

img/494886_1_En_9_Fig6_HTML.jpg

图 9-6

用户空间、内核和硬件堆栈

获取内核版本

您可以通过运行以下命令来找出您正在使用的 Linux 内核的版本

uname -r

有关该版本的更多完整信息,可以运行

cat /proc/version

这将返回更多关于你的内核的完整信息,如图 9-7 所示。除了版本之外,还列出了编译内核的人的身份、使用的编译器、编译的类型以及编译的日期/时间。

img/494886_1_En_9_Fig7_HTML.jpg

图 9-7

显示内核版本

配置和安装驱动器

通常在设置服务器时,无论是在个人还是在云中,默认的存储空间都不足以存储数据。在这一节中,我们将看看如何将一个驱动器附加到文件系统。

/dev/一节所述,所有连接的驱动器将显示在/dev/文件夹中。但是,这些将显示为单个文件,而不是可以浏览的文件夹。为了将驱动器视为文件系统,需要挂载它。

安装驱动器的第一步是找出哪个文件在/dev文件夹中。您可以通过运行mount并抓取“/dev/sd”的实例来实现这一点:

mount | grep /dev/sd

这将列出所有连接的驱动器及其挂载点,如图 9-8 所示。

img/494886_1_En_9_Fig8_HTML.jpg

图 9-8

显示可装载的驱动器

注意突出显示的部分/dev/sda4 on / type ext4。这告诉我们一些关于 sda4 驱动器的事情。首先,它被挂载为我们的系统/的根,其次,它的格式是 ext4。

mount命令不会列出所有设备;为了更好地了解情况,尝试运行lsblk,它应该会返回如图 9-9 所示的列表。

img/494886_1_En_9_Fig9_HTML.jpg

图 9-9

使用 lsblk 查看驱动器和分区

注意,在这种情况下,我们可以看到sda ( 物理驱动器)和那个磁盘上的分区( sda 1 到 4 )之间的关系。

在我的例子中,sda3是一个以前用于 Windows 安装的分区。由于不再需要它,我将格式化它并挂载它。无论何时格式化,都要仔细检查驱动器是否有你需要的数据,以及是否是正确的分区名。格式化分区后,所有数据都将丢失。

我们将采取的步骤:

  1. 删除 windows 分区

  2. 创建新分区

  3. 格式化分区

  4. 安装分区

  5. 确保在启动时总是挂载分区

删除分区

要删除分区,首先您将进入相关驱动器的fdisk交互模式:

sudo fdisk /dev/sda

您将被要求输入一个命令;输入d进行删除。然后输入分区号,在我的例子中是 3。为了最终完成更改,输入w命令进行写入。删除过程将开始,如图 9-10 所示。

img/494886_1_En_9_Fig10_HTML.jpg

图 9-10

使用 fdisk 删除分区

现在,如果您再次运行lsblk | grep sd,我们将会看到少了一个分区。

创建分区

接下来,我们将使用释放的空间创建一个新的分区。再次打开fdisk:

sudo fdisk /dev/sda

这次输入命令n进行新建。首先你会被要求选择一个数字;我们将用 3 来替换被删除的那个。接下来,您将被要求选择硬盘上的扇区来启动新分区。在大多数情况下,默认将是最低的可用位置,是一个很好的选择。

选择起始扇区后,你会被问及结束扇区;您可以指定内存中的特定位置或指定分区的大小。我们将简单地选择默认选项,该选项将使用所有剩余空间来创建我们的分区。在我的情况下,我也被问及是否要删除 ntfs 签名,这是 Windows 特有的事情;可以安全移除。该过程的示例如图 9-11 所示。

img/494886_1_En_9_Fig11_HTML.jpg

图 9-11

用 fdisk 创建分区

创建分区后,您需要运行以下命令来重新读取分区表:

partprobe

格式化分区

我们现在有了一个新的/dev/sda3文件,但是我们仍然需要格式化它。我们将使用mkfs命令来完成这项工作,它是“make filesystem”的缩写。

sudo mkfs.ext4 /dev/sda3

Or:

sudo mkfs -t ext4 /dev/sda3

安装分区

格式化分区后,我们现在可以将它挂载到我们的文件系统中。首先,您需要创建一个文件夹,它将被挂载到。推荐的安装位置是/mnt/media,尽管这些文件夹有不同的推荐用途。/mnt文件夹用于手动安装的驱动器,而/media是自动安装的可移动驱动器(如 USB 便携驱动器)将出现的地方。

然而,从技术上来说,没有什么可以阻止你在任何你想安装的地方安装一个设备。在我的例子中,我将创建一个名为/mnt/drive1的文件夹:

sudo mkdir /mnt/drive1

创建完成后,让我们将驱动器安装到它上面:

sudo mount /dev/sda3 /mnt/drive1

从分区到~/的系统链接

把你的存储放在你的主目录之外可能会很尴尬,因为它不在你的主目录之内,而且默认情况下你没有权限。你能做的就是在你的主目录中创建到其他文件夹的系统链接。

例如,假设我们需要更多空间来存放位于~/Movies的电影收藏。首先进入/mnt/drive1并创建文件夹:

sudo mkdir Movies

接下来,让自己成为目录的所有者:

sudo chown $USER:$USER /mnt/drive1/Movies

现在我们有了使用~/Movies的权限,我们将在我们的主目录中创建一个符号链接作为快捷方式,这意味着我们永远不必到主目录之外去使用它(确保第一个参数使用完整路径):

ln -s /mnt/drive1/Movies/ ~/

现在,如果你去你的主目录,你应该看到一个电影文件夹。保存到~/Movies文件夹中的任何内容都将被保存到我们新安装的驱动器中。

使挂载的分区持久化

我们的分区运行良好;你可能认为我们结束了。不幸的是,如果我们现在重启我们的机器,它会在没有sda3挂载的情况下重新启动。为了让新分区在每次启动时挂载到/mnt/drive1,我们还需要做一件事。

启动时,系统查看文件/etc/fstab以确定需要安装哪些驱动器。在我们开始之前,让我们看看需要哪些值:

  1. 块设备的 UUID(用 lsblk -d -fs <文件> 查找)

  2. 要装载的文件夹

  3. 文件系统类型

  4. 安装选项(使用默认选项或参见手册

  5. 是否应该转储文件系统(通常为 0 )

  6. Fsck 顺序(主分区使用 1,其他分区使用 2

要获得分区的 UUID,请使用您自己的分区位置运行以下命令:

lsblk -d -fs /dev/sda3

一旦有了所需的六个值,打开/etc/fstab 进行编辑。我们将使用的值显示在图 9-12 的第二个未注释行中。

img/494886_1_En_9_Fig12_HTML.jpg

图 9-12

编辑/etc/fstab

编辑/etc/fstab时要小心,因为不正确的输入会导致系统重启时进入紧急模式。如果发生这种情况,不要惊慌,只需在紧急模式下使用命令行打开/etc/fstab并注释掉您添加的行。

您可以通过运行以下命令来减少出错的可能性

sudo findmnt --verify

这将发现诸如磁盘上的文件类型和声明的文件类型不匹配之类的问题,但在捕捉错误时并不是 100%安全的。

lm 传感器

安装lm-sensor后,首先需要让应用检测你的系统上有哪些传感器。用...做这件事

sudo sensors-detect

它会问几个问题,您可以回答“是”来启用。在大多数情况下,默认的响应是好的,所以你只需按下回车键。完成设置过程后,您可以运行

sensors

这将返回传感器、风扇和其他可用数据,如图 9-13 所示。

img/494886_1_En_9_Fig13_HTML.jpg

图 9-13

使用 lm 传感器查看传感器

inxi

在获取硬件信息时,可以安装一个类似于lshw的程序来改善体验,这就是 i-nex。它可以与一起安装

sudo apt-get install inxi

默认情况下,它将在单行输出中返回非常基本的数据。要获得完整的详细信息,请使用-F标志运行:

inxi -Fxz

这将返回硬件信息的详细列表,如图 9-14 所示。

img/494886_1_En_9_Fig14_HTML.jpg

图 9-14

使用 inxi 查看硬件

迪米特里

虽然lshwinxi对于大多数人来说应该足以看到一台机器的基本硬件细节,但是dmidecode可以用于更深入的了解。

例如,使用dmidecode,您可以使用以下命令查看 BIOS 信息

sudo dmidecode -t bios

sudo dmidecode的身份独立运行该命令将返回所有详细的系统信息,包括序列号和制造商等信息,这些信息在不太详细的实用程序中是找不到的。当单独使用它时,您可能希望通过管道连接到less以便于阅读:

sudo dmidecode | less

对于主板,可以运行

sudo dmidecode -t baseboard

有各种选项可以通过-t指定,以指定具体的硬件信息;有关更完整的信息,请参见手册页。

摘要

在这一章中,我们看了几种你可以使用像lshwinxidmidecode这样的工具探索系统底层硬件的方法。我们还查看了连接的硬件如何出现在/dev/文件夹中,该文件夹包含硬件设备和许多特殊文件,如对各种任务有用的/dev/null/dev/urandom。我们通过使用mount命令将硬盘安装到/mnt目录中,与/dev文件夹中的硬盘进行交互。

十、解析文本

无论您在 Linux 上做什么,您可能会发现自己在某个时候需要解析文本。由于 Linux 在很大程度上是基于文件的,因此非常需要能够解析大量文本以找到特定值、格式化并处理它的实用程序。

有几个实用程序可用于解析文本。在这一章中,我们将看看这些工具中的几个,以及如何用它们来解析文本。

可做文件内的字符串查找

grep是最常用的命令行工具之一。它允许您在一组文本中查找特定的字符串。例如,给定一个有几行的文件,我们可以找到包含我们要找的文本的那一行。例如,让我们在/etc/passwd文件中找到根用户。

cat /etc/passwd | grep root

您应该得到如图 10-1 所示的单个条目。

img/494886_1_En_10_Fig1_HTML.jpg

图 10-1

从/etc/passwd 中抓取根目录

或者更好的是,我们可以直接在文件本身上执行grep,而不需要管道:

grep root /etc/passwd

你也可以做相反的工作,在没有的情况下查找行,为此添加代表反匹配的-v标志:

cat /etc/passwd | grep -v root

这应该会为系统中的其他用户返回类似的条目。-v标志只是可以和grep一起使用的众多选项之一;详见表 10-1 。

表 10-1

grep 的选项

|

|

描述

| | --- | --- | | -e | 正则表达式模式 | | [构成来自拉丁语、结尾为-us 的名词的复数] | 忽略大写/小写 | | -v | 反转匹配 | | -c | 竞赛比赛 | | 同-EN | 匹配前获取 X 行并显示行号(需要数字输入) | | -h | 匹配行前不显示文件名(当抓取单个文件时默认为 | | [加在以-u 结尾的法语词源的名词之后构成复数] | 精确线匹配 | | -f | 从文件中加载正则表达式 | | 表示“具有…性质的” | 仅输出一行中匹配的部分 | | [构成动植物的古名或拉丁化的现代名] | 匹配后显示 N 行(需要数字输入 | | -乙 | 匹配前显示 N 行(需要数字输入 | | -丙 | 在匹配前后显示 N 行(需要数字输入 |

切口

虽然grep可以解析文件以返回文件中的相关行,但有时需要解析行本身的文本。对于解析单行,cut工作得很好。cut可用于按字符、字节或自定义分隔符拆分一行的内容,例如,用 byte:

echo hello world | cut -b 1,2

前面的命令将返回“he ”,因为这是“hello world”的第一个和第二个字节的内容。也可以从字节 X 到行尾,例如:

echo hello world | cut -b 7-

这应该只返回“你好”。cut不需要从管道接收其输入;您也可以直接从文件中读取。当从文件中读取时,相同的转换将应用于每一行。例如,让我们从/etc/passwd文件中的每一行获取第 1 到第 9 个字节:

cut -b 1-9 /etc/passwd

您应该为每个用户返回一行,如图 10-2 所示。

img/494886_1_En_10_Fig2_HTML.jpg

图 10-2

从/etc/passwd 中抓取根目录

Note

对于普通的文本文件,-b-c标志的作用是一样的,因为单个字符是一个字节长。

当然,在前面的例子中,结果不是特别有用;我们已经获得了几个用户名,但是由于不是所有用户的长度都一样,一些线路获得了额外的数据,而另一些线路被切断了。最常用的模式是-d作为分隔符。例如,让我们只获取用户名。我们提供了想要用作分隔符的字符,在我们的示例中,每个用户名前面都有一个“:”。然后,我们用-f标志指定要返回的剪切文本的部分:

cut -d : -f 1 /etc/passwd

这将返回所有用户的列表,如图 10-3 所示。

img/494886_1_En_10_Fig3_HTML.jpg

图 10-3

用 cut 获取每行的第一列

金圣柱

解析文本时另一个有用的命令是uniq,用于解析出重复的行。为了测试这个命令,让我们首先创建一个包含一些重复行的文件:

printf 'Hello %d\n' 1 1 1 2 2 3 > /tmp/hello.txt

文件/tmp/hello.txt现在应该包含六行,其中三行是唯一的。为了确认,首先cat文件的内容,然后做第二个cat传入uniq:

cat /tmp/hello.txt
uniq /tmp/hello.txt

您的内容应该类似于图 10-4 中所示的内容。

img/494886_1_En_10_Fig4_HTML.jpg

图 10-4

使用 uniq

值得注意的是,独特的功能只适用于彼此相邻的副本。例如,如果我们在文件的末尾添加另一个“Hello 1 ”,它仍然会被打印为唯一的一行。确保使用 >> 而不是 > 作为一个单独的重定向符号将覆盖文件而不是添加文件:

echo Hello 1 >> /tmp/hello.txt
uniq /tmp/hello.txt

注意第一行和最后一行是多么的相似,如图 10-5 所示。

img/494886_1_En_10_Fig5_HTML.jpg

图 10-5

当重复行不相邻时使用 uniq

如果我们只想打印完全唯一的行,我们必须首先用sort解析文件,我们将在下一节看到。

表 10-2 中显示了一些需要注意的可与sort一起使用的选项。

表 10-2

uniq 的选项

|

|

描述

| | --- | --- | | -c | 统计每行的出现次数 | | -d | 仅显示重复的行 | | [构成来自拉丁语、结尾为-us 的名词的复数] | 不分大小写 | | 构成名词复数 | 跳过每行的前 N 个字符(需要数字输入 | | -你 | 仅显示独特的线条 | | -w | 仅比较前 N 行(需要数字输入 |

分类

sort实用程序用于对文件中的行进行排序。为了进行演示,让我们创建一个编号为 1–5 的文件,后面再跟一遍相同的编号:

seq 1 5 > /tmp/numbers.txt && seq 1 5 >> /tmp/numbers.txt

接下来让我们查看输出,然后通过sort再次查看输出:

cat /tmp/numbers.txt
sort /tmp/numbers.txt

第一个命令的输出应该按照 1,2,3,4,5,1,2,3,4,5 的顺序,而第二个命令将数字排序为 1,1,2,2,…

这在与uniq结合使用时特别有用,因为您可以确保相似的行彼此相邻。假设您仍然有在uniq部分创建的/tmp/hello.txt文件,让我们对它进行排序,然后得到唯一的行:

sort /tmp/hello.txt | uniq

通过sortuniq的组合,你将只能得到每行的一个实例,如图 10-6 所示。

img/494886_1_En_10_Fig6_HTML.jpg

图 10-6

使用 sort with uniq 只显示每行的一个实例

使用-u选项,单独使用sort可以达到同样的效果:

sort -u /tmp/hello.txt

正如我们已经讨论过的其他实用程序一样,sort有一些有用的选项,如表 10-3 所示。

表 10-3

排序选项

|

|

描述

| | --- | --- | | -r | 反向排序(可与其他选项结合使用) | | 同-EN | 数字排序 | | -d | 字典排序,仅考虑空白和字母数字字符 | | k | 按列排序(需要数字输入 | | -你 | 仅显示独特的线条 | | -男 | 按月份排序(在行中采用月份名称) | | -五 | 版本号排序 |

正则表达式

Regex 本身不是一个实用程序,而是文本解析的标准形式,被许多实用程序和编程语言使用。Regex 是正则表达式的缩写。正则表达式提供了再次测试字符串的模式。举个简单的例子,假设我们想匹配“Hello”或“Hi”。对此的常规表达应该是

(Hello|Hi)

对于扩展的正则表达式,grep有一个特殊的-E选项。所以我们可以用grep来表达。在此之前,让我们在上一节创建的/tmp/hello.txt文件中添加一行“Hi 1 ”:

echo "Hi 1" >> /tmp/hello.txt

完成后,运行以下命令:

grep -E '(Hello|Hi)' /tmp/hello.txt

你应该在每一行都得到一个匹配,匹配的部分高亮显示,如图 10-7 所示。

img/494886_1_En_10_Fig7_HTML.jpg

图 10-7

带有 grep 的正则表达式

相同的 regex 格式可以用于多种实用程序和编程语言:Perl、JavaScript、Python 和 Ruby 等等。例如,如果您安装了perl,您可以使用完全相同的正则表达式:

perl -pe '(Hello|Hi)' /tmp/hello.txt

除了一个或另一个单词,我们实际上可以使用通配符或特定的类来再次匹配。假设您正在编写验证产品序列号的软件,它们以“数字数字字母数字字母数字”的模式出现这种模式可以表示为

[0-9][0-9][0-9][a-zA-Z][a-zA-Z][0-9]

注意,对于字母,我们使用[a-zA-Z];这表明我们接受大写和小写。如果我们只想要大写字母,我们可以做[A-Z]

现在,假设我们想让我们的序列号更难猜测,所以我们希望第一个数字是 3、5 或 8。我们将使用第一个字符的[358]来更新表达式:

[358][0-9][0-9][a-zA-Z][a-zA-Z][0-9]

同样的模式也适用于字母和数字,例如,[123ABC]将匹配列出的任何字符。另一个常见的类似用法可能是电话号码:

[0-9]{3}[-][0-9]{3}[-][0-9]{4}

前面的例子引入了一个我们还没有使用过的新元素。不用定义数字中的每个字符,我们可以用简写形式[0-9]{3},意思是三个[0-9]的实例。所以我们有一个三位数,后面跟着一个破折号,一个三位数后面跟着一个破折号,然后是一个四位数。

上述正则表达式的一个缺点是,它明确要求破折号。您可以在任何字符后加上?使其成为可选字符。因此,如果我们想使用相同的正则表达式,并使破折号可选,我们最终会得到

[0-9]{3}[-]?[0-9]{3}[-]?[0-9]{4}

注意添加了两个?。所以现在我们的正则表达式将匹配带或不带破折号的电话号码。如果您来自美国/加拿大以外的国家,您可能需要进一步调整 regex 以匹配您所在地区使用的模式。此外,这个正则表达式没有考虑在数字周围使用“()”的可能性。但是,使用这些简单的元素,您可以修改正则表达式来处理任何类型的电话号码格式。

为了测试电话号码示例,让我们打开在sort一节中创建的numbers.txt文件。然后添加一行包含“519-555-0100”格式的电话号码。完成后,运行以下命令:

grep -E '[0-9]{3}[-]?[0-9]{3}[-]?[0-9]{4}' /tmp/numbers.txt

这应该只返回添加了电话号码的换行符。

另一个常见的正则表达式用于查找电子邮件。这不是一个全面的例子,但它适用于大多数电话号码:

\S+@\S+\.\S+

在这个例子中,我们使用的是后面跟有+的任意非空格字符\S,这意味着前面的一个或多个字符。因此,合在一起\S+表示任意数量的非空格字符。然后我们有一个“@”符号,后面跟着另一个\S+;之后,我们有\.;通常.是一个通配符,但是有了反斜杠,它就有了“.”的字面意思。然后我们以另一个\S+结束。

就像电话号码一样,如果我们将电子邮件添加到我们创建的/tmp/numbers.txt文件中,我们可以将正则表达式作为命令的一部分进行测试:

grep -E '\S+@\S+\.\S+' /tmp/numbers.txt

表 10-4 包含了 regex 中常用符号的列表。

表 10-4

正则表达式符号

|

特殊字符

|

描述

| | --- | --- | | \s | 匹配任何空格或制表符 | | \S | 匹配任何非空格字符 | | \d | 匹配任何数字 | | \D | 匹配任何非数字字符 | | \w | 匹配任何单词字符 | | \W | 匹配任何非单词字符 | | 。 | 匹配任何字符 | | ^ | 行首 | | $ | 行结束 | | * | 匹配前面的字符零任意次 | | + | 匹配前面的字符一次或多次 | | ? | 零次或一次匹配前面的字符 | | | | 用于 Or 表达式的 or 符号 |

使用

awk是一种模式扫描和处理语言和命令行实用工具。它擅长处理格式化的文本数据。例如,使用以下文本创建文件/tmp/users.txt:

Jesse 4557389203 jesse@gmail.com xl 1991 1
Matt 8839293940 matt@hotmail.com s 1983 1
Jeff 8493739304 jeff@outlook.com l 1980 3
Sarah 4939304952 sarah@email.com m 1974 2

我们将使用这个文件作为样本数据进行处理。鉴于前面的数据,我们想看看所有的电子邮件。我们可以跑

awk '{ print $3 }' /tmp/users.txt

这将打印出$3指定的第三列的所有信息,如图 10-8 所示。

img/494886_1_En_10_Fig8_HTML.jpg

图 10-8

用 awk 打印文件中的第三列

我们可以混合和匹配这些值,并按照我们喜欢的方式设置它们的格式,例如,获取电子邮件和大小,并用空格将它们分开:

awk '{ print $3" "$4 }' /tmp/users.txt

或者说我们想使用每行数据的信息生成一个句子(图 10-9 中的输出示例):

img/494886_1_En_10_Fig9_HTML.jpg

图 10-9

在 awk 中使用列作为变量

awk '{ print "Hello "$1", thanks for buying a "$4" shirt" }'\
  /tmp/users.txt

我们还可以使用基本的搜索功能来查找特定的行,例如:

awk "/Jeff/" /tmp/users.txt

这将返回用户 Jeff 所在的行,如图 10-10 所示。

img/494886_1_En_10_Fig10_HTML.jpg

图 10-10

使用 awk 搜索字符串

我们之前看到的正则表达式也与awk兼容。比方说,我们希望获得所有大号为“l”的用户。我们将创建一些正则表达式来查找两边都有空格的“l”的情况:

awk "/\sl\s/" /tmp/users.txt

或者如果我们既想得到大的又想得到小的,我们可以使用(...|...)模式,就像我们对(Hello|Hi)做的那样。记住每个\s实际上是一个空格,并不是指字母本身。所以\ss\s实际上是“s”的意思:

awk "/(\sl\s|\ss\s)/" /tmp/users.txt

这将返回小和大的条目,如图 10-11 所示。

img/494886_1_En_10_Fig11_HTML.jpg

图 10-11

使用 awk 获得大小不同的用户

任何正则表达式都可以和awk一起使用;简单地把它放在我们已经看到的/ /之间。

这些是awk有用的几个例子。它并不全面,因为awk实际上是它自己的编程语言,并且已经有整本书都在讨论如何使用它。如果您感兴趣,其他功能包括

  • 创建由awk直接调用的.awk文件

  • 定义和使用变量的能力

  • 支持在 awk 脚本中编写独立的函数

  • 像随机数生成器这样的内置函数

  • 支持 if、else 和循环

一项 Linux 指令

代表流编辑器,它将出现在大多数 Linux 安装中。awksed能做的事情有很大的重叠。它们都可以用来搜索匹配的文本或对数据执行操作。例如,如果我们想像在awk中一样在/tmp/users.txt中搜索该行,我们可以这样做

sed -n "/Jeff/p" /tmp/users.txt

-n标志禁止sed自动打印文件,取而代之的是,我们将只打印我们指定的行。然后我们比赛图案末端的p代表印刷。

总的来说,我推荐学习awk而不是sed,因为它使用起来更简单,而且对于更多的情况来说是一个更完整的工具。然而,sed有一些事情比awk简单。其中之一就是查找和替换文本。

让我们以示例数据为例,将“Jeff”替换为“Jeffery”:

sed -i 's/Jeff/Jeffery/g' /tmp/users.txt

这里的-i支持就地编辑,所以我们正在读取的文件被改变了。然后s/告诉sed使用替代命令。然后我们匹配Jeff,在/的另一边,我们指定替换。最后,末尾的/g指定这是一个全局更改,而不是简单地替换第一个匹配。

但是,前面的命令有一个小问题。如果运行第二次,它会尝试将“Jeff”替换为“Jeffery”与awk一样,我们可以指定空格与\s的匹配,然后在替换部分使用一个文字空格:

sed -i 's/Jeff\s/Jeffery /g' /tmp/users.txt

您可能从 regex 表中认出了\s。与awk一样,regex 语法与sed兼容。

使用 JQ 与 JSON 一起工作

Linux 上使用的许多老程序都是在 JSON 成为 web 应用间信息共享的标准之前编写的。虽然像sedgrep这样的程序在解析和文本操作方面很强大,但它们并不太适合处理 JSON。处理 JSON 最流行的命令行程序是 JQ,以至于它已经开始成为许多发行版的标准,比如 Ubuntu。

JQ 是一个用 c 语言编写的速度非常快的 JSON 处理器。我问作者 JQ 是否代表 JSON Query,他说这很有意义,但他不打算让它代表任何东西。尽管如此,您可以将其视为一种查询和使用 JSON 的方式。

Note

在本节中,我们将使用 Open Trivia DB 作为获取 JSON 的示例 API。请随意用它来替换任何其他 API。当然,您必须针对您正在处理的数据修改命令。一些有趣的不需要获取 API 键的 API 包括

打开琐事 DB-www.opentb.com

TheSportsDB-www.thesportsdb.com

JQ可以做的最简单的事情是将有效的 JSON 通过管道输入其中,并接收一个有色结果,例如,用 Open Trivia DB:

curl -s https://opentdb.com/api.php?amount=3 | jq

这将返回相同的 JSON,但颜色编码便于阅读,如图 10-12 所示。

img/494886_1_En_10_Fig12_HTML.jpg

图 10-12

正在用 JQ 解析 Curl 请求

你会发现使用JQ更加容易,特别是如果你请求的服务器最初以压缩格式提供 JSON。还要注意,对于curl,我们使用了-s标志;如果没有这个,你会看到一个小小的进度条,不必要的浪费空间。

当然这只是开始;JQ 不仅仅是一幅简单漂亮的版画。让我们用同样的数据做一点工作。比方说,我们只想显示查询中的第一个问题(记住,每个请求的问题都是随机的)。

curl -s https://opentdb.com/api.php?amount=3 \
  | jq '[ .results][0][0]'

我们简单地添加[0]来获得数组中的第一个元素,类似于您可能熟悉的类似 C 的语言,如 JavaScript。在这种情况下,我们实际想要的结果被包装在一个只包含我们的目标数组的外部数组中,所以它最终被命名为[0][0]

如果您熟悉使用 JavaScript 或其他语言中的数组和对象,那么做更复杂的事情对您来说会非常容易。假设现在我们要回答第一个问题,并且只选择问题文本。

curl -s https://opentdb.com/api.php?amount=3 \
  | jq '[ .results][0][0]'.question

如果在您阅读本文时数据库格式保持不变,并且您已经正确地复制了命令,那么您应该会在屏幕上看到一个问题文本。让我们回想一下关于管道的部分,将结果发送到cowsay(默认情况下没有安装)只是为了好玩。

curl -s https://opentdb.com/api.php?amount=3 \
  | jq '[ .results][0][0]'.question \
  | cowsay

输出应该如图 10-13 所示。

img/494886_1_En_10_Fig13_HTML.jpg

图 10-13

利用 JQ 得到一个问题,然后把它传给考赛

我们可以扩展前面的示例,通过将 curl 请求的结果保存在脚本中并提取问题和答案以分别显示,来创建一个完整的基于命令行的问答游戏。有关命令行问答机器人的完整示例,该机器人打印潜在答案列表并检查用户是否给出了正确答案,请参见以下链接:

https://github.com/Apress/basic-linux-terminal-tips-and-tricks

摘要

在本章中,我们看了从命令行和脚本解析文本的工具。对于纯文本文件或管道输入,这些包括grepcutuniqsortawksed。我们看到,正则表达式对于匹配文本模式非常有用,并且受到几个实用程序和大多数流行编程语言的支持。最后,我们看到了如何使用 JSON,JSON 通常是通过使用程序 JQ 从 web APIs 返回的。

十一、systemd

我们已经探索了使用像ps这样的工具直接查看流程;查看系统上运行的进程的另一种方式是从守护进程的角度。守护程序是在系统后台运行的长期运行的进程;通常它们会在系统启动时由类似systemd的 init 程序自动启动。systemd中的“d”来自守护进程的概念,因为它充当系统上运行的所有守护进程的控制器。

是一个调度系统,已经在 Linux 发行版中广泛使用。它经常是赞扬和批评的主题。它在包括日志记录、调度、服务监控和系统初始化在内的许多领域中控制系统功能的核心作用导致一些人说它太集中了,违背了每个程序做好一件事的 Unix 哲学。systemd的捍卫者会指出,它实际上是几个二进制文件的集合,如systemctljournald,它们各自做一件事,共同创造一个更大的系统。

无论你对systemd有什么看法,它已经变得如此普遍,如果你使用任何流行的 Linux 发行版,这几乎是不可能避免的。它最初是在 2010 年由 Red Hat 开发的,作为替换旧的 init 系统,特别是 SysV 风格的 init 的一种方式。到 2015 年,systemd已经取代了 SysV init 和大多数流行发行版上的其他 init 系统,包括 CentOS、RHEL、Debian、Ubuntu 和 SUSE。

systemctl

如果你的系统运行的是systemd,你应该有一个命令行程序叫做systemctl,是系统控制的缩写。systemctl可用于监控、查询和修改systemd控制的服务和流程。参见图 11-1 查看由systemd监控的子任务的可视化。

img/494886_1_En_11_Fig1_HTML.jpg

图 11-1

系统的许多用途

systemctl是系统控制,连接系统的各个方面,跟踪每个服务状态,根据设置打开/关闭服务,解析服务输出并将其移动到日志文件。

不带任何标志运行systemctl将返回活动systemd单元列表,如图 11-2 所示。

img/494886_1_En_11_Fig2_HTML.jpg

图 11-2

运行 systemctl 的输出示例

停止、启动、禁用和启用服务

我们已经使用了一些我们将在这里介绍的命令,但是值得重申一下,因为它们是一些您想要使用 systemd 管理服务的最常见的命令。

停止服务

如果一个服务正在运行,你想通过systemd停止它,只需用sudo运行以下命令;我们将使用打印服务cups作为例子(成功时没有输出显示):

sudo systemctl stop cups

获取服务的状态

接下来,为了确保服务关闭,我们将使用status命令。当您不确定服务的状态时,这在许多情况下会很有用。

sudo systemctl status cups

你不仅可以得到服务的状态,还可以得到最新的日志;示例见图 11-3 。添加最近日志是旧的 System V service 命令中没有的功能。

img/494886_1_En_11_Fig3_HTML.jpg

图 11-3

使用 systemctl 获取特定程序的状态

请注意底部的日志,其中显示了启动和停止的时间和消息。

启动服务

接下来让我们重新打开服务;正如您可能已经猜到的那样,这可以通过以下命令来完成:

sudo systemctl start cups

运行start后,重新运行status命令,确认cups再次运行。

禁用服务

停止和开始处理当前会话中服务的状态。禁用和启用在机器启动后的新会话启动期间处理服务的状态。简单地在一个服务上使用stop将导致它在每次计算机停止时重新启动。要彻底关闭服务,应该使用 disable 命令:

sudo systemctl disable cups

运行后,再次检查status并观察差异。

启用服务

正如您可能猜到的,disable 的反义词是 enable:

sudo systemctl enable cups

测试禁用命令后,如果希望该服务在引导时继续启动,请确保将其重新启用。

单位文件

程序通过单元文件将它们的配置传递给systemd,单元文件是位于/etc/systemd/system/文件夹中的 ini 文件。最简单的单元文件只是告诉systemd保持程序运行。让我们创建一个示例程序和单元文件来演示;称之为logTime.sh。我在/tmp文件夹中创建了我的文件夹,因为我不打算保留它。

#!/usr/bin/env bash

while true
  do
    echo time is $(date)
    sleep 5
  done

编写完脚本后,使用以下命令授予它可执行权限:

chmod +x logTime.sh

进入文件夹/etc/systemd/system;这是你可以放置配置程序使用systemd的单元文件的地方。我们将为简单记录时间的脚本创建尽可能简单的单元文件;将文件命名为logTime.service。您需要拥有 root 权限才能在/etc/systemd/system中编辑和创建文件。

[Service]
ExecStart=/tmp/logTime.sh

保存单元文件后,您现在可以打开服务了。

sudo systemctl start logTime

接下来,我们将获得守护进程的状态。

sudo systemctl status logTime

这应该会返回一些信息,告诉我们服务是活动的,并显示最近的日志,如图 11-4 所示。

img/494886_1_En_11_Fig4_HTML.jpg

图 11-4

启动自定义单位文件并检查状态

您可以使用journalctl主动查看生成的日志。

sudo journalctl -u logTime -f

当您想要调查正在您的机器上运行的一些特定服务时,这可能是有用的。如果它看起来不正常或者占用了太多的资源,查看日志可能会给你一些提示。

在单元文件中还可以设置其他几个选项。下面是一个更完整的单元文件,带有描述每行内容的注释:

[Unit]
# Description of what the program does
Description=Log time every 5 seconds
# List services needed for this service to work
After=time-sync.target

[Service]
# Path to executable
ExecStart=/tmp/logTime.sh
# Policy for restarting when stops
Restart=always
# Working directory for executable
WorkingDirectory=/tmp
# The user the process will run under
User=philip
# User group for the process
Group=philip
# Set environment variables
Environment=MYVAR=var

[Install]
# Which programs require the unit
# multi-user.target is when linux start
# Adding this line makes the program start when system is booting
WantedBy=multi-user.target

如果您手动修改服务文件,您需要使用以下命令对systemd进行软复位:

sudo systemctl daemon-reload

即使最后一行告诉程序在引导期间打开,也需要启用它来实际考虑单元文件。

sudo systemctl enable logTime

这将激活服务。如果您想禁用该服务,只需运行

sudo systemctl disable logTime

disable 命令非常有用。比方说,您检查正在运行的服务,看到一个您没有使用也不需要的程序。你终止了进程或者关闭了它,却发现下一次重启计算机时,它又回来了。如果你遇到那种情况,systemctl disable或许可以解决。

在您完成这一部分后,确保删除我们在/etc/systemd/system中创建的服务文件。如果您像我们在这里一样在/tmp目录中创建了可执行文件,那么如果您没有通过删除服务文件来删除它,那么在您第一次重启之后,服务将会失败。

查找正在运行的服务

当您登录到一台机器时,您可能想要弄清楚哪些服务已经在运行。我们之前看到的命令systemctl,用于启用和禁用我们的logTime服务,也可以用来获得机器上运行的服务的完整列表。

systemctl是 system control 的缩写,是 systemd 的命令,用于控制系统上的服务。鉴于此,几乎所有的服务都将通过 systemd 启动(至少是重启后自动启动的)。

你可以用systemctl做的最简单的命令是独立运行它:

systemctl

这将返回系统中当前活动的进程列表,如图 11-5 所示。

img/494886_1_En_11_Fig5_HTML.jpg

图 11-5

systemctl 的输出

这列出了所有的东西,很难通读。如果您想查看正在运行的特定单元文件服务,您可以使用

systemctl list-units --type service

关于这个的另一个有用的事情是,你可以看到设置为正在运行但由于某种原因失败的服务,如图 11-6 中的postfix@-.service的情况。

img/494886_1_En_11_Fig6_HTML.jpg

图 11-6

仅使用 systemctl 列出服务

如果我们只想查看失败的服务,我们可以在前面的命令中添加--state failed标志。

此外,请注意活动但已退出的服务,这意味着从技术上讲,它们正在工作,但没有运行。要仅查看当前正在运行的程序,您可以使用以下命令:

systemctl list-units --type service --state failed

另一个有用的命令将允许您查看所有单元文件及其当前状态:

systemctl list-unit-files --type service

这将输出所有的单元文件及其当前状态,示例如图 11-7 所示。

img/494886_1_En_11_Fig7_HTML.jpg

图 11-7

用 systemctl 列出单元文件

有几种可能的状态,在表 11-1 中列出。最常用的是启用、禁用和静态。

表 11-1

systemd 的可能服务状态

|

状态

|

描述

| | --- | --- | | 使能够 | 服务已打开 | | 有缺陷的 | 服务已关闭 | | 静电 | 无法打开/关闭服务、依赖关系或单一运行脚本 | | 戴面具的 | 已锁定,因此即使手动也无法打开 | | 连接的 | 通过系统链接变得可用 | | 间接的 | 间接启用 | | 生成的 | 通过生成器工具动态生成 | | 短暂的 | 通过运行时 API 动态生成 | | 严重的 | 无效的单位文件 |

有关这些状态的更多详细信息,您可以运行

man systemctl list-unit-files

期刊

systemd 不仅仅处理调度任务。它还在指导运行服务生成的日志方面发挥作用。这就是journalctl的用武之地,是日志控制的简称。与systemctl一样,您可以运行的最简单的命令是journalctl本身。

journalctl

这将返回通过 systemd 创建的所有日志的列表。我们可以通过使用-f标志来观看这个文件更新时的实时版本:

journalctl -f

这将显示发生的任何日志;要退出,可以按ctrl+c

有许多选项,让你不必自己想出复杂的解析器;表 11-2 包含了几个有用选项的列表。

表 11-2

日志选项列表

|

[计]选项

|

描述

| | --- | --- | | -f | 获取实时日志流 | | k | 显示内核日志 | | -u | 显示特定服务的服务 | | -b | 显示启动消息 | | -r | 按相反顺序排序 | | -p | 按进程优先级排序 | | _PID= | 从特定进程 ID 获取日志 | | _UID= | 从特定用户 ID 获取日志 | | _GID= | 从特定组 ID 获取日志 |

journal CTL–按时间解析

除了前面的标志,还可以使用--since--until标志解析特定时间之间的日志,例如:

journalctl --since yesterday

直到使用基本小时表示法的时间

journalctl --until 13:00

或者使用两者的组合

journalctl --since "2 days ago" --until yesterday

还支持传统时间戳:

journalctl --since "2019-12-24 23:15:00" --until "2019-12-25"

其他初始化系统

虽然systemd已经被广泛使用,但仍有几个地方可以找到其他的 init 系统——仅举几个例子:

  • 最小的 Linux 版本,如 Alpine Linux

  • 旧版本的 Linux

  • 较少使用的操作系统

  • 高度定制的操作系统

系统 V 初始化

systemd成为标准之前,经典的 Linux 系统使用 SysV init。单词“init”指的是引导期间启动的第一个进程。跑步还是能看到的

ps -up 1

然而,脚本本身很可能是initsystemd版本。systemd被有意设计成与 SysV init 兼容。使用 SysV init,内核启动 init 进程,该进程处理系统状态的更改,以便引导、重启和关机。对于 SysV,在表 11-3 中定义了八种不同的运行级别。

表 11-3

SysV 上的运行级别

|

运行级别

|

目录

|

使用

| | --- | --- | --- | | 普通 | - | 系统引导 | | Zero | /etc/rc0.d/ | 暂停系统 | | one | /etc/rc1.d/ | 单用户模式 | | Two | /etc/rc2.d/ | 多用户模式 | | three | /etc/rc3.d/ | 联网的多用户 | | four | /etc/rc4.d/ | 为自定义运行级别保留 | | five | /etc/rc5.d/ | 图形用户界面启动( X11 ) | | six | /etc/rc6.d/ | 重新启动 |

当系统启动时,它在运行级别之间移动,并不总是按顺序移动,例如,进入单用户模式(运行级别 1)是一种特殊的状态。当您的操作系统在启动过程中被破坏时,例如,/etc中的一个脚本(如/etc/fstab)被破坏,您将只能以 root 用户身份登录到单用户模式。其他级别更有顺序性,例如,在到达级别 5 之前,通常要通过运行级别 2 和 3。

与每个级别相关联的文件夹包含与需要在该级别启动的程序相关联的 bash 脚本。

Note

虽然运行级别对于 SysV 风格的 init 至关重要,但是它们仍然以相同的级别 N、0 和 1 - 6 存在于 systemd init 中。在大多数系统上,您可以通过运行who -r来查看您当前的运行级别。

暴发户

另一个以前流行的 init 系统是 Upstart ( 上一次发布是在 2014 年)。Upstart 是在 Ubuntu 上使用的,直到他们从 Debian 8 开始改用systemd。尽管如此,你仍然会发现 Upstart 今天仍在使用。

Upstart 看起来像其他 init 系统,不包含名为“upstart”的命令。如果您不确定您的操作系统正在运行 Upstart,您可以使用

ps -eaf | grep '[u]pstart'

如果您看到一些进程而不是 grep 调用本身,那么您的系统已经安装了 Upstart。您可以使用它来检查哪些服务正在运行

service --status-all

这将返回服务及其状态的列表。您可以通过直接与服务的 init 脚本进行交互来与服务进行交互,例如:

sudo /etc/init.d/ssh status

或者要重新启动服务,请运行

sudo /etc/init.d/ssh restart

这种互动方式并不是 Upstart 特有的。甚至在systemd系统上,你会发现许多程序都有一个/etc/init.d文件,可以像前面显示的那样直接交互。

摘要

在这一章中,我们看了一下systemd系统,以及如何使用它来控制系统上运行的程序。我们看了如何通过停止、启动、启用和禁用来使用systemctl处理这些服务。为了查看正在运行的服务及其日志,我们探索了journald的使用。我们甚至创建了自己的单元文件来从头开始制作一个systemd服务。

十二、VIM

迟早,您会想要开始使用基于终端的文本编辑器,如果不是全职的,那么至少当您远程登录到服务器或设备时。

许多系统管理员最终依赖于nano,一个预装在许多系统上的简单文本编辑器。nano的主要优点是它容易被新用户理解和使用。从长远来看,使用nano会大大降低你的速度。有了 nano,当你试图浏览一个文本文档时,你不得不长时间按住箭头键或删除。

Vim 通过创建一种基于键盘的语法来解决这个问题,这种语法可以在文档中导航,并且不需要鼠标就可以快速修改。在一次击键中,你可以从一个文档的顶部到底部G,然后用两个gg再返回。Vim 有各种类似的基于击键的命令,可以帮助你快速移动和编辑。

模式

如前一章所述,许多键被绑定到特殊的动作或命令,例如,G转到文档的底部。那么,当你真的想在文档中输入“G”的时候呢?这就是模式出现的地方。Vim 中有两种主要模式,第三种使用较少但仍然重要的模式:

  • 正常模式–用于运行G等命令

  • 插入模式–像在其他编辑器中一样书写文本

  • 视觉模式–用于选择文本,类似于用鼠标突出显示文本

常见命令

当您在 Vim 中打开一个文档时,默认情况下您将处于正常模式。正常模式是运行 Vim 特定命令的模式。表 12-1 中列出了一些你可能想熟悉的最常见的。

表 12-1

Vim 命令

|

命令

|

描述

| | --- | --- | | :问 | 退出 Vim | | :w | 保存文档 | | :x | 保存并退出 | | 我 | 进入插入模式 | | :u | 取消 | | Ctrl+r | 重做 | | | 从插入模式返回正常模式 | | :e | 在 Vim 已经打开的情况下打开文件 | | :h | 帮助屏幕 |

注意如何退出 Vim 这是一个常见的问题,也是一个笑话,新加入这个项目的人很难退出这个项目。

Note

人们经常在退出 Vim 时遇到困难。在正常模式下,可以按:q。如果您更改了文件,您将在未保存的文件上方得到提示。你可以用:w保存一个文件,并将这两个动作合并为:wq。保存和退出也可以用一个稍微短一点的命令:x来完成。

使用帮助命令

如果您发现自己忘记了 Vim 基础知识,您可以通过运行:h打开帮助页面。这将把您带到一个常规帮助页面。如果您需要关于特定命令的信息,您可以在命令的:h后面跟随,例如:

:h G

这将调出G命令的具体帮助文本,如图 12-1 所示。

img/494886_1_En_12_Fig1_HTML.jpg

图 12-1

G 命令的帮助屏幕

复合命令

Vim 的一个伟大之处在于,它可以用一种非常简单的语言来组合命令。某些电源命令可以串在一起创建新的命令。做“删除内引号”这样的事情,三次击键就能完成;简单地按下

di" // delete in quotes

前面的命令表示三个较小的组件串在一起:

d = delete
i = in
" = quotes

现在你知道如何删除引号,你认为你如何删除括号内?

di) // delete in brackets

删除当前单词?删除段落中的?

diw // delete in word
dip // delete in paragraph

有几个类似的选择器可以用在同一个“在 X 中删除”序列中。你要做的就是把三个键序列中的最后一个键换出来。表 12-2 中显示了其中一些键和符号。

表 12-2

可与“删除于”复合命令一起使用的选择器

|

钥匙

|

描述

| | --- | --- | | " | 引用 | | (, {, , < | 各种支架类型 | | t | HTML 标签 | | p | 段落 | | w | 单词 |

Note

对于前面列出的任何方括号,如(、{、和[,您也可以使用该方括号的结束版本来获得相同的效果。

我们也可以把所有这些语句的第一个字母换出来,改变意思。一些复合命令示例如表 [12-3 所示。在极少数情况下,这个形容词可能根本不需要。例如'diw'可以进一步简化为'dw'。

表 12-3

复合命令的示例

|

动词

|

(数字)

|

形容词

|

名词

|

描述

| | --- | --- | --- | --- | --- | | c | - | 我 | t | 在 HTML 中创建标签 | | d | four | - | l | 删除四个字母 | | c | - | a | < | 删除-左右- | | d | Two | - | w | 删除两个词 |

使用视觉模式选择

Vim 还有第三种模式,它提供的功能类似于在其他程序中用鼠标高亮显示一段文本。例如,用 Vim 打开/etc/passwd(确保不要使用 sudo 或 root,因为我们不想保存对此文件的任何更改,最好将/etc/passwd复制到您的/tmp文件夹中,并练习编辑副本)。

文件打开后,按v;这将使您进入视觉模式。现在你处于可视模式,按键盘上的向下箭头或j;当你向下移动文本时,你的高亮显示会改变。参见图 12-2 中您应该看到的示例。

img/494886_1_En_12_Fig2_HTML.jpg

图 12-2

在可视模式下选择文本

现在文本高亮显示,我们可以对它执行操作。如果我们按下d,所有高亮显示的文本都将被删除。

请注意,我们在前面的图像中为单词“games”选择了悬挂的字符。避免这种情况的一个好方法是进入视觉行选择模式,这与视觉选择模式相同,但只突出显示整行。要使用视觉行选择,使用shift+v而不仅仅是v

虽然这可能看起来与您习惯在普通文本编辑器中使用鼠标的方式相似,但 Vim 视觉模式实际上要强大得多。我们可以选择垂直的代码块,而不是选择文本行。为此,首先确保您处于正常模式,按下esc。现在按下ctrl+v并使用j或向下箭头向下滚动。

向下滚动四行后,按几次l或右箭头键。请注意,我们正在做与上面视觉模式相同的事情,但是选择了一个垂直的代码块,它将被高亮显示,如图 12-3 所示。

img/494886_1_En_12_Fig3_HTML.jpg

图 12-3

在视觉模式下垂直选择

此时,我们可以对选中的代码执行一个操作,如d删除或按esc切换取消选择并返回正常模式。视觉模式的另一个常见用法是在所有的行前添加一些常见的文本。例如,假设我们想要注释掉前四行代码。回到左上角,按下ctrl+v。接下来向下滚动四行,按ctrl+I(必须是大写的 I);这将进入插入模式,但我们实际上将同时输入所有四行。

现在如果我们输入#,变化将在每一行重复,如图 12-4 。当您对插入的文本感到满意时,按esc完成操作。如果我们想取消对这些行的注释,我们可以使用选择一个垂直的代码块并按下d来删除我们刚刚添加的内容的技术。

img/494886_1_En_12_Fig4_HTML.jpg

图 12-4

一次在几行的开头添加一个散列符号

确保不要保存任何这些更改。要退出 Vim 而不保存,您可以在正常模式下按:q!

我是来当家教的

当你安装 Vim 时,它还附带了另一个名为vimtutor的可执行文件。当您运行它时,将会打开一个教程,引导您使用 Vim。Vim 导师的第一课如图 12-5 所示。

img/494886_1_En_12_Fig5_HTML.jpg

图 12-5

我是来当家教的

它包含了做简单事情的详细课程,比如移动光标、编辑、删除和创建文本。建议您通过 Vim tutor 学习,掌握在 Vim 中做普通事情的窍门。

查找文本

在导航文本时,另一件常见的事情是查找特定的文本字符串。这可以在正常模式下使用/键完成。首先按下/,然后键入您要搜索的字符串。您将在屏幕的左下角看到您的输入。输入搜索短语后,按 enter 键,光标将根据光标的起始位置转到下一个字符串实例。

将光标放在第一个实例上,可以按n转到下一个实例,或按N转到上一个实例。

搜索可能是导航文档的一种强大方式,通常后跟一个组合命令,如用于“创建单词”的cw

查找和替换

有时当你搜索时,你真正想做的是找到一个变量或单词的所有实例,并用另一个名称或单词替换它。一旦记住了命令,这在 Vim 中也相当容易。

:%s/old/new/g

这里的%s代表替身;然后是旧词,后面是我们要替换的词。在这种情况下,g代表 global,意味着我们希望用“new”替换所有“old”的实例。运行不带g的相同命令将只替换找到的第一个实例。

另一个可以与 substitute 一起使用的有用选项是i不区分大小写(与 regex 相同),例如:

:%s/old/new/gi

这将替换该单词的任何匹配项,而不管该单词的任何字母是大写还是小写。

运行命令

也可以从 Vim 中运行 Unix 命令。例如,让我们在/tmp文件夹中创建一个名为“vim”的文件:

:!touch /tmp/vim

按 enter 键后,您将进入一个 shell 实例,其中显示了命令的结果。然后再次按回车键,您将返回到 Vim。这对于在不离开 Vim 或不改变窗口的情况下快速命令是很方便的。

除了运行一次性命令,还可以在 Vim 中运行全窗口终端。您可以通过运行:terminal或简称:term在 Vim 中打开一个迷你终端。它将在窗口的上半部分打开一个新的终端会话,如图 12-6 所示。

img/494886_1_En_12_Fig6_HTML.jpg

图 12-6

在 Vim 中打开终端会话

终端窗口显示在顶部,您可以在应用内终端和您正在编辑的文本之间快速来回移动。要在两个窗口之间切换,按下ctrl+w,然后按下w

要关闭终端窗口,首先按下ctrl+w,然后按下:q!,再按下enter,与强制关闭正常窗口的方式相同。

Vim 排序命令

另一个方便的内置命令是 Vim 的 sort,它类似于我们在前一章中看到的命令行实用程序sort。为了演示排序,进入/tmp文件夹,用 1 到 99 之间的 10 个随机数创建一个文件:

for i in `seq 10`;
  do echo ${RANDOM:0:2};
done > /tmp/numbers.txt

现在,如果我们打开/tmp/numbers.txt,你应该有十个未排序的数字,每个都在不同的行上。接下来在 Vim 中运行以下内容:

:1,5!sort

按回车键后,前五行应该被排序。第一个数字是排序的起点,第二个数字是终点。因此,如果您用 10 而不是 5 再次运行相同的命令,文件中的所有数字都应该是有序的。

显示和隐藏行号

在上一节中,我们在 sort 命令中使用了行号,这很容易,因为我们从第 1 行开始,但是如果您在一个长文件的中间呢?如果您需要查看行号,您可以运行

:set number

然后要再次删除数字,运行

:set nonumber

交换文件

在使用 Vim 时,您可能会注意到扩展名为.swp的文件的创建。当您正确关闭 Vim 时,会自动创建和删除这些备份文件。如果由于某种原因,您的 SSH 连接中断或 Vim 意外关闭,您将有机会恢复您的更改。只要重新打开关联有.swp文件的文件,你就会看到如图 12-7 所示的屏幕。

img/494886_1_En_12_Fig7_HTML.jpg

图 12-7

当打开一个有交换文件的文件时

请注意页面底部显示的选项。要恢复更改,请按R。如果不想恢复更改,就要按D;否则,每次打开该文件时都会看到这条消息,直到.swp文件被删除。

摘要

在本章中,我们看了如何使用 Vim 文本编辑器来提高生产率。它允许您快速操作文本,而无需使用鼠标,因为鼠标会导致您丢失上下文。我们研究了 Vim 的三种主要模式——正常模式、插入模式和可视模式。我们还看到了 Vim 如何拥有自己的语言来创建复合命令,比如代表“在 word 中创建”的ciw虽然这一章只展示了 Vim 的一小部分功能,但是希望它可以作为一个起点,让您能够使用编辑器并提高编辑文件的速度。

十三、编辑器

在这一章中,我们将谈论一个在 Linux 世界中非常受欢迎的编辑器。Emacs 是历史最悠久、最受欢迎的编辑器之一。虽然 Vim 非常紧凑,只专注于编辑文件的任务,但 Emacs 更像是一个可以为其创建“模式”的平台。Emacs 中的不同模式以不同的方式解释命令和文本。

模式可以与正在编辑的文本文件的类型相关,例如,特定于编程 Python、JavaScript、C++等的模式。然而,模式也可以像程序一样,例如,org-agenda 提供了一个全功能的议程、待办事项列表,以及 calendar 或 EWW 提供了一个功能性的 web 浏览器,而无需离开 Emacs。甚至还有一些社区制作的模式与外部 API 绑定,例如,telega模式提供了一个嵌入 Emacs 的全功能电报聊天应用。

我们不会查看 Emacs 中的每个模式,甚至所有标准特性,因为这本身就需要一整本书。相反,我们将调查一些从终端有用的有趣内容,如果您希望更深入地研究 Emacs 世界,这些内容可以提供一个起点。

Note

当讨论 Emacs 时,我将使用它们的标准语法来描述命令。当你看到类似

M-x run-command

“M-x”代表按住修饰键的同时按“x ”,在大多数机器上是 ALT 键。

你会看到的第二个东西是 RET 这仅仅代表按下回车键。

安装 Emacs

在大多数包管理器上都可以找到 Emacs 的相对最新的版本。要在基于 Debian 的系统上安装 Emacs,运行

sudo apt-get install emacs

在撰写本文时,我们发现 ELPA (Emacs Lisp Package Archive)上验证包的程序附带的 GPG 密钥已经过期。您可以使用以下命令手动更新密钥:

gpg --homedir ~/.emacs.d/elpa/gnupg \
  --receive-keys 066DAFCB81E42C40

根据读取时间的不同,可能需要更改066DAFCB81E42C40上方的键。查看 GNU 网站链接, https://elpa.gnu.org/packages/gnu-elpa-keyring-update.html ,在那里你可以找到最新的密钥,以便与“完整描述”正文中的命令一起使用

为了告诉 Emacs 使用 MELPA 包存档,您必须在您的主文件夹中创建一个名为.emacs的文件。它应该包含以下代码:

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

Vim 绑定又名 Emacs 邪恶模式

我喜欢 Vim,因为你几乎可以在任何地方找到它,如果不是完整的,那么至少是限量版的vi。让 Vim 对我来说很棒的是,按键绑定允许我非常快速地修改和输入数据。然而,当谈到有趣的模式、模块和扩展时,我更喜欢 Emacs。

我们要看的有趣模块的例子包括艺术家模式、组织模式、演示和 tramp。在我们查看这些模块之前,我们将启用 Vim 键绑定,这样我们就可以在运行 Emacs 时使用我们所看到的 Vim 的最佳特性。值得注意的是,其他几个程序和 ide 提供了可选的 Vim 键绑定(在实现中有不同的质量水平),例如 VS Code 和 Qt Creator。一些终端程序如 Ranger 甚至默认使用它们,而另一些如bash允许你用一个选项来设置它们。

要在 Emacs 上启用 Vim 键绑定,我们首先需要安装模块“evil-mode”;这个名字一半是关于 Emacs 与 Vim 竞争的笑话,一半是基于 e (Emacs) + vi (Vim)的文字游戏。

在安装任何软件包之前,您应该更新本地软件包列表。这类似于在 Debian apt-get update上更新你的操作系统包管理器。要更新 Emacs 包管理器,请运行以下命令:

M-x package-refresh-contents

要安装 evil-mode,可以使用内置的包管理器 MELPA。运行以下命令:

M-x package-list-packages

这将显示 MELPA 上所有可用软件包的列表。接下来,我们将安装邪恶模式使用

M-x package-install RET evil

这将安装软件包,在屏幕的左下方,您应该看到“完成”安装了软件包后,您应该能够运行以下命令来为当前会话启用按键绑定:

M-x evil-mode

但是,在关闭 Emacs 并重新打开后,绑定将不再启用。为了确保在打开 Emacs 时默认启用绑定,我们将修改我们的~/.emacs文件。将以下两行添加到文件的底部:

(require 'evil)
(evil-mode 1)

Note

Emacs 中的一个主要概念是模式。改变模式可以改变输入键的反应方式。让 Emacs 使用 Vim 绑定的模式本身就是一种叫做evil-mode的模式。Emacs 中有两个子类别的调式:小调调式和大调调式。主要模式是排他的,而多个次要模式可以同时启用,并且每个模式都增加了一些功能。

在其他模式下使用 Vim 绑定的社区扩展已经存在,并且正在积极地维护/开发中。您可以在以下网址了解更多信息

www.github.com/emacs-evil/evil-collection

内置教程

像 Vim 一样,Emacs 有一个内置的教程,可以通过按

C-h t

这将打开一页文本,如图 13-1 所示。

img/494886_1_En_13_Fig1_HTML.jpg

图 13-1

GUI 模式下的 Emacs 内置教程

在切换到终端模式之前(我们将在下一节中进行操作),有必要研究一下默认的起始页,了解一下“打开主目录”等选项和链接的文档。从许多方面来说,Emacs 是为从 GUI 而不是在终端中使用而构建的。如果您喜欢 GUI 版本,并且它适合您的设置,请随意使用它。

在很大程度上,从终端而不是 GUI 使用 Emacs 并没有什么好处。它确实使从终端进入文件变得更容易,对于那些来自 Vim 的用户来说可能会感觉很舒服,但是许多 Emacs power 用户相信 GUI 版本,并且在单个实例中打开多个文件并在后台运行它。

在终端中运行 Emacs

默认情况下,Emacs 是一个桌面 GUI 程序。当然,如果你正在读这本书,你是为了终端特定的程序和工作流程而来的。您会很高兴听到 Emacs 也可以像 Vim 一样在终端中运行。为此,您需要使用--no-window-system选项打开程序,如下所示:

emacs --no-window-system

同样的事情也可以用捷径-nw来完成:

emacs -nw

当然,您可能不希望每次从终端启动 Emacs 时都这样写。你可以做的是给你的.bashrc文件添加一个别名,这样emacs就可以调用emacs --nw。在我的例子中,我决定使用e,因为敲五个键看起来工作量很大。.bashrc别名如下:

alias e='emacs -nw'

使用哪个按键模式的提示

如果你是 Emacs 新手,甚至是老用户,一个很好的安装模式是which-key-mode。此模式会弹出一个小缓冲区,显示您当前状态下可以使用的键盘快捷键。图 13-2 显示了哪个键对话的示例。

img/494886_1_En_13_Fig2_HTML.jpg

图 13-2

哪个键模式建议

从 MELPA 安装which-key-mode与安装evil-mode的过程相似。

M-x package-list-packages
M-x package-install RET which-key

一旦安装了which-key-mode,你需要修改你的~/.emacs文件,告诉which-mode在你输入命令时在迷你缓冲区显示建议。我们将使用use-package命令,所以我们首先需要导入它。在我们上一节写的以(package-initialize)结尾的代码块下,添加

  (package-install 'use-package))
(require 'use-package)

(unless (package-installed-p 'use-package)  (package-refresh-contents)

这将允许我们在命令中使用use-package。现在,在文件的底部,添加

(use-package which-key
  :ensure t
  :config
  (which-key-mode))

这确保了 Emacs 打开时which-key-mode开启。

完成后,关闭并重新打开 Emacs。现在如果你打字

C-x

你应该会看到一个小缓冲区,显示所有可以用来在C-x之后完成的键以及它们的作用,如图 13-3 所示的例子。

img/494886_1_En_13_Fig3_HTML.jpg

图 13-3

C-x 的哪个键模式建议

如果有太多的可能性需要列出,迷你缓冲区将被分成几个部分。要在它们之间切换,请按

C-h

这将允许使用n前进或p后退一节。

which-key有一些其他可以运行的内置命令。例如,如果您需要当前主要模式下可用命令的概述,请运行

M-x which-key-show-top-level

例如,如果你在evil-mode中,你会看到evil-mode的可用选项。

当您不熟悉 Emacs 时,能够看到所有可能的命令特别有用,因此强烈推荐这种模式。

Emacs 艺术家模式

虽然我更喜欢使用 Vim 进行文本编辑,但我欣赏 Vim 的竞争对手文本编辑器 Emacs 的独特性和有趣的模式。其中一些模式是内置的,而另一些必须使用内置的软件包管理器 MELPA 来安装。

这些有趣的模式之一是 Emacs 艺术家模式。艺术家模式提供了一套用于创建基于文本的艺术或图表的工具。图 13-4 显示了我在演示文稿和自述文件中包含的服务器架构图。

img/494886_1_En_13_Fig4_HTML.jpg

图 13-4

以艺术家模式制作的图表示例

这类图表的真正优势在于能够在终端上制作和查看它们。当通过 SSH 登录服务器并看到自述文件时,无法显示正常图像。然而,用 Emacs artist-mode 创建的图可以很容易地更改。

这类图像在非图形读物或手册中特别有用。例如,我在一个关于向物联网设备提供更新的系统的演示中使用了这种艺术,结合了 Emacs 演示模式,这是我们接下来要看的另一个模块。

Note

我们将在这里向您展示如何通过 Emacs 的终端版本使用艺术家模式,但这是一种在 GUI 版本中更容易使用的模式。这是因为在 GUI 中,你可以使用鼠标和拖放形状来绘制文本,而在终端中,你需要使用键盘来完成所有的事情。如果您的设置允许,您可能希望在 GUI 模式下启动 Emacs,并尝试用鼠标在艺术家模式下绘制文本。

用 Emacs 创建一个空白文件,然后切换到艺术家模式。在切换到艺术家模式之前,您需要创建一个空白空间(文字空格字符)的“画布”,在这里您将绘制您的图像。使用 Vim 绑定实现这一点的一个简单方法是按下i进入插入模式,并按住空格键,直到光标向右移动到您想要的画布宽度。然后按esc退出插入模式。按两次y复制空行;接下来按住p直到你的光标到达你想要的画布深度。你的光标应该停留在右下角,如图 13-5 所示。

img/494886_1_En_13_Fig5_HTML.jpg

图 13-5

在 Emacs 中创建一个空白画布,用于艺术家模式

从光标到左上方的空间现在都是空白,我们将在使用艺术家模式时操作。

接下来使用以下命令切换到艺术家模式:

M-x artist-mode

如果您启用了 Vim 绑定,您还会想要关闭它们,因为它们与artist-mode不兼容。您可以通过运行相同的命令来打开它们:

M-x evil-mode

一旦进入艺术家模式,我们有大量的形状工具可供选择。在终端模式下使用 Emacs 时,首先按下ctrl+c,然后按下ctrl+a,可以在所有形状之间进行切换,之后你可以在对应于特定形状的字母(不区分大小写,我复制了 Emacs GUI 中出现的快捷键)。

C-c C-a L         ## Line
C-c C-a r         ## Rectangle
C-c C-a s         ## Square
C-c C-a P         ## Poly-line
C-c C-a C         ## Ellipse
C-c C-a T         ## Text
C-c C-a z         ## Spray-can
C-c C-a E         ## Erase
C-c C-a V         ## Vaporize

在我们的例子中,我们将选择矩形;一旦你用C-c C-a r选择了矩形,移动你的光标到你想要开始绘图的地方。然后按下enter并四处移动光标;你会看到当你移动它的时候,矩形会改变形状。当对大小和形状满意时,按 enter 键完成。

尝试制作如图 13-6 所示的两个矩形。

img/494886_1_En_13_Fig6_HTML.jpg

图 13-6

在艺术家模式下创建的两个矩形

接下来使用切换到线条工具

C-c C-a l

将光标移动到顶部矩形的底部中间,然后按 enter 键开始您的行。将其向下移动到第二个矩形的顶部,使它们如图 13-7 所示连接起来。

img/494886_1_En_13_Fig7_HTML.jpg

图 13-7

用线条连接两个矩形的艺术家模式

为了让它看起来更像一个从顶部矩形到底部矩形的箭头,我们将把+替换为v。要做到这一点,只需在光标位于上图所示位置时按下v。你应该得到类似图 13-8 的东西。

img/494886_1_En_13_Fig8_HTML.jpg

图 13-8

在艺术家模式下,用 v 替换+使线条变成箭头

当不在艺术家模式下使用特定形状时,按下一个键就可以用您所按下的内容替换光标当前所在位置的文本。我们可以用同样的效果给矩形添加一些标签。将光标移动到您想要添加标签的位置,然后简单地输入。您可以添加标签文本,如图 13-9 所示。

img/494886_1_En_13_Fig9_HTML.jpg

图 13-9

在艺术家模式下向图表添加标签

如果您不小心写错了,您可以简单地将光标放在单词的开头,然后按空格键用空格覆盖文本。同样的道理也适用于当你书写时不小心弄乱了你的形状;只需用这种方法手动添加形状的缺失文本。

有了这两个简单的形状和技术,你可以创建相对复杂的建筑图形,就像本节顶部显示的木偶流行机一样。然而,如果你探索其他工具并且有时间,你可以创造无限的文字艺术。我会给你一些灵感,一个我在同一个演示中发现并使用的 pop 机器文本艺术图形,如图 13-10 所示。你可以在像www.asciiworld.comwww.asciiart.eu这样的网站上找到这样的文字艺术。

img/494886_1_En_13_Fig10_HTML.jpg

图 13-10

Pop 机器文字艺术

组织模式

另一种在原始文本中有效记录笔记甚至进行演示的有用模式是 Emacs org-mode。Emacs org-mode 是 organization mode 的缩写,提供了在分层标题下编写文本的能力,能够方便地扩展和压缩章节,例如,给定如图 13-11 所示的格式(标题由*指定)。

img/494886_1_En_13_Fig11_HTML.jpg

图 13-11

具有扩展部分的组织模式

要折叠一个部分,只需将光标放在要折叠的标题上,然后按下tab。级别由标题前面的星的数量来定义,如图 13-12 所示。

img/494886_1_En_13_Fig12_HTML.jpg

图 13-12

具有精简子部分的组织模式

折叠更高的标题将隐藏其所有子标题,如图 13-13 所示。

img/494886_1_En_13_Fig13_HTML.jpg

图 13-13

组织模式折叠部分

artist-mode一样,它不能很好地处理 Vim 绑定。如果你想同时使用 Vim 绑定和org-mode,有一些软件包试图给org-mode添加补丁,使其与 Vim 绑定一起工作,但我发现这不值得努力。套餐包括evil-orgorg-evilsyndicate。我的建议是不要同时使用这两种模式。如果您在启动时启用了evil-mode,您必须在运行org-mode之前通过运行evil-mode手动关闭它。

使用org-mode不需要安装任何额外的包,因为它是 Emacs 的标准配置。

组织模式下的表格

Org-mode 还有一个用于制作和使用表格的内置模式。组织模式下的表格由|字符指定。要生成表格,首先按

C-c |

这将在页脚打开一个对话框,询问您想要多大的表格,如图 13-14 所示。

img/494886_1_En_13_Fig14_HTML.jpg

图 13-14

屏幕底部的对话框询问新表格的尺寸

对于我们的例子,我们将使用 2x3。输入尺寸后,将生成如图 13-15 所示的空表。

img/494886_1_En_13_Fig15_HTML.jpg

图 13-15

在组织模式下创建的空 2x3 表格

接下来用一些示例数据填写表单。这样做后,工作台很可能会像图 13-16 所示那样错位。

img/494886_1_En_13_Fig16_HTML.jpg

图 13-16

组织模式下的无格式表

要重新格式化表格,请确保将光标放在表格的某个位置,然后按 ctrl+c 两次。

C-c
C-c

第二次按下后,org-mode 将重新排列表格,产生如图 13-17 所示的布局良好的表格。

img/494886_1_En_13_Fig17_HTML.jpg

图 13-17

组织模式中的格式化表格

您现在应该有了一个格式良好的基于文本的表格。

您可以找到处理表格的其他功能,例如将 CSV 格式转换为表格,以及在表格的组织手册页中重新排列行: https://orgmode.org/worg/org-tutorials/tables.html

从组织模式导出

使用org-mode可以做的一件方便的事情是使用一个简单的命令导出到其他几种文件格式。可能的格式包括

  • 便携文档格式

  • 超文本标记语言

  • 乳液

  • OpenDocument Text (ODT)文件

  • 纯文本

  • 伊卡伦达尔

要开始,请按

C-c C-e

这将打开一个显示可能导出选项的导出菜单,如图 13-18 所示。

img/494886_1_En_13_Fig18_HTML.jpg

图 13-18

组织模式下的导出类型选择

例如,如果我们想导出为 PDF,按下l按钮,该部分将会高亮显示。参见图 13-19 的 PDF 小节示例。

img/494886_1_En_13_Fig19_HTML.jpg

图 13-19

LaTeX 子部分在组织模式导出菜单中突出显示

我们现在可以按p导出为 PDF。完成后,将在与您的 org 文件相同的目录中创建一个 PDF。

组织-议程

处理 org 文件时,可以使用特殊的TODO指示器将文本标记为议程项目。你也可以告诉 org-agenda 跟踪某些文件,作为全球可访问的议程的一部分,包括像每日计划和日历这样的东西。

为了演示,创建一个名为/cal.org的文件。然后,为不同优先级的任务创建分区(高优先级、低优先级,如图 13-20 )。创建文件后,按

C-c [

这将把文件添加到 Emacs 的文件列表中,以供 org-agenda 查询。您可以通过运行以下命令来删除文件

C-c ]

添加文件后,任何 TODO 实例都将包含在 org-agenda 中。TODO 前面必须有一个*,如图 13-20 所示。

img/494886_1_En_13_Fig20_HTML.jpg

图 13-20

组织模式下的待办事项列表

现在,如果我们按 alt+x,输入 org-agenda,然后按 enter:

M-x org-agenda RET

我们将得到 org-agenda 的选项列表,如图 13-21 所示。

img/494886_1_En_13_Fig21_HTML.jpg

图 13-21

组织-议程菜单

t可以看到所有待办事项列表,如图 13-22 所示。

img/494886_1_En_13_Fig22_HTML.jpg

图 13-22

组织议程中列出的所有待办事项

在该议程选项卡中,我们现在可以按n进入下一行,按p进入上一行。下到您的列表项目之一,然后按下t。这将在您的议程和最初编写的文件中标记该任务为已完成。请记住,议程可以跟踪任意多的不同文件。因此,如果你想用不同的文件列出不同类型的任务,你可以这样做,然后把它们都拉进你的日程表(编译后的待办事项列表示例如图 13-23 所示)。

img/494886_1_En_13_Fig23_HTML.jpg

图 13-23

在组织议程中将待办事项标记为已完成

要退出议程,请按q

Org-agenda 也支持任务期限。要为待办事项添加截止时间,请将光标放在待办事项上,然后按

C-c C-s

这将打开一个可以输入日期的提示,如图 13-24 所示。

img/494886_1_En_13_Fig24_HTML.jpg

图 13-24

在组织模式下向待办事项添加日期

在输入日期/时间并按下回车键后,您将在任务下放置一个关联的日期,如图 13-25 所示。

img/494886_1_En_13_Fig25_HTML.jpg

图 13-25

组织模式下计划日期的待办事项示例

现在,如果您通过输入以下内容返回到组织议程选项

M-x org-agenda RET

然后按a进入日程周视图,你会看到你一周的任务按天显示,如图 13-26 所示的例子。

img/494886_1_En_13_Fig26_HTML.jpg

图 13-26

组织日程模式下的每周日程视图

一个预定的项目将保留在你的议程上,直到完成。Org-agenda 还提供了创建一个显示在日历上的条目的能力,但不管它是否被标记为完成,都将通过;要使用此替代时间戳,请在项目上按下C-c .而不是C-c s。还有一个高优先级的时间戳截止时间,可以在待办事项上按下C-c d来使用。

将组织日程与 Google 日历同步

Org-agenda 是一个很好的工具,但是它没有提供像手机甚至其他电脑这样的设备之间的无缝集成。MELPA 上有一个名为org-calendar的社区包,使 org-agenda 和 Google Calendar 之间的拉、推和双向同步变得容易。

从 MELPA 安装后,您必须在 Google 开发者控制台上设置一个项目,以使用他们的日历 API。你可以在他们的 GitHub 页面上找到关于设置org-calendar的最新说明。请记住,上次提交是在 2017 年 4 月,因此更新和支持可能有限。

www.github.com/myuhe/org-gcal.el

大纲演示模式

另一个可以与 Emacs 艺术家模式结合使用的好模式是 Emacs 演示模式。大纲演示模式允许您采用组织模式大纲,并将其转换为演示文稿,其中每个部分都充当幻灯片。不幸的是,这种模式没有在 MELPA 包管理器中发布。为了安装大纲演示模式,您需要手动下载脚本,然后将其添加到您的~/.emacs中。我发现很难在网上找到原始代码,所以我把脚本上传到了 GitHub。您应该使用 GitHub 下载它:

cd /tmp
git clone https://github.com/kirkins/outline-presentation-mode

然后进入下载的文件夹,将脚本移动到你的~/.emacs.d/extra/文件夹中(如果文件夹不存在就创建文件夹)。

cd /outline-presentation-mode
mv outline-presentation-mode.el ~/.emacs.d/extra/

现在,Emacs 脚本保存在您的~/.emacs.d/extra/文件夹中,您必须修改您的~/.emacs文件,以便在 Emacs 启动时加载脚本。在文件底部,添加以下内容:

(load-file (expand-file-name "~/.emacs.d/extra/outline-presentation-mode.el"))

现在,当您打开 Emacs 时,您将能够以大纲演示模式打开文件。您可能没有组织大纲文件演示文稿来测试;我在一个仓库里做了一个,你可以下载

git clone https://github.com/kirkins/puppet-pop-machine
cd puppet-pop-machine

接下来,在 Emacs 中打开名为presentation.org的文件。文件打开后,切换到presentation-outline-mode:

M-x presentation-outline-mode

这将打开演示文件并显示演示的轮廓,如图 13-27 所示。

img/494886_1_En_13_Fig27_HTML.jpg

图 13-27

Emacs 中的演示大纲模式

现在,您可以按住alt键并点击n进入下一张幻灯片;要返回,点击p。可使用的命令列表如表 13-1 所示( M 表示修改键,默认为 alt)。

表 13-1

Emacs 大纲模式命令

|

命令

|

描述

| | --- | --- | | 男男 | 下一张幻灯片 | | M-p | 上一张幻灯片 | | 男-女 | 下一部分的第一张幻灯片 | | 前一个单词 | 返回上一节幻灯片 | | 并购 | 第一张幻灯片 | | 环粘贴 | 扩展目录 | | M-s | 在目录中显示幻灯片光标 | | M-r | 返回到您进入目录的幻灯片 | | M-q | 退出演示模式并返回到组织模式 |

图 13-28 显示了一个纯文本幻灯片的示例。

img/494886_1_En_13_Fig28_HTML.jpg

图 13-28

嵌入在大纲演示幻灯片中的艺术家模式制作的图表

Emacs 蹦床

Emacs TRAMP 代表 Emacs 透明远程访问,多协议。它允许您通过在后台使用 rlogin、telnet 或 ssh 来访问远程文件系统,就像它们是本地系统的一部分一样。

Emacs TRAMP 默认包含在 Emacs 22.1 版本中,因此您不必做任何额外的工作来安装它。

要使用 ssh TRAMP,您首先要按

C-x C-f

这将在屏幕底部打开一个提示,让您导航您的系统以找到一个文件。它应该如图 13-29 所示。

img/494886_1_En_13_Fig29_HTML.jpg

图 13-29

按下 C-x C-f 后,在屏幕底部找到一个文件对话框

按 backspace 键删除文件路径,代之以/ssh:<your server>,如图 13-30 所示。为了使事情变得简单,我将使用一个在我的 SSH 配置文件中定义的简称“aws ”,这个文件已经有了我的用户名和密钥文件设置。

img/494886_1_En_13_Fig30_HTML.jpg

图 13-30

在查找文件对话框中输入/ssh:remotehostname 来激活 Emacs TRAMP

此时,按 tab 键,系统将开始在后台连接远程机器,出现如图 13-31 所示的信息。

img/494886_1_En_13_Fig31_HTML.jpg

图 13-31

显示 Emacs TRAMP 连接到远程服务器的对话框

一旦连接上,你就可以按 tab 键并获得所有远程文件的列表,就好像它是你本地机器上的一个文件夹一样。图 13-32 显示了一个例子。

img/494886_1_En_13_Fig32_HTML.jpg

图 13-32

通过 Emacs TRAMP 自动完成显示远程服务器上的文件

方便的是,您可以编辑远程机器上的文件,然后切换到本地机器上的文件,然后返回到远程机器上的文件,连接将保持打开。

您甚至可以同时与几台远程机器连接,并在文件之间无缝切换,同时保持本地 Emacs 编辑器设置——而不是通过 SSH 连接到那些机器,并使用每台本地机器上的编辑器的配置文件。由于这个原因,Emacs TRAMP 对于那些必须定期在几台机器上切换编辑文件的人来说特别有用。

其他模式

这里我们只看了几种 Emacs 模式,但还有很多。如果你感兴趣,这里有一个小清单可以让你开始。请记住,我这里关注的是类似应用的模式,但是几乎每种编程语言和配置文件类型都有模式。其他流行模式列表见表 13-2 。

表 13-2

Emacs 模式

|

名字

|

描述

| | --- | --- | | 壳 | Emacs 中的命令行 shell | | 干燥的 | 导航目录的模式 | | 呀 | Emacs 中的网络浏览器 | | 魔法吗 | 高级 git 接口,用于合并等操作 | | 常春藤 | 用于自动完成的交互式界面 | | 牛羚 | 阅读电子邮件、RSS、新闻组群组等等 | | 彩虹模式 | 为十六进制颜色代码设置背景 | | 公司 | 文本完成 | | 埃迪夫 | 用于比较文件和补丁的工具 | | 飞溅模式 | 拼写检查用红色突出显示错误的单词 |

如果你已经安装了模式,你可以简单地按 alt+x 并输入名称。如果您想获得已安装模式的完整列表,请按

C-h a

然后进入“模式”;这将列出所有安装的模式,并附有非常简短的描述。

摘要

在这一章中,我们介绍了 Emacs 文本编辑器及其通过模式和嵌入式应用提供的许多功能,从创建艺术风格的图表和文本表格到管理任务列表和个人日历。正如我们所看到的,Emacs 不仅仅是一个文本编辑器,更像是一个可以构建基于文本的应用的平台。