跳转至

常用 Linux 命令与工具

主要作者

@Paulkm2006

目的

让使用 Linux 变得像使用 Windows 一样简单!

本文只是作为一些常用工具的常用方法的介绍。有很多工具都具有更加高级的使用方法,因篇幅限制无法在本文中展开描述。若对某一个工具感兴趣,最简单的办法就是阅读他的 man 手册。同时,runoob 网站也覆盖了很多本文没有提及的工具。

快速开始(新手建议)

如果你是第一次接触 Linux,建议按以下顺序阅读内容,逐步掌握基础工具的使用:

  1. 如果完全没用过命令行,先读「文件与目录基础」,掌握 ls、cd、cp、rm、find 和权限的概念。
  2. 再读「输入输出与管道」,理解重定向和 |,这是后面几乎所有组合命令的基础。
  3. 然后学习如何查阅命令的用法,掌握基本帮助命令的使用方法(可参见第 0 节“如何查看命令的帮助”)。
  4. 接着了解如何查看和关闭进程,熟悉任务管理相关操作(可参见第 1 节“任务管理器系列”)。
  5. 再学习如何查看磁盘、CPU、USB 等硬件资源的使用情况(详见第 2 节“资源管理器系列”)。
  6. 最后学习查看和编辑文件内容、搜索关键词等基本文件操作(请参考第 3 节“文本和文件操作类”),以及网络与压缩等杂项(第 4、5 节)。

建议配合实际操作边学边练,更容易理解和记忆。

编写格式

很多工具都可以接受一些可选参数和开关。但同时,也有部分应用要求一些输入才能运行。在本文中,通常用如下的格式来描述命令 command [optional_parameters] required_input 其中:

  • [optional_parameters] 为可选的输入
  • required_input 为必须的开关和输入

一些开关(以- -- /等开头的参数)可能会要求额外的输入。此时其将会表示为-flag <input>,代表必须输入 input

Warning

请注意!Linux 系统是大小写敏感的!若执行命令时出现了错误的结果或提示无法识别参数,请检查一下自己的大小写是否正确。

Note

什么是“终端”或“命令行”?
简单理解,它是一个可以输入命令并看到执行结果的窗口。在 Ubuntu 中你可以使用 Ctrl+Alt+T 打开它。也叫 shell 或终端窗口。

文件与目录基础

本节面向完全没有接触过命令行的读者。已经用过 Linux 的同学可以快速浏览,但建议至少读完“权限与 sudo”部分。

认识当前位置与目录内容

  • pwd:打印当前所在目录(print working directory)。
  • ls:列出目录内容。常用组合:

    ls -l          # 长格式:权限、所有者、大小、修改时间
    ls -a          # 显示以 . 开头的隐藏文件(如 .git、.bashrc)
    ls -lh         # 大小用 KB/MB 显示,更易读
    ls -R          # 递归列出子目录
    
  • cd <目录>:切换目录。cd .. 回到上级目录,cd ~ 回到用户主目录,cd - 回到上一次所在的目录。

  • which <命令>:查看某个命令实际使用的是哪个可执行文件,遇到“同名命令版本不对”时很有用。
  • history:查看执行过的命令;!编号 可以重新执行历史中的某条命令。
  • alias ll='ls -lah':给常用命令起别名。写在 ~/.bashrc 里才能长期生效,临时起的别名在关闭终端后失效。

创建、复制、移动、删除

  • mkdir <目录>:创建目录;mkdir -p a/b/c 可以一次创建多层目录。
  • cp <源> <目标>:复制文件;复制目录必须加 -r,例如 cp -r src/ backup/。
  • mv <源> <目标>:移动文件或目录;在同一个目录内移动就相当于重命名。
  • rm <文件>:删除文件。

命令行里没有回收站

rm 删除的文件不会进入任何可以还原的地方。养成两个习惯:

  1. 删除前先确认:rm -i 文件 逐个询问,或在 rm -r 目录 之前先用 ls 目录 看清内容;
  2. 在 ~/.bashrc 中加上 alias rm='rm -I'。-I 会在删除三个以上文件或递归删除时统一询问一次,比逐个询问的 -i 更实用。
rm -i old-file.txt        # 删除前询问
rm -I build/ cache/       # 多个目标时统一询问一次

另外,命令中不要出现 rm -rf $VAR/ 这种写法:变量为空时它等价于 rm -rf /。在脚本里应先用 ${VAR:?变量未设置} 之类的写法确认变量非空。

