一些杂项
当你看到这一章的时候,那么恭喜你,你已经到了初级篇的最后一章了。在这一章,我们会介绍一些不太能融入前面的体系中,但是却不能被忽视的一些重要命令。同时,这些命令可能跨度比较大,所以大家可能会感觉这一章的内容比较跳跃。
查看命令的历史记录——history
首先,我们来了解一个查询shell的命令历史记录的命令history。这个命令的基础用法十分简单直接,就是不加任何参数,就可以直接输出一个历史记录的列表,这个列表按照时间顺序从前到后列举了当前这个shell中执行过的命令(也就是最后一个命令是你最近执行的命令),并且每个命令前面都有一个序号。当然,这个列表的长度是有限的。
执行历史命令
如果history功能只是这些,那么这个命令的作用就太平凡了,这个命令还附带一个很有趣的功能,就是它允许你直接地快速执行某个历史命令。还记得刚才输出的历史命令的列表带有序号吗?你可以使用!加这个序号来执行之前的历史命令。例如,你的历史记录列表中序号114的命令是ls,那么你使用!114可以再次运行这个命令。注意,执行这个命令的环境不会被还原,也就是你之前ls之后你进入了其他目录,那么你执行!114的时候是仍然是打印现在的目录中的内容而不是之前那个目录。
另外,你还可以使用!-n执行最近的倒数第n个命令,例如!-2就会执行你前前一个执行的命令。同时,还有一个缩写形式可以使用就是!!表示执行上一个命令,等价于!-1。
!开头的这种形式还有一些其他用法,你可以通过man history来查看。同时,它也是一类被称为展开(substitution)的shell特性的一个特例,这个特性是shell中很关键但不那么好理解的部分,我们将会在中级篇的最后一章中详细讲解。(不过本章下面很快我们就会先介绍一个它的简单用法)
另外,大家需要注意,我们使用man history时打开的是第3个分区的文档。也就是说,它并不是history命令的文档,history命令只提供了一个history --help来说明它的用法。
打印命令执行的时间戳
history的另一个我认为可能会比较有用的功能就是打印命令执行的时间戳,也就是显示历史命令的时候同时显示它们的执行时间。并且这个功能并不是像其他大多数命令一样通过命令的参数来使用的。它的使用方式是通过环境变量。
简单理解,环境变量就是一系列变量,它们的值通常用来表示我们的系统的状态,例如系统的时区,语言,当前工作目录等。这些变量是我们的系统上运行的程序用来感知自己的运行的环境(也就是系统的状态)的重要手段。这个概念非常重要,所以我们会在中级篇详细介绍。对于这里,我们只需要知道两点。第一,一个名叫HISTTIMEFORMAT的环境变量用来控制history打印时间的行为。实际上应该说是你的bash会通过读取这个变量的值来决定当你执行一个命令的时候是否记录时间戳,history则会根据这个环境变量的值来决定以什么形式记录时间戳。第二,我们可以通过下面的命令来修改环境变量的值。
HISTTIMEFORMAT="%Y-%m-%dT%H:%M:%S%Z "
注意
这个命令中,=两侧都不能有空格,并且你最好把后面的字符串用"包裹来避免歧义。
对于这个变量的内容的规定规则如下。首先,HISTTIMEFORMAT变量值为空(也就是空字符串,用""来表示,这是这个变量的默认值)表示history不显示时间戳。其他情况下,你可以用和第12章中date命令的格式化话字符串的格式来格式化时间戳的形式。特别的,当你第一次将HISTTIMEFORMAT的值设置为非空的时候,你的bash就会开始记录你执行的每条命令的时间,在这之前的时间戳都是错误的。在次之后,即使你设置HISTTIMEFORMAT的值为空,bash也仍然会记录时间,当你再次将HISTTIMEFORMAT的值设置为非空的时候,显示的时间戳也是正确的。
history还有不少其他参数可用,它们的功能包括但不限于将历史记录输出到文件,修改历史记录,限制输出的列表长度。你可以在你需要的时候,查阅相关的文档。
命令的别名——alias
有的时候我可能会觉得某个经常需要执行的命令太长了,每次输入一遍都太麻烦,那么我们有没有什么方式给这样的命令一个简称呢?当然有,这就是我现在要介绍的alias命令。这个命令的用法十分简单直接,下面是一个例子
alias ll="ls -l"
ls -l命令了一个别称ll,也就是运行完这个命令之后你再运行ll就会打印当前目录的详细内容了。任何命令都可以用类似的方式添加别称。但是这个别称只适用于当前会话,当你关闭了终端再重新打开的时候,这个别称就无法使用了。
如果你希望设置一些可以永久使用的别称,你可以将它们放到你的shell的配置文件中。关于shell的配置文件的细节我们也会在中级篇讲到,这里我只做一个简单的介绍。一般来说,bash的配置文件会有多个:整个系统会有一个所有用户共享的配置文件,一般这个配置文件只有root用户有权限编辑;其次就是每个用户会有一个自己的配置文件,这个文件一般在主目录下的.bashrc文件中,也就是~/.bashrc路径下。这个配置文件本质上是一个bash的脚本,每次在你启动你的bash的时候会执行一次。所以,如果你把你需要的alias命令放到配置文件,它就会在你每次启动bash的时候执行然后生效了。你可以选择用有图形界面的vscode使用ssh插件连接到你的linux机器来编辑,也可以使用命令行界面的编辑器(如果你不会用也不用急,我们会在中级篇讲到这个)。
最后,关于alias,还有一个用法需要介绍,就是使用-p选项可以列出现在你当前的shell会话中有哪些别名可以使用。
多用户和权限
Linux是一个支持多用户的系统。对于这样的多用户系统,一个重要的功能就是当不同的用户共享系统的一些资源的时候,可以正确管理不同用户的权限。当然,Linux的权限系统比较复杂,我们并不会讲太多,大家使用的时候也不需要深入掌握。
首先,每个Linux系统都一定有一个root用户,这个用户拥有系统的最高权限,可以做所有的操作;其次,系统中通常会有若干普通用户,默认情况下,这些普通用户都是sudoer,也就是说可以使用下面提到的sudo命令;最后,root用户,通常是管理员,可以设置一些用户没有sudo的权限。
以其他用户的身份执行命令——sudo
那么,我们就先来介绍一下sudo命令。这个命令的基础用法就是可以以其他用户的身份执行单个命令。如果你不指定用户的名称直接接命令就会默认以root用户的身份来执行这个命令。这个过程需要输入你当前用户的密码。例如;
sudo ls ~
ls /sys这个命令。
如果你加上了-u/--user选项,就可以在后面指定以某个其他用户的身份执行命令,例如
sudo --user test-user ls /sys
sudo还有一个很常见的用法,有的时候我们会忘记了我们的当前用户没有某个命令的权限,然后在没有加sudo的情况下直接执行了命令,这样就会导致命令的执行失败。这时,我们可以结合本章第一节所讲的内容,使用下面这个命令
sudo !!
切换到其他用户——su
Linux的多用户有关的命令中,还有一个比较常用的命令就是使用su切换到其他用户。这个命令的用法更加简单,使用su而不加任何参数就会切换到root用户,在后面加上用户名就会切换到那个用户。切换到其他的用户的时候需要输入那个用户的密码。不过,从root用户切换到其他用户不需要密码。
在你安装Linux系统的时候,系统会默认创建一个root用户,并且通常会要求你创建一个自己的用户,并设置用户名密码等,因此你登录系统的时候默认会使用你自己的用户。这个时候你需要先设置root用户的密码,才能这正常使用root用户的权限(当然如果这台电脑不是你的,并且你不是管理员的话,请直接联系管理员)。你可以直接使用passwd来设置或者修改密码。你可以直接使用
sudo passwd root
root改成其他的用户名来设置或修改其他用户的密码。
查看系统的资源的动态使用情况
对于大部分计算机系统,查看系统资源的动态使用情况都是一个很重要的功能,这个功能允许我们在命令行中直接监视系统的实时状态。Linux系统当然也提供了这种功能。下面我就来介绍两个常用的,查看系统资源使用情况的命令。
top
top命令是通常系统自带的命令。直接使用top就可以进入一个动态的界面,在这个界面的最上方可以查看系统的整体状态,例如总共有多少进程在运行,内存和CPU的占用情况等。下面则是一个进程列表,可以用来查看每个进程的资源占用情况。这里的CPU占比是按核来算的,所以当某个进程占用超过一个核的时候就会超过100
%。这个列表中还有一些其他详细信息的含义大家可以自己上网查询或者查阅文档。如果你的系统中进程数量比较多,可以通过键盘的上下键来翻页。
top还提供了一些对进程列表的排序和过滤的方式,使用命令行参数进行,用法比较麻烦,这里就不详细介绍了,如果有需要大家可以自己查阅文档。如果你的系统可以使用鼠标(远程连接的模拟器通常都可以),推荐你使用下面要介绍的htop,使用起来会更加方便。
htop
htop实际上和top的功能几乎完全一样,它同样也会进入一个动态的界面,查看系统的整体状态和每个进程各自的状态。不太一样的是,htop的界面是交互式,可以使用键盘和鼠标进行交互。你可以使用鼠标电击来选择你根据哪种指标排序进程,还可以使用鼠标点击来选中某个进程。它还提供类似kill功能。你可以通过在它的基面中输入?来查看交互式界面的使用方式。如果你想了解更多的信息也可以查看它的说明文档或者去询问AI。
这个应用可能不是你的系统自带,不过你可以使用你的系统上的包管理进行下载和安装。
反复输出某个特定字符串的命令——yes
最后,我们再来介绍一个功能很简单但是却比较有用的命令,yes。这个命令的用法非常简单,这个命令后面可以接一个可选的位置参数。如果你没有加任何参数,这个命令就会默认一直重复输出y(中间会有回车作为间隔);如果你接了一个字符串,就会重复输出这个字符串。这个命令的作用看上去有点好笑,但是它在一些情况下很有用。如果你使用过一些交互式的命令,例如,使用包管理器安装某个应用的时候,有时会需要你按y进行确认。如果你希望写一个全自动的脚本,如果在这个脚本的运行过程中出现了某些需要按y确认的地方,就可以让yes通过管道连接来自动确认,就像下面这样
yes | sudo apt install htop
yes不断输出回车,例如
yes '' | ssh-keygen
小结
看到这里,Linux shell教程的初级篇就已经完成了。在这个初级篇中,我们从shell的基本概念和基本用法开始讲起,依次介绍了和文件有关的命令,网络有关的命令,进程任务有关的命令,归档和解压缩,时间有关的命令,说明文档有关的命令以及你刚刚看完的一些杂项。这些命令都是我们开始使用Linux shell的时候会大量使用的基础命令。
如果你只是日常简单使用Linux shell,不需要在Linux shell中完成大量复杂的工作,也不需要编写脚本的话,你看到这里,可以说已经系统地入门了Linux shell,后面的内容也不是必须要学习的了。但是如果你之后会需要大量使用Linux shell,并且需要使用Linux完成各种复杂的任务,以及如果你需要学习如何自己编写bash脚本的话,那么我推荐你继续阅读之后的中级篇和高级篇的内容。