查看文件内容片段

  • head -n 20 文件:查看开头 20 行;不加 -n 时默认显示 10 行。
  • tail -n 20 文件:查看结尾 20 行(-f 可实时跟踪,详见“文本和文件操作类”中的 tail)。
  • wc -l 文件:统计行数;-w 统计词数,-c 统计字节数。

排序与去重

  • sort 文件:按字典序排序;sort -n 按数值排序,sort -r 反向排序。
  • uniq:去掉相邻的重复行,因此通常和 sort 连用;uniq -c 会在每行前面显示出现次数。

    head -n 1000 access.log | sort | uniq -c | sort -rn | head -n 5   # 出现最多的 5 行
    

查找文件

  • find <起点> -name "*.py":按名称查找文件。
  • find <起点> -type d -name build:只查找目录。
  • find . -size +100M:查找大于 100 MB 的文件。

Tip

find 会遍历你指定起点下的整个目录树,在 / 这类大目录上执行会非常慢。把起点缩小到具体项目目录即可;只想按文件名快速定位时,locate(需要先执行 updatedb 建立索引)会快得多。

权限与 sudo

ls -l 输出的第一列形如 -rw-r--r--,共 10 个字符:

  • 第 1 位表示类型:- 普通文件、d 目录、l 符号链接;
  • 后面 9 位每 3 个一组,依次是所有者、所属组、其他人的权限;
  • 每组中的 r 表示读、w 表示写、x 表示执行,没有该权限时显示 -。

修改权限用 chmod,修改归属用 chown:

chmod +x script.sh              # 给所有用户增加执行权限
chmod 644 file.txt              # 所有者可读写,组内与其他用户只读
sudo chown "$USER:$USER" file.txt

sudo <命令> 表示以 root 身份执行这一条命令。使用时注意:

  • 只在确有必要时使用,尤其是 sudo rm、sudo mv 这类改写系统文件的命令;
  • 需要 root 权限的命令(例如监听端口的 ss -p、安装软件包)会在本文中明确标注;
  • sudo 不是“切换到管理员模式”,不要图省事给一整段脚本都加上 sudo。

内容

0. 如何查看命令的帮助

Linux 中的命令数不胜数。很显然,一下子把他们的用法和命令全部记住是一件不现实的事情。 那么有什么能帮助我们在忘记用法的时候快速查看命令的帮助呢?当然有!他的名字是 man(manual 的缩写)

man 可以被称为 Linux 系统的百科全书。从命令使用到操作系统的 API,都可以从这个工具中查阅。一般,我们会使用name(section)的格式来提示用户,这个工具的相关信息存在 man 手册中section片段的name条目下。一般来说,section的确定遵循以下编号:

  • 1 用户命令(即大部分软件的文档)
  • 2 系统调用(系统提供的 API 接口)
  • 3 运行库调用(第三方运行库提供的 API 接口)
  • 4 特殊文件/设备(如果你对某个位于/dev的东西很感兴趣,他大概率位于这个章节)
  • 5 文件格式与配置(用于配置应用/服务的配置文件格式)
  • 6 游戏
  • 7 概览与杂项
  • 8 系统管理命令(需要 root 执行的,可以改变系统信息的命令,如mount)

别慌!一般来说,作为用户的我们是不需要记住这些编号的。如果你想查看一个东西的文档,最简单的办法就是直接运行man name。man 会自动找到含有这个条目的章节并展示给你。

Note

一般来说,我们无需指定章节号。但是对于某些可能存在于多个章节的条目(比如printf既是一个位于章节 1 的工具,也是一个位于章节 3 的 API 函数),要想跳到其他章节,这个编号就是必须的。此时,命令的结构为 man [section] name

Info

对于绝大部分人类来说,man pages 的文档还是有些过于晦涩了。别担心!我们可以使用一个叫tldr的开源工具来阅读更加实用、通俗易懂的说明。关于这个工具的详情,请参考下一节的“常用的开源工具”篇目。

1. 任务管理器系列

在 Windows 中,我们可以很方便的使用任务管理器(taskmgr)实时查看后台及前台的程序列表,监视其资源占用,并强制结束掉一些无响应/不愿意自己退出的程序。 在 Linux 中,同样有很多可以实现相同功能的命令,这里选择以下几个介绍:

  • ps

    ps 命令全名为 Process Status。顾名思义,他可以监测后台正在运行的程序。

    用法:ps [options]

    当没有参数时,ps 默认输出以调用用户身份运行的全部进程。

    如果指定参数-e,则可以输出本机全部用户运行的所有进程。

    一个更常用的参数为aux,能够输出用户、pid、CPU 和内存占用、启动命令等信息

  • top

    top 命令是动态版的 ps。可以实时刷新显示后台程序及其资源占用

    用法:top [options]

    当没有参数时,top 默认每 3 秒刷新一次后台情况,并在收到用户终端Ctrl+C前保持开启

    当指定-d <seconds>、-n <times>时,会每隔 seconds 刷新一次,直到刷新了 times 次

    当指定-u <username>时,会显示指定用户的进程

    在 top 运行时输入k,会跳转到结束进程的会话,此时输入进程 pid 和信号代码即可结束。

    top 是一个相对底层(也更加难以使用)的工具。虽然它可以展示绝大多数的系统状态信息,但是这些信息过于杂乱,不是很适合人类阅读。这就引出了下一个要介绍的工具

    Tip

    如果你出于某些原因只能使用 top,可以依次按 z(彩色显示)、x(高亮当前排序列)、m(切换内存信息的显示方式)来改善阅读体验。注意 top 的交互命令都是单键,按下即生效、不需要回车,也不要像输入命令那样把它们连成一串。

    在 top 中常见字段说明:

    PID:进程 ID
    USER:所属用户
    %CPU:CPU 使用率
    %MEM:内存使用率
    TIME+:累计使用的 CPU 时间
    COMMAND:命令名

  • htop

    htop 是 top 的(超级)增强版。除了可以显示进程外,它还可以以图标的方式展现系统负载和资源利用情况,并提供了方便的快捷操作

    用法:htop

    启动后,htop 的界面一目了然:最上方为系统负载显示,中间区域列出后台进程,最下方为操作按钮。

    Tip

    是的,“按钮”是可以使用鼠标点击的——事实上,类似于 htop 这样的可以使用鼠标操作的命令行程序有个专门的名字,tui(terminal ui)

    htop 的功能非常丰富。除了可以对进程进行筛选、排序外,我们还能直接向一个进程发送中断。

    选中你想操作的进程(使用方向键或直接用鼠标点击),按F9,最左边会出现一长串以SIG开头的命令。一般来说,我们保持默认的SIGTERM即可。但是,如果一个程序不回应我们的SIGTERM,我们也可以使用更加强制的SIGKILL强制结束它。

    如果向了解更多有关 Linux 中各个信号的意义,可以参考这篇文章

    Warning

    如果系统提示找不到 htop 命令,可以使用以下命令安装(根据你的系统选择):

    # Debian/Ubuntu
    sudo apt install htop
    
    # RHEL 8+ / Rocky / AlmaLinux / Fedora
    sudo dnf install htop
    
    # CentOS 7(已停止维护 EOL,不建议在新环境使用)仍使用 yum
    sudo yum install htop
    
    # Arch Linux
    sudo pacman -S htop
    
  • kill killall 和 pkill

    我们除了可以使用 htop 与 top 来结束任务,还能直接使用命令行工具进行。

    kill 工具用于根据进程 pid 结束进程。进程的 pid 可以通过上述三个工具获取。

    用法:kill [flags] pid

    当指定-s <signal>时,会使用指定的信号结束进程。否则默认为15 SIGTERM

    信号可以用编号或名称指定,最常用的两个是:

    • -15(SIGTERM):安全终止,请求进程自行清理后退出,也是默认值;
    • -9(SIGKILL):强制终止,由内核直接结束进程,进程没有机会清理资源,只在进程不响应 SIGTERM 时使用。

    kill -l 会列出系统支持的全部信号名与编号。

    kill 12345          # 等同于 kill -15 12345
    kill -9 12345       # 强制结束无响应的进程
    kill -l             # 列出所有信号
    

    killall 工具用于根据进程名称结束进程。注意若有多个进程拥有相同的名字,killall 将会杀死所有同名的进程。

    用法:killall [flags] process_name

    当指定-i时,killall 会在结束进程之前与用户二次确认。

    pkill 工具可以用来模糊匹配需要结束的进程。例如,执行pkill fire既会结束firefox,也会结束firebird。

    用法:pkill [flags] fuzzy_name

    当指定-x时,pkill 只会结束名称完全匹配的进程

2. 资源管理器系列

Windows 里,我们可以使用设备管理器(devmgmt.msc)、磁盘管理器(diskmgmt.msc)和系统控制面板查看系统中内存、磁盘和外接设备的状态。 同理,Linux 也包含很多实用程序,帮你管理系统的各种资源

  • lsblk 与 df

    介绍这两个工具之前,我们先了解一些操作系统知识

    在操作系统的眼中,通俗意义上的“磁盘”其实包含了两层意思——物理存储数据的设备,和规定如何存储数据的文件系统。前者是底层的、一般不可改变的硬件属性,而后者(大部分是)操作系统管理的,可进行一定操作的软件抽象。

    lsblk 命令用于查看前者的属性。

    用法:lsblk

    这个命令输出的是原始磁盘和分区的大小和位置。你可以方便的看到系统连接的物理硬盘,以及它的分区情况。

    df 用于查看文件系统的属性。

    用法:df [options]

    当指定-h时,命令将输出人类可读的数据单位(MB GB 等)而非字节

    当指定-i时,命令将输出文件系统inode的使用状况。何为 inode?

    这个命令输出的是物理和虚拟文件系统的使用情况。

  • lscpu

    lscpu 输出系统 CPU 的信息。

    用法:lscpu

    输出包含 CPU 型号、核心数、频率和支持的指令集等信息

  • lspci 和 lsusb

    lspci 输出所有通过 PCI 总线连接的设备的信息。这包括显卡、多数硬盘、网络接口、USB 控制器等等设备。lsusb 显示所有插入的 USB 设备。

    用法:lspci lsusb

    注意,wsl 环境中不存在这两个命令

  • /proc 目录

什么是/proc?

Linux中/proc是虚拟文件系统,不占用磁盘空间,实时反映系统状态 你可以像查看普通文件一样查看这些特殊文件

是的,这是一个目录,而并非一个工具。Linux 遵循“万物皆文件”的原则,故我们也可以从一个个“文件”中读取到相应的系统信息。

以下几个文件是比较常用的

  • /proc/cpuinfo: 显示 CPU 信息
  • /proc/meminfo: 显示内存信息
  • /proc/swaps: 显示交换分区信息 何为 swap?

    通常,我们使用cat命令查看这些文件

  • du

    du 命令用于查看目录的大小。

    用法:du [options]

    当指定-h时,将会以人类友好的单位输出数据

    当指定-d <size>时,将以深度为 size 的目录作为一个条目

    当指定-s时,将统计当前目录占用的空间

Tip

如果你想要一个酷炫的工具来展示你的配置信息,那不妨试试neofetch或者inxi。这两个工具并非系统自带,所以你需要使用包管理器安装一下。 neofetch 输出示例

图 1. neofetch 展示的系统信息

3. 文本和文件操作类

  • cat

    cat 命令用于将一个文件的内容输出到标准输出(stdout,也就是命令行里显示的东西)。

    用法:cat [options] [filename]

    当指定-n时,cat 将会为输出加上行号

    若未指定filename,cat 将会重定向标准输入(stdin,也就是你输入命令行的东西)到标准输出。具体来说,他会变成一个复读机,显示任何你输入的内容。

  • grep

    grep 用于对文本进行提取和筛选。

    用法:grep [options] pattern [file]

    当指定-i时,grep 将忽略大小写进行匹配

    当指定-v时,grep 将进行反向查找,只输出不符合pattern的行

    当指定-n时,grep 将会为输出加上行号

    pattern参数代表需要查询的字符串或正则表达式。

    当没有指定file时,grep 将从命令管道中读取数据并进行查找。有关管道的使用和定义,请参考本章「输入输出与管道」一节。

    当file为一个目录且指定-r时,grep 将遍历该目录下所有文件。

    可以毫不夸张的说,grep 是 Linux shell 中绝大多数应用必不可少的帮助工具。例如,我们常用 grep 和 cat 筛选并列出日志中感兴趣的条目,或使用 grep 和 ps 查找一个进程的 pid。

  • nano,vi 和 vim

    这三个工具都是 Linux 环境下的文本编辑器。

    对于初学者(但是并不局限于初学者)来说,nano 是其中最友好也最方便的一个。

    用法:nano [options] filename

    当指定-B时,nano 将自动为编辑的文件创建一份备份(文件名为filename~)

    nano 的界面非常友好,可以进行的操作一目了然。以下几个快捷键是比较常用的:

  • Ctrl+X 退出

  • Ctrl+O 保存
  • Ctrl+W pattern 查找
  • Ctrl+\ pattern replace 替换
  • Ctrl+/ n 跳转到第 n 行

    vi 和 vim 是有悠久历史的 Linux 文件编辑器。它们的操作方式比较复杂,但是对于熟练掌握的用户来说非常方便。本文在此对其高级用法不过多的赘述,若感兴趣可以阅读Vim Cheat Sheet

    用法:vi/vim filename

    打开文件后:

    1. 按下 i 进入编辑模式(底部显示 -- INSERT --)
    2. 编辑完成后按 ESC 返回命令模式
    3. 在命令模式下输入:
      • :w 保存
      • :q 退出
      • :wq 保存并退出
      • :q! 强制退出不保存(注意是英文感叹号)

    Tip

    若编辑时卡住,连续按 ESC 确保返回命令模式再输入指令。

    Info

    多数系统自带的 vim 都是vim-tiny而非完整的vim。若你在更改他的配置时发现了一些不对劲的地方,可以试试安装完整版的 vim。

  • more 和 less

    在使用 shell 时,我们经常遇到输出过长,一页屏幕装不下的情况。这时,我们可以使用 more 和 less 来实现输出的分页。通常来说,我们会更倾向于使用 less

    more 与 less 的用法非常相似,故在此一并叙述

    用法:more/less [+line] [+/pattern] [filename]

    当指定+line时,工具将会从line行以后开始显示

    当指定+/pattern时,工具将会从符合pattern的位置开始显示

    当未指定filename时,工具将会读取标准输入作为数据源

    在进入了分页界面后,我们可以使用以下命令操作

  • Enter 向下一行

  • Down/Up 注意,在 more 中这两个按键的作用是向下/上一页,而在 less 中是向下/上一行
  • q 退出
  • h 查看帮助信息

Example

你可以使用 cat 命令输出内容并通过管道 | 传给 less 实现分页:

cat largefile.txt | less

或直接打开文件:

less largefile.txt
  • tail

    我们有时只想查阅文件最末尾的内容,或实时显示文件的最新输出。此时,tail 工具就能派上用场。

    用法:tail [options] [+from] [filename]

    当指定-f时,tail 将进行循环读取,也就是实时更新文件内容

    当指定-n <num>时,将会输出末尾num行的内容。若无此参数,默认输出末尾 10 行

    当指定+from时,将会从第from行开始输出内容

  • touch

    touch 命令用于修改文件的时间属性或创建文件。顾名思义,被 touch 的命令就像被“摸”过,其读取或修改时间会变为命令执行的时间。

    用法:touch [options] filename

    当指定-a时,则只会改变读取时间

    当指定-m时,则只会改变修改时间

    当指定-t <stamp>时,则会使用 stamp 指定的时间。stamp 的格式为[[CC]YY]MMDDhhmm[.ss]

    当未指定-c且filename不存在时,touch 会创建该文件

  • diff

    diff 用于比较两个文件不同的地方。

    用法:diff [options] filename1 filename2

    当指定-y时,将会以并排的方式显示两个文件。若同时指定-W <width>则会使用指定的宽度作为一栏

    当指定-u时,将会高亮输出差异的部分,并合并相同的部分

    当指定-q时,仅会输出两个文件是否有差异,而不输出他们的差异详情

    当文件较大时,通常会指定-H参数以加速比对

    Tip

    我们可以使用vimdiff工具进行可视化、交互的文件对比

4. 网络操作类

  • wget 和 curl

    wget 和 curl 都被用于发起网络请求。他们的区别在于 wget 主要用于下载文件(然而 curl 其实也可以),curl 主要用来发起请求。

    用法:wget [options] url

    当指定-O <filename>时,会将下载的文件重命名为filename。当filename为-时,将会将获得的内容输出到标准输出

    当指定--no-check-certificate时,会忽略证书错误

    Warning

    忽略证书校验会同时关闭对中间人攻击的防护,攻击者可以替换你下载的内容而不会被察觉。它只适合在确认是本地证书配置问题时的临时排障,不要写进脚本、CI 或长期配置里。

    用法:curl [options] url

    当指定-X <method>时,将使用method方法发送请求。

    当指定-H <header>时,将会使用header作为请求头

    当指定-o <filename>时,将会把回应输出为文件。若没有指定这个选项,将会输出到标准输出

    当指定-L时,将会跟随重定向

    当指定-d <data>时,将会把data的数据作为请求体发送。特别的,data中可以指定@filename,此时将会上传文件

    常用场景示例:

    # 下载文件并重命名
    wget -O logo.png https://example.com/image.png
    
    # 快速测试 API(JSON 格式美化)
    curl -s https://api.example.com/data | jq  
    
    # 带身份验证的请求:省略密码,让 curl 交互式提示输入
    curl -u user https://api.example.com
    # 或把凭据放进 netrc 文件(记得 chmod 600,不要提交到仓库)
    curl --netrc-file ~/.netrc https://api.example.com
    

    不要把密码写在命令行里

    curl -u user:password 会把明文密码写进 shell 历史(~/.bash_history),并且在该进程运行期间对同机器的其他用户可见(ps aux 能看到完整命令)。CI 和脚本中请使用环境变量或平台的密钥管理,不要把凭据硬编码进命令。

功能 wget curl
默认行为 下载文件 显示网页内容或发起请求
支持协议 HTTP, HTTPS, FTP 支持协议更多(HTTP, FTP, SMTP 等)
文件上传 不支持 支持(-d 或 --upload-file)
是否默认安装 随发行版而异:部分最小化安装、容器镜像不含 wget 随发行版而异:部分精简镜像不含 curl

使用前可以用 command -v wget curl 检查它们是否存在。两者都是 HTTP 客户端,缺哪个就用另一个替代即可。

  • ftp

    ftp 用于从或向服务器传输文件。注意!ftp,ftps,sftp是三个不同的协议!ftps是加密的ftp协议,而sftp是基于ssh协议传输。

    用法:ftp [[user[:password]@]host[:port]]

    当在执行程序时没有指定服务器时,可以在打开工具后执行命令open [[user[:password]@]host[:port]]进行连接

    连接后,使用put local remote上传文件,get remote下载文件。

  • ssh 和 sftp

    ssh 协议是一种加密的数据传输协议。通常,我们使用这个协议来远程登录服务器。

    用法:ssh [options] [user@]host

    当指定-p <port>时,ssh 将通过port连接

    当指定-i <filename>时,使用filename指定的私钥进行鉴权。若没有指定这个选项,ssh 默认使用位于~/.ssh/id_{rsa,ecdsa,ed25519}的文件中的密钥

    当指定-L <[bind_address:]port:host:hostport>时,将会把远程服务器上host:hostport的端口转发到本机bind_address:port上

    sftp 的用法与 ftp 与 ssh 非常相似,故在此不多赘述。

  • ping

    ping 命令用于向服务器发送 ICMP 数据包以检测网络连通性与延迟。注意,目前多数公共服务阻断了 ICMP 连接,所以无法 ping 通并不意味着无法使用该服务。

    用法:ping [options] host

    当指定-c <count>时,将会进行count次检测。若无此参数,ping 将一直检测直到按下Ctrl+C

    当指定-i <interval>时,将会在两次检测之间延迟interval秒

  • ip

    ip 工具用于配置 Linux 系统上几乎全部的与网络相关的设置。出于简洁需要,本文只对其中一小部分常用功能进行叙述。若想了解更多,可以使用 man 命令查看其手册

    用法:ip object [command]

    当指定object为a(或addr,address),会输出网络端口的地址信息

    当指定object为link,会输出网络端口的状态信息

  • ss

    ss 用于查看网络连接、统计信息和监听端口,是 netstat 的现代替代品(netstat 在新版发行版中已不再默认安装)。

    用法:ss [options]

    当指定-t/-u时,分别显示 TCP/UDP 连接;-n 用数字形式显示地址和端口(不做域名解析,速度更快、结果更稳定);-l 只显示处于监听(listen)状态的端口。

    加上-p会显示占用端口的进程,但读取其他用户的进程信息需要 root 权限,普通用户执行时这一列会是空的或提示权限不足;把命令写成 sudo ss -tunlp 即可。

    ss -tunl           # 查看所有监听的 TCP/UDP 端口(无需 root)
    sudo ss -tunlp     # 同时显示占用端口的进程
    

5. 杂项

  • 压缩与解压缩

  • .tar.*文件

    初次使用 Linux 下的压缩文件时,你会发现很多文件的后缀都有两个部分。这是因为,tar是一种文件归档格式,作用是将多个文件、目录集中到一个文件中;xz,gz和bz2等是压缩格式,用于减小归档文件的体积。

    无论使用了何种压缩格式,我们都能使用tar工具对其解压

    用法:tar [options]f filename [options2]

    注意,如果你是对文件进行操作,则在任意option的末尾必须加上这个f,代表文件操作

    一些常用的方法为:

    tar xvf filename -C dir 解压并展开filename中的文件和路径到dir目录中,并显示详细信息

    tar czvf archive.tar.gz file1 file2 dir1 ... 将file1,dir1等文件和目录归档并压缩到archive.tar.gz文件中

  • 7z和rar

    本节使用 7-Zip 的 7z 命令。若系统没有该命令,先通过包管理器安装提供它的软件包。部分发行版还提供名为 p7zip 的包装脚本,它与 7z 的语法不同,不能混用。

    7z 采用命令式语法:7z <命令> [选项] <归档> [文件...],压缩与解压对应不同的命令。

    7z x archive.7z          # 解压
    7z a archive.7z dir/     # 把 dir/ 压缩成 archive.7z
    

    关于输入文件的去留:7-Zip 默认保留输入文件。只有在显式加上 -sdel(delete after compression)时,才会在成功操作后删除源文件。所以“7z 默认删除输入”是常见误解。

    RAR 只能解、不能压:7z 可以解压 RAR 归档,但无法创建 RAR 文件(RAR 的压缩算法有许可限制)。需要生成 RAR 时只能使用官方的 rar 工具。 - zip

    zip 文件是日常生活中最常见的压缩格式。在 Linux 中,我们可以选择使用7z或unzip与zip来操作。7z的使用方法参考上一条

    用法:unzip [options] file.zip

    当指定-d dir时,将会解压到dir目录中

    用法:zip archive file1 file2 ...

  • 计划任务

    有时,我们会希望某个命令被按一定的时间执行,例如每天 9 点自动更新软件包。此时,我们可以使用 crontab 工具

    用法:crontab [options]

    当指定-e,该命令会使用你的默认文本编辑器打开一个配置文件。这个配置文件的详细格式可以参考这篇文章

    时间格式图解:

    ┌── 分钟 (0-59)
    │ ┌── 小时 (0-23)
    │ │ ┌── 日 (1-31)
    │ │ │ ┌── 月 (1-12)
    │ │ │ │ ┌── 星期 (0-7, 0 和 7=周日)
    │ │ │ │ │
    * * * * * command
    

    示例

    0 9 * * 1-5 command → 每周一到周五 9:00 执行
    */10 * * * * command → 每 10 分钟执行

  • 服务

    我们会希望一些服务(如 web 服务器、数据库等)能够在系统启动的时候也一起启动,并能够不被干扰的在后台运行。这时,我们就会用到systemd

    对于 systemd 的使用可以参考这篇文章

    一般来说,通过包管理器安装的应用都为我们配置了systemd服务,我们可以直接对其进行操作

    用法:systemctl verb [options] [object]

    其中,verb 可以是以下这几个。注意除特殊说明外,object 均是必须包含的参数

    - start 启动
    - stop 停止
    - enable 设置开机启动。若同时附带`--now`参数相当于同时执行`start`
    - disable 取消开机启动
    - restart 重启
    - reload(对于支持的应用)重载配置
    - status 查看状态
    - daemon-reload 当更改过服务的配置文件后,需要运行这个命令让 systemd 读取更新的文件。这个命令无需指定`object`
    - ...
    

    Note

    严格意义上来说,systemd其实是一整套工具,能够让我们管理 Linux 系统的方方面面。

    Warning

    对于 Alpine Linux 用户:Alpine 发行版使用的并不是systemd而是OpenRC。若需要了解更多信息,请参考Alpine wiki

  • nohup 与 screen 在 ssh 会话结束后,我们运行的所有前台应用都将会被销毁。若需要将会话长时间保持后台运行,我们可以使用 nohup 或 screen 工具 nohup 的作用是让应用不受 ssh 会话终止的影响,继续在后台运行。 用法:nohup [command]

    通常,我们使用指令nohup command > log.log 2>&1 &,意义为:在后台运行command,将其的标准错误输出(stderr)合并到标准输出,并重定向到文件log.log,并让终端继续接受后续命令

    基础用法:

    # 后台运行脚本并忽略关闭信号
    nohup python myscript.py &
    
    # 查看实时输出
    tail -f nohup.out
    

    screen 的作用是相当于一个虚拟终端。我们可以随时切换回到这个终端,或从这个终端分离。分离后,其将继续在后台运行 用法:screen [options] [command] 当指定-ls时,会显示所有运行的 screen 会话 当指定-d时,会以分离的模式运行这个会话 当指定-S <name>时,会将会话命名为name,方便后续管理 当指定-r <id/name>时,会切换到相应终端 当指定-XS <id/name> <command>时,会在对于会话中执行命令 若想从终端中分离,可以同时按下Ctrl+A+D按键 若想结束一个终端,先用 screen -ls 查看会话 ID,再将 screen -XS SESSION_ID quit 中的 SESSION_ID 替换为目标会话 ID。

    结束会话会终止其中的任务

    执行前确认会话 ID 无误,并确认会话中没有需要继续运行的任务或尚未保存的工作。

    Note

    screen 工具由于维护不佳,导致出现了许多漏洞。在可能的情况下,我们更加推荐使用 tmux。关于这个工具的详情,请参考下一节的“常用的开源工具”篇目

输入输出与管道

Linux 命令默认从标准输入(stdin)读取数据,把正常结果写到标准输出(stdout),把错误信息写到标准错误(stderr)。把这三者分清,才能像搭积木一样组合命令。

重定向

写法 作用
> file 把标准输出写入文件,覆盖原有内容
>> file 把标准输出追加到文件末尾
< file 把文件内容作为标准输入
2> file 把标准错误写入文件
2>&1 把标准错误合并到标准输出
> file 2>&1 标准输出和标准错误一起保存(顺序不能颠倒)
ls -l > listing.txt          # 覆盖写入
date >> log.txt              # 追加写入
./build.sh > out.txt 2>&1    # 输出与错误都保存
./build.sh > /dev/null 2>&1  # 丢弃全部输出

> 会立刻清空目标文件

即使后面的命令执行失败,> file 也已经把文件内容清空了。想保留原内容请用 >>;对重要文件先备份一份。

管道 |

管道把前一个命令的标准输出交给后一个命令的标准输入,中间不产生临时文件:

ps aux | grep ssh        # 在进程列表中筛选 ssh
less largefile.txt       # 直接打开,不必先 cat
history | grep git       # 在命令历史中查找 git

管道只传递标准输出。前一个命令写到标准错误的报错仍会直接显示在终端上;需要一起处理时写成 2>&1 |。

tee:既显示又保存

tee 把标准输入同时写到文件和标准输出,适合既要看结果又要留档的场景:

./tests.sh | tee result.log        # 显示并写入(覆盖)
./tests.sh | tee -a result.log     # 追加
./tests.sh | tee /dev/tty | wc -l  # 在屏幕上显示的同时统计行数

xargs:把输入变成参数

管道传递的是数据,不是命令行参数。有些命令(如 rm、mkdir)只接受参数,这时用 xargs 把输入的每一行转换成参数:

find . -name "*.tmp" | xargs rm -f               # 删除所有匹配文件
grep -rl "TODO" docs/ | xargs wc -l              # 统计所有含 TODO 的文件行数
find . -name "*.png" | xargs -I{} cp {} backup/  # 对每个文件执行一次

文件名含空格时 xargs 会出错

xargs 默认按空白切分输入,文件名中的空格会被当成参数分隔符。安全做法是配合 -0 和 find -print0:

find . -name "*.tmp" -print0 | xargs -0 rm -f

也可以让 find 自己执行命令:find . -name "*.tmp" -exec rm -f {} +。

小练习

  1. 用 ps aux 命令查看所有进程,并使用 grep 查找包含关键词 "ssh" 的进程。
  2. 使用 top 命令,观察当前哪个进程占用 CPU 最高。
  3. 使用 kill 命令终止某个你启动的测试进程(比如 gedit)。
  4. 尝试用 ss -tunlp 查看当前系统监听的端口(-p 需要 root 权限,可用 sudo ss -tunlp;只看端口可省略 -p)。
  5. 在任意目录下用 pwd、ls -l、cd 走一遍,再用 mkdir 建一个临时目录并在其中创建文件。
  6. 把 ps aux 的输出保存到文件(>),再用 wc -l 统计行数;尝试用 | 把两步合成一条命令。

小贴士

  • 想更深入学习这些工具?推荐查看 https://explainshell.com
  • 遇到不会用的命令?试试 man <命令> 或 <命令> --help
  • 多实践!Linux 学习最好的方式是——动手敲命令

附录:推荐安装的常用工具(适合新手)

下表只列出本文提到的工具与安装方式;更详细的用法(尤其是 tmux 与 btop)请参考 常用的开源工具 一节。

工具 作用简述 安装命令(Ubuntu/Debian)
tldr 简洁版 man 手册 sudo apt install tldr
htop 图形化任务管理器 sudo apt install htop
btop 现代化的资源监视器(详见 常用的开源工具) sudo apt install btop
tmux 终端会话管理,断线后任务不丢(详见 常用的开源工具) sudo apt install tmux
neofetch 显示系统信息图 sudo apt install neofetch
inxi 全面展示硬件/系统信息 sudo apt install inxi
unzip 解压 zip 文件 sudo apt install unzip
p7zip-full 处理 7z 文件(安装后命令为 7z) sudo apt install p7zip-full