1. Linux背景

Linux 不是凭空出现的,它属于“类 UNIX(Unix-like)”体系,所以讲 Linux 背景一般要从 UNIX 的起源讲起。

  • 1968 年:Multics(多任务、文件管理、多用户等新概念)
  • 1969–1970 年:贝尔实验室 Ken Thompson 和 Dennis Ritchie 在吸收 Multics 思想后开发 UNIX;从一开始就强调 多用户、多任务、高效
  • 1972 年:开始发放商业版本,并授权给伯克利等;伯克利后来形成 BSD 分支
  • 后续:AT&T 的 System V、BSD 等分支并行发展,导致“标准化需求”出现

一句话总结背景:Linux 所继承的是 UNIX 这条路线的核心思想(多用户、多任务、工具链、文件系统/权限等)。

1.1 Linux 的“发展历史”在说什么?

Linux 的发展史通常指:Linux 内核从“个人项目”变成“全球协作 + 工业级生态”的过程。

关键节点:

  • 1991/10/5:Linus Torvalds 在新闻组宣布做了一个类似 UNIX 的小 OS(受 Minix 启发)
  • 0.01 没正式发布(不实用),提供过源代码;10/5 发布的被称为 0.02,已经能跑 bash、gcc 等工具链
  • 后续版本快速迭代,1994 年正式发布 1.0 版本

Linux 一开始就和 GNU 工具链(bash/gcc)强绑定,这也是为什么我们说“Linux 生态不是只有一个内核”,而是一整套用户空间工具+开发工具+发行版组织方式。

1.2 Linux发行版:为什么会有 Ubuntu / CentOS 这么多?

先把最关键的词拆开:Linux ≠ 一个完整操作系统

严格说:

  • Linux:是“内核”(kernel)
  • 平常装的“Ubuntu / CentOS / Debian …”:是 Linux 内核 + 用户空间程序 + 包管理器 + 默认工具/配置 +(可选)桌面环境 组成的“完整操作系统”

所以“发行版”就是:把内核与大量软件打包、配置、测试、发布,让普通人能直接安装使用的一整套系统。

1.3 为什么会有很多发行版?

本质原因是“目标不同”:

  • 有的追求 极致稳定/服务器友好
  • 有的追求 对新手友好/桌面体验
  • 有的追求 企业商业支持/认证体系
  • 有的追求 最新技术试验场
  • 有的面向 特定场景(如安全测试)

这些目标不同,就会带来:默认软件选择不同、更新节奏不同、包管理工具不同、社区/公司支持方式不同。

1.4 常见发行版(Ubuntu、CentOS 等)区别

下面按讲义给的定位来讲(这就是你问的“区别在哪”)。

Debian:稳定、偏“老手/管理员”

  • 特点:稳定,非常适合服务器
  • 但对新手不友好,更适合系统管理员和高级用户

Ubuntu:Debian 的衍生版,新手友好、应用广

  • Ubuntu 是 Debian 的衍生版,也是非常流行的免费系统
  • 常见于服务器、云计算、甚至一些移动设备;对新手友好

“衍生版”:可以理解为“在 Debian 的包体系/社区成果上,重新做默认选择、体验与发布策略”,更贴近某类用户(Ubuntu 更贴近大众与新手)。

RHEL(红帽企业版):商业化、企业生态

  • 面向商业市场,有服务器版本,支持多种处理器架构
  • 还配套管理员/工程师认证体系(RHCSA/RHCE)

CentOS:用 RHEL 的免费源码重构,追求“像 RHEL 但不用付费”

  • CentOS 用 RHEL 的免费源代码重新构建
  • 去掉商标与二进制包上很细微的差异;外观与行为与 RHEL 很像
  • 使用 YUM 管理软件包

这就是你问的“Ubuntu vs CentOS 最大差异”之一:

  • Ubuntu 走“Debian 系 + 新手友好 + 通用桌面/服务器生态”
  • CentOS 走“红帽系 + 企业服务器风格 + 接近 RHEL 的行为/管理方式(YUM)”

Fedora:更“新”、更激进,像红帽的试验田

  • 适合想尝试最先进技术、等不及稳定版的人
  • 它相当于红帽的测试平台:新东西先在 Fedora 上开发测试,再进入企业发行版

Kali Linux:Debian 衍生版,面向安全测试场景

  • Kali 是 Debian 的衍生版,目标是渗透测试(安全测试)
  • 带大量相关工具,使用 APT 管理软件包

(了解定位即可;真正学习安全方向需要系统课程与合规环境,不建议“拿来就用”乱试。)


1.5 XShell 是什么?它和 shell 有啥关系?

先别被名字迷惑:

  • shell(小写):shell 是“解释器这一类东西”的总称(类别/概念),bash 是其中一个具体实现(某一种 shell)。

    “shell”指的是:接收你输入的命令 → 解析(解释)→ 调用系统去执行 → 把结果输出给你 的那层程序。
    它像一个“命令语言的运行环境”。

    常见 shell:bash、sh、zsh、fish、csh 等。

    bash 全称 Bourne Again SHell,是最常见的 shell 之一;即bash是一种具体的shell。
    所以:

    • 你说“我在用 shell” = 你在用某个 shell(可能是 bash/zsh…)
    • 你说“我在用 bash” = 明确指出你用的 shell 是 bash
  • XShell(大写):是 Windows 上的远程终端软件,用来从你电脑连接到 Linux 服务器/虚拟机,常用协议是 SSH。

    场景:在xhsell中输入ll指令
    XShell 把字符发给远端 → 远端的 bash(shell) 解析 ll(alias)→ 实际运行 ls -l

2. 基础指令

下面把你截图这几页内容整理成复习笔记(按“指令 → 语法/功能 → 常用选项 → 示例/要点”来写),并把最常用的选项加粗。


2.1 ls 指令

语法

  • ls [选项] [目录或文件]

功能

  • 对目录:列出该目录下的所有子目录与文件
  • 对文件:列出文件名以及其他信息

常用选项

  • -a:列出目录下所有文件,包括以 . 开头的隐含文件
  • -d:将目录像文件一样显示,而不是显示其下的文件(例:ls -d 指定目录)
  • -i:输出文件的 i 节点(inode)索引信息(例:ls -ai 指定文件)
  • -k:以 k 字节的形式表示文件大小(例:ls -alk 指定文件)
  • -l:列出文件的详细信息
  • -n:用数字的 UID、GID 代替名称(介绍 UID、GID)
  • -F:在每个文件名后附上一个字符说明类型:
    • * 可执行普通文件;/ 目录;@ 符号链接;| FIFOs;= sockets(目录类型识别)
  • -r:对目录反向排序
  • -t:以时间排序
  • -S:在文件名后输出文件大小(用于大小排序,思路:找目录下最大文件)
  • -R:列出所有子目录下的文件(递归)
  • -1:一行只输出一个文件

复习提醒: ll 往往是 ls -l 的别名(alias),本质还是在调用 ls。

ls -ld / = “显示根目录 / 这个目录本身的详细信息(权限/属主/大小/时间等),不展开列出 / 里面有哪些文件”。

在这里插入图片描述

示例

  • ls:只列当前目录的普通可见项(例:dir file.txt)
  • ls -a:会多出 . 和 ..(当前目录/上级目录),并显示隐藏文件
  • ls -a -l:进入“详细信息模式”,输出会出现 total 12 以及每项的详细行
  • ls -a -l -F:在文件名后追加类型标记(如目录会显示为 dir/、当前目录 ./)
  • ls -alFn:把 -a -l -F -n 合在一起;效果上能看到 UID/GID 变成数字(例:1003 1003)

2.2 pwd 命令

语法

  • pwd

功能

  • 显示用户当前所在的目录

常用选项

  • 无

示例

  • 输入 pwd 输出如:/home/zmm/test

路径

  • Linux 系统中,磁盘上的文件和目录被组织成一棵目录树,每个节点都是目录或文件
  • 普通文件一定是目录树的叶子节点
  • 目录可能是叶子(空目录),也可能是“路上节点/路径节点”
  • 路径存在意义:树状组织是为了快速定位文件;定位需要唯一性
    • 任意节点只有一个父节点,所以从根目录开始定位,路径具有唯一性
  • 绝对路径:一般从 / 开始,不依赖其他目录来定位文件/目录的方式
  • 相对路径:相对于当前用户所处目录来定位文件/目录的方式
  • 绝对路径一般不会因用户所在路径变化而丢失唯一性,常用于特定服务配置文件
  • 相对路径因为方便,一般在命令行里用得更多

Linux 目录结构

  • /dev:存放抽象硬件
  • /boot:存放内核与启动文件
  • /lib:存放系统库文件
  • /bin:存放二进制文件(可执行命令)
  • /sbin:存放特权级二进制文件
  • /usr:存放安装程序(软件默认目录)
  • /var:存放经常变化的文件
  • /mnt:文件挂载目录(U 盘、光驱)
  • /home:普通用户目录
  • /root:特权用户目录
  • /etc:存放配置文件目录
  • /opt:大型软件存放目录(非强制)

2.3 cd 指令

语法

  • cd 目录名

功能

  • 改变工作目录:将当前工作目录切换到指定目录下

示例

  • 返回上级目录:从 /home/zmm 回到 /home(本质是 cd .. 的效果)
  • 绝对路径定位:cd /home/zmm/test,再 pwd 看到 /home/zmm/test
  • 相对路径定位:cd ./temp/,再 pwd 看到 /home/zmm/temp
  • 回到家目录:cd ~ 回到 /home/zmm
  • 回到最近访问目录:cd - 可在“当前目录”和“上一次所在目录”之间来回切换(例子里在 /home/whb 和 / 之间切换)

2.4 touch 指令

语法

touch [选项]... 文件...

功能(两件事)

  1. 如果文件不存在:创建一个新的空普通文件(大小 0)。
  2. 如果文件已存在:更新文件的时间戳(也可以用于目录)。

“更改文档或目录的日期时间,包括存取时间和更改时间”。这里的“存取时间”= Access time(atime),“更改时间”通常指 Modify time(mtime),但 stat 里还有一个更关键的 Change time(ctime)(下面解释)。

常用选项

  • -a:只改访问时间(Access time / atime)。
  • -c:只改修改时间。

⚠️ 重要纠错(别漏这个坑):在常见 Linux(GNU coreutils)里:

  • -m 才是 “只改 mtime(Modify)”
  • -c 通常是 “文件不存在就不创建(no create)”

而你课件的示例也实际使用了 touch -m newFile.txt 来改 Modify 时间。
所以:以示例为准:改 Modify 用 -m;-a 改 Access;两者都会影响 Change(下面讲原因)。

(1) 创建文件

touch newFile.txt

然后 ls 能看到多了 newFile.txt。

root@aliyun:~/lesson1# stat newFile.txt 
  File: newFile.txt
  Size: 0         	Blocks: 0          IO Block: 4096   regular empty file
Device: 253,3	Inode: 261647      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2026-02-10 13:02:38.235452027 +0800
Modify: 2026-02-10 13:02:38.235452027 +0800
Change: 2026-02-10 13:02:38.235452027 +0800
 Birth: 2026-02-10 13:02:38.235452027 +0800

stat 就是“查看文件状态(status)”的命令:把文件在文件系统里的关键信息打印出来。

  • 它看的不是文件内容,而是文件的属性(权限、属主、时间、inode 等)。
  • Linux 内部有个系统调用也叫 stat(),这个命令本质就是把系统调用拿到的信息格式化输出。

(2) stat newFile.txt

课件里 stat 的关键行有四个时间:

  • Access: 权限(例如 0664)+ 所有者/组
  • Access: 2023-...:atime(最后一次“访问/读取”该文件内容的时间)
  • Modify: 2023-...:mtime(最后一次“文件内容发生变化”的时间),只要文件内容变了(写入/追加/截断),mtime 就变。
  • Change: 2023-...:ctime(最后一次“元数据变化”的时间:权限、所有者、链接数、atime/mtime 被改等都会更新它)
  • Birth::创建时间(很多文件系统/挂载方式下可能没有,所以显示 -)
  • +0800:时区是东八区,.235452027:纳秒级小数(非常精细)

你图里问的“Change 为什么会变?”就是 ctime 的机制问题。

在这里插入图片描述


(3) touch -a newFile.txt:只改 atime,为啥 Change 也变?

在这里插入图片描述

  • Access(atime) 变成了 13:35:09…
  • Modify(mtime) 没变(还在 15:06:45…)
  • Change(ctime) 变成了 13:35:09…

原因(务必掌握):

  • Change(ctime) 是 inode 元数据最后变更时间。
  • 你执行 touch -a 虽然只改了 atime,但“atime 本身就是 inode 里记录的元数据之一”,所以 inode 被更新了 → ctime 必然刷新。
  • 结论:只要你改 atime 或 mtime,ctime 都会跟着变。

1)inode 有两层含义

在日常口语里大家把 inode 说成“身份证”,其实混了两件事:

  1. inode 号(inode number):才像“身份证号”,一般不会变
  2. inode 里存的内容(inode 数据/元数据):像“身份证上印的各种信息”,这些是会变的

stat 里这一行:

Inode: 261647

这里的 261647 就是 inode 号(“身份证号”)。


2)那我说 “inode 被更新” 到底在说啥?

我说的“inode 被更新”指的是:inode 这个结构体里的某些字段被改写了,不是 inode 号变了。

inode 里面通常存这些“元数据”:

  • 权限(0644)
  • 属主/属组(root/root)
  • 硬链接数(Links)
  • atime / mtime / ctime 这些时间戳
  • 以及文件数据块的位置指针(文件内容在哪些块)

当你执行:

touch -a newFile.txt

它的目标是:把 atime 改成现在的时间。
atime 就存放在 inode 的一个字段里,所以内核需要把 inode 里“atime 那个字段”写成新值。

于是发生两件事:

  • atime 字段变了 ✅
  • 因为 inode 的“元数据”发生了变化,所以 ctime(status change time)也必须更新 ✅

注意:inode 号不需要变,也通常不会变。


(4) touch -m newFile.txt:改 mtime,同时 ctime 也变

课件里:

  • Modify 变到 15:09:19…
  • Change 也同样变到 15:09:19…

同理:改了内容时间戳(mtime)→ inode 更新 → ctime 更新。


需要记住的“时间戳三件套”规律

  • -a:改 atime,ctime 也会变,mtime 不变
  • -m:改 mtime,ctime 也会变,atime 不变
  • 任何会改 inode 的动作(chmod/chown/ln/改时间戳等)→ ctime 更新
root@aliyun:~/lesson1# ll
-rw-r--r-- 1 root root 0 Feb 10 13:02 newFile.txt

默认 ls -l 显示的是 mtime(Modify),也就是“最后修改内容时间”。


(5)

sleep 2
echo "hi" >> newFile.txt
stat newFile.txt

Modify(mtime) 一定更新

Change(ctime) 也一定更新(因为内容变了,inode 也更新)


2.5 mkdir 指令

语法

mkdir [选项] dirname...

功能

在当前目录下创建一个名为 dirname 的目录。

常用选项

  • -p/--parents:递归创建路径。路径中某些中间目录不存在时,会自动补齐;一次能建多层目录。

示例拆解

(1) 创建普通空目录

mkdir mydir 后 ls -l 多出 mydir(目录类型在 ls -l 第一位是 d)。

(2) 递归建多级目录

mkdir -p path1/path2/path3/path4:如果 path1/path2/… 都不存在,会全部建出来。
课件用 tree path1 展示结构。

-p 的另一个常见效果:当目录已存在时,不会报错(更适合脚本)。


2.6 rmdir 指令

定位(和 mkdir 相反)

mkdir 建目录,rmdir 删目录。

语法

rmdir [-p] [dirName]

适用对象

对目录有相应操作权限的用户。

功能

只能删除空目录。

常用选项

  • -p:如果删掉子目录后父目录也变空,则 连父目录一起删(一路向上“顺带清理”)。

示例与错误场景

  • 删除空目录:rmdir mydir 成功。
  • 递归删除一串空目录:rmdir -p path1/path2/path3/path4,连带把空的父目录都清掉。
  • 目录非空就失败:课件展示 Directory not empty。

2.7 rm 指令(删除文件/目录)

语法

rm [-f-i-r-v] [dirName/dir]

功能

删除文件或目录(但删目录通常要配合 -r)。

常用选项

  • -f:强制删除。就算只读(写保护)也直接删,不提示。
  • -i:删除前逐一确认(安全)。
  • -r:递归删除目录及其下所有内容(删目录必备)。

语法里还有 -v:一般表示 verbose(显示过程)。作用:让 rm 输出删除了哪些项。

示例拆解

  1. rm file.txt:删除普通文件。
  2. 直接 rm dir 会报错:因为 dir 是目录。
  3. rm -r dir:递归删除目录成功。
  4. rm -i newFile.txt:删除前询问,输入 y 才删。
  5. rm -ri d:对目录递归删除时,每下钻一层、删每个目录都会问一次(非常安全但很啰嗦)。
  6. rm -rf path1:递归 + 强制 删除非空目录(危险但常用)。

最关键安全提醒

  • rm -rf 在 root 下几乎不可逆,路径写错就是事故。
  • 习惯:先 ls/pwd 确认位置;不确定就先用 rm -ri;或者先 echo rm ... 演练命令再执行。

补充: ls -l 里看到的第一位字符就是类型:

  • d 目录、- 普通文件、l 软链接……。
    touch 创建的是 普通文件(-);mkdir 创建的是 目录(d);rmdir/rm -r 删除的是目录节点。

下面把你截图里 man 和 cp 这两块内容整理成“可复习的笔记”,并且把最常用的选项加粗、每个点都配例子(都来自你这份讲义)。


2.8 man 指令

作用/意义

Linux 命令参数很多,不可能全记住,可以用 man 查看联机手册获取帮助。

语法

man [选项] 命令

常用选项(加粗=最常用)

  • -k:根据关键字搜索联机帮助(按“关键词”查)。

    man -k printf
    # man -k ls:在本机手册索引里“搜关键字 printf”,把相关条目列出来
    

在这里插入图片描述

  • num:只在第 num 章节查找(指定“手册章节”)。

    man 2 fork
    
  • -a:把所有章节都显示出来。讲义解释:例如 man printf 默认从第1章开始搜,找到就停;用了 -a 后,你按 q 退出当前章节,它会继续往后搜索,直到把所有章节都搜完。
    例子:

    man -a printf
    

man 手册的“9个章节”分别是什么

注:不同系统可能会有差别。

  1. 第1章:普通命令
  2. 第2章:系统调用,如 open、write(还能方便查到调用函数需要加什么头文件)
  3. 第3章:库函数,如 printf、fread
  4. 第4章:略
  5. 第5章:文件格式,比如 passwd 会说明字段含义
  6. 第6章:游戏相关(留给游戏自己定义)
  7. 第7章:附件/杂项/变量,比如全局变量 environ 会在这里说明
  8. 第8章:系统管理命令(通常只有 root 能用),如 ifconfig
  9. 第9章:略

例子(逐条解释)

man printf
  • 查看 printf 的手册(讲义强调:printf 也有对应的手册页)。
man fork
  • 查看 fork(讲义说:默认没有这个“指令”,man 会自动去 2号手册 查找,即系统调用)。

    这句话你可以这样理解:fork 不是你在 shell 里直接敲的“外部命令”,它更像是 C 里用的系统调用,所以它的主要文档在 man 的第2章。

man 2 fork
  • 指定第2章查看系统调用。
man 3 printf
  • 在 第3章(库函数) 查看 printf。
man 7 signal
man 7 environ
  • 在 第7章 查看变量/杂项相关说明(environ 是讲义点名的例子)。
man man
  • 查看 man 自己的手册。

2.9 cp 指令(复制文件/目录)

语法

cp [选项] 源文件或目录 目标文件或目录

功能

  • 复制文件或目录。

说明

  • cp 用于复制文件或目录。
  • 如果同时指定两个以上的文件/目录,并且最后的目的地是一个已经存在的目录:那么前面指定的所有文件/目录都会被复制到这个目录中。

常用选项(加粗=最常用)

  • -f 或 --force:强行复制,不管目标是否已存在。

目标是文件:cp -f a.txt b.txt

  • b.txt 已存在 → 会被覆盖成 a.txt 的内容

  • b.txt 原来的内容丢失

  • 通常不会提示你,也不会让你确认(这就是 -f 的意义)

如果你不加 -f,很多系统默认也会覆盖;区别在于:

-i 会问你;-f 会“更强硬”:遇到权限/交互限制时也尽量覆盖。

注意:-i与-f一般不能同时用,会冲突 比如-fi或-if 这样子一般取最后一个选项比如-if就被识别为-f

目标是目录:cp -f a.txt dir/

  • 目标是目录 dir/ 已存在 → a.txt 会复制成 dir/a.txt
  • 如果 dir/a.txt 已存在 → 也会被覆盖(不提示)
  • -i 或 --interactive:覆盖前先询问用户。
  • -r:递归处理(复制目录时必须要有它),把目录下文件和子目录一并处理;如果源对象不是目录或符号链接,就按普通文件处理。

例子1:复制普通文件

先创建文件,再复制为备份文件。

echo "你好" > myfile.txt
cat myfile.txt

ll
cp myfile.txt myfile-backup.txt

ll
cat myfile-backup.txt

补充:Linux 下“一切皆文件” + 重定向 > >> <

1)“显示器也是文件”是什么意思?

在 Linux 里,很多东西都抽象成“文件”来读写:

  • 键盘输入 → 进到程序(标准输入 stdin)
  • 程序输出 → 显示到屏幕(标准输出 stdout)
  • 屏幕/终端在系统里对应一个终端设备文件(比如 /dev/tty 或 /dev/pts/*)

所以你 echo "hello world":

  • echo 把字符串写到 stdout
  • stdout 默认连接到你的终端 → 所以你在屏幕上看到它

2)>:输出重定向(覆盖/清空后写入)

echo "hello world" > log.txt

含义:

  • 把本来要输出到屏幕的内容(stdout),改写到文件 log.txt
  • 文件不存在:创建
  • 文件存在:先清空(truncate),再写入(所以叫“覆盖”)

3)>>:追加重定向(在末尾追加)

echo "aaaa" >> log.txt

含义:

  • 不清空文件
  • 在文件末尾继续追加一行

4)<:输入重定向(把文件当“输入”喂给命令)

cat < log.txt

含义:

  • cat 默认从键盘读(stdin)
  • < log.txt 把 stdin 改成来自 log.txt 这个文件
  • 所以 cat < log.txt 会把文件内容打印出来

补一句:cat log.txt 和 cat < log.txt 效果几乎一样,只是后者更能体现“stdin 来自哪儿”的概念。


“指令是什么?就是程序!” + which

你图上写的意思是:你在终端里敲的很多命令,本质是磁盘上的可执行程序文件。

例如:

which top
# /usr/bin/top

which mkdir
# /usr/bin/mkdir

解释:

  • which 会根据你的环境变量 PATH(一串目录列表)
  • 从这些目录里去找名为 top / mkdir 的可执行文件
  • 找到就告诉你它的路径(比如 /usr/bin/mkdir)

一句话:which 用来快速定位“这个命令到底是哪个程序文件在执行”。

which ls / which ll 为什么会显示 alias?

  • ls 可能被设置成别名:alias ls='ls --color=auto'
  • ll 也常见是别名:alias ll='ls -l --color=auto'
  • 真正的程序一般在 /usr/bin/ls

这里要抓住两点:

1)alias(别名)是什么?

别名就是:你输入一个短名字,shell 自动替换成一串更长的命令。

  • ll 不是独立程序,通常只是 ls -l ... 的别名

2)为什么 which 也能看到 alias?

有的系统里 which 会被做成能识别 alias(或者 which 本身是 shell 函数/脚本),所以会把 alias 也打印出来。

更标准、最推荐的查看方式是:

type ls
type ll

你会更清楚地看到它到底是 alias 还是外部程序。

“日志”查看:head + tail + 管道 |

head -2020 log.txt | tail -21

1)head -2020 log.txt

取 log.txt 的前 2020 行输出到 stdout。

2)管道 |

把左边命令的 stdout,直接接到右边命令的 stdin:

  • 左边产出一大段文本
  • 右边拿这段文本继续加工

3)tail -21

从输入里取最后 21 行。

4)组合起来的效果

head -2020 ... | tail -21 的整体含义是:

先取前 2020 行,再从这 2020 行里取最后 21 行
也就是大概在看:第 2000 行到第 2020 行附近(21 行窗口)

这就是看日志时常用技巧:

  • 日志很大,不想打开编辑器
  • 只想快速定位某个行号附近的一小段

例子2:一次复制多个文件到“已存在目录”(并用通配符)

讲义示例:先建目录 dir,再把所有 .txt 结尾的文件复制进去。

mkdir dir
cp *.txt dir      # * 表示通配符,匹配所有 .txt 结尾的文件名
tree dir

这里也对应了上面那条规则:多个源 + 目标是已存在目录 ⇒ 全部复制进目标目录。


例子3:默认会覆盖(不问你)

讲义示例:先把 myfile.txt 内容改掉,再 cp 到 myfile-backup.txt,备份文件内容就被覆盖成新的。

echo "hello" > myfile.txt
cat myfile.txt

cp myfile.txt myfile-backup.txt
cat myfile-backup.txt

例子4:覆盖前询问(-i)

讲义示例:加 -i 后会提示是否覆盖。

cp -i myfile.txt myfile-backup.txt
# cp: overwrite 'myfile-backup.txt'? y

例子5:递归 + 强制复制整个目录(-r + -f)

讲义示例:把目录 test/ 整体复制成 test-backup/。

tree test
cp -rf test test-backup
tree test-backup
  • 这里 -r:递归复制目录
  • -f:目标存在就强制覆盖(不纠结)

2.9 echo指令

在 shell 里输入 echo ...,就是让 shell 去执行一个叫 echo 的“程序/内建命令”,把你给的内容输出出来。1)

echo:把参数原样输出到标准输出(stdout),默认就是输出到屏幕。

例子:

echo hello

输出:

hello

2) echo 最常见的用途:配合重定向写文件

覆盖写(>)

echo "hello world" > log.txt
  • 把本来要打印到屏幕的内容,改写到 log.txt
  • 文件不存在就创建,存在就先清空再写

追加写(>>)

echo "line2" >> log.txt
  • 不清空,在末尾追加一行

  1. echo 的基本语法
echo [选项] [字符串...]

把后面的字符串按空格拼起来输出。

例子:

echo a b c

输出:

a b c

4) 常用选项(你最该记的两个)

-n:不自动换行

默认 echo 会在末尾加一个换行符 \n。

echo -n "hi"

输出后光标不会跳到下一行。

在这里插入图片描述

-e:让转义字符生效(比如 \n 换行、\t 制表)

echo -e "a\nb"

输出:

a
b

5) echo 和变量

name=Tom
echo $name

输出:

Tom
  • $name 表示取变量值
  • 用双引号也常见:echo "hello $name"

和 printf 的对比

  • echo:简单、快,适合随手打印、写小文件、调试
  • printf:更严格、可控(格式化输出),写脚本更稳

例子:

printf "%s\n" "hello"

区分有无引号:

echo "hello world" > log.txt
echo hello world > log.txt

在这里插入图片描述

  • 有引号:那串“多个空格”会被当成内容保留下来
  • 没引号:shell 会把多余空格当作分隔符,传给 echo 的参数会变成两个词,输出通常只剩一个空格
echo "*" > log.txt
echo *   > log.txt
  • "*":写入字面量 *
  • *:会被 shell 展开成当前目录下的一堆文件名,再写进去(完全不同)

在这里插入图片描述

msg="hello    world"
echo "$msg" > log.txt # 即 echo "hello    world"
echo $msg   > log.txt # 即 echo hello    world -> 输出hello world 中间的多余空格被清了

2.10 mv 指令(移动 / 改名)

含义

mv 是 move 的缩写,用来移动文件或给文件改名(move/rename files),也常用于“备份/整理目录”。

语法

mv [选项] 源文件或目录  目标文件或目录

核心规则(取决于“第二个参数”是文件还是目录决定是“改名”还是“移动到目录”)。

当第二个参数是“文件”时:完成重命名

  • 这时“源文件只能有一个”(也可以是源目录名),把源文件/目录改成目标文件名。

当第二个参数是“已存在的目录”时:完成移动到目录

  • 这时“源文件/目录参数可以有多个”,所有源都会被移动到目标目录中。

常用选项(最常用加粗)

  • -f:force 强制。目标文件已存在时,不询问,直接覆盖。
  • -i:interactive。目标文件已存在时,会询问是否覆盖。

推荐先用 -i 养成安全习惯。


例1:改名(重命名)

touch myfile.txt
ll
mv myfile.txt yourfile.txt
ll

效果:myfile.txt 变成 yourfile.txt。


例2:同名覆盖(不加 -i 时可能直接覆盖)

当前路径如果存在同名文件,改名会覆盖。
例子(把 yourfile.txt 改成 myfile.txt,而 myfile.txt 已存在):

touch myfile.txt
ll
mv yourfile.txt myfile.txt
ll

对应现象:原来的 myfile.txt 会被覆盖掉(名字被占用时,mv 用“覆盖式替换”完成重命名)。


例3:覆盖前询问(-i)

讲义:如果当前路径存在同名文件,改名前加 -i 让系统提示你选择。

touch yourfile.txt
ll
mv -i yourfile.txt myfile.txt
# mv: overwrite ‘myfile.txt’? y

例4:移动文件到目录

touch myfile.txt
mkdir temp
ll
mv myfile.txt temp
ls

移动后,当前目录下只剩 temp/,文件进了 temp/。


例5:移动整个目录

mv temp ../
ls -d ../temp

把 temp 移到上级目录


2.11 cat 指令(查看文件内容)

语法

cat [选项] [文件]

功能

  • 查看目标文件的内容。

常用选项

  • -b:对非空行编号,空行不编号。
  • -n:对所有行编号(包括空行)。
  • -s:不输出多行空行(把连续多行空行“压缩”为一行空行)。

例1:命令行构建一个多行文件 temp.txt

讲义用 while 循环把 “hello” 写 0~20 次到 temp.txt:

cnt=0; while [ $cnt -le 20 ]; do echo "hello"; let cnt++; done > temp.txt

例2:基本用法:直接查看文件内容

cat temp.txt

会输出一堆 `hello 行。

例3:cat -b(非空行编号)

cat -b temp.txt

效果:每行前面出现行号。


例4:先用 vim 把文件改成“带多行空行”

先编辑 temp.txt,让它出现多行空行。

vim temp.txt

例5:再测 -b:空行不编号

-b 只给非空行编号;空行不编号。


例6:cat -n(所有行都编号,包括空行)

cat -n temp.txt

空行也会被编号(比如 4、5、6 这些对应空行)。

在这里插入图片描述


例7:cat -s(压缩多行空行)

cat -s temp.txt

效果:连续的多行空行会被压缩成一行空行,不会“刷屏”。

下面把你这几页(more / less / head / tail / date)按“复习笔记”形式一条不漏总结,并把“最常用”的选项加粗。


2.12 more 指令(分页查看,功能类似 cat)

  • 语法:more [选项](实际使用时通常跟文件名,如 more -10 temp.txt)
  • 功能:more 命令功能类似 cat,用于分页显示内容
  • 常用选项:
    • -n:指定输出行数(例如一次显示 10 行)
    • q:退出 more(在 more 界面里按 q 退出)
  • **例子:先造一个 2000 行左右的文件,再分页看
    1. 生成文件:
      cnt=0; while [ $cnt -le 2000 ]; do echo "hello bite"; let cnt++; done > temp.txt
    2. 分页显示 10 行:
      more -10 temp.txt
      输出会出现类似 --More--(0%) 的提示,表示还没看完

2.13 less 指令(更强的分页查看:可前翻、可搜索)

重要特点(对比 more,文档逐条)

  • less 是对文件/输出进行分页显示的工具,被称为 Linux “正统”查看文件内容工具,功能强
  • less 比 more 更灵活:
    • 用 more 时只能往后看,没法往前翻
    • 用 less 可以用 [pageup]/[pagedown] 前后翻页,更容易查看文件
  • less 里搜索更强:可向下搜,也可向上搜

语法与功能

  • 语法:less [参数] 文件
  • 功能:类似 more,但 less 可以随意浏览;more 只能向前移动不能后退;而且 less 在查看前不会加载整个文件

选项/交互

  • -i:忽略搜索时大小写
  • -N:显示每行行号
  • /字符串:向下搜索“字符串”
  • ?字符串:向上搜索“字符串”
  • n:重复上一次搜索(跟 / 或 ? 相关)
  • N:反向重复上一次搜索(跟 / 或 ? 相关)
  • q:退出 less

例子

  • 造文件:cnt=0; while [ $cnt -le 2000 ]; do echo "hello $cnt"; let cnt++; done > temp.txt
  • 带行号查看:less -N temp.txt

2.14 head 指令(看文件开头)

  • 说明:head 和 tail 名字很直观:head 看开头,tail 看结尾
  • 语法:head [参数] [文件]
  • 功能:输出文件开头到标准输出;默认打印开头 10 行
  • 选项:
    • -n <行数>:显示行数
  • 例子(文档原例):
    • head temp.txt(默认 10 行)
    • head -5 temp.txt(显示前 5 行)

2.15 tail 指令(看文件结尾,常用看日志)

  • 核心描述:
    • tail 从指定点开始把文件写到标准输出;
    • -f 选项方便查阅正在改变的日志:tail -f filename 会持续显示文件末尾并刷新,让你看到最新内容
  • 语法:tail 必要参数 [文件]
  • 功能:显示文件末尾内容;不指定文件时,把输入当作内容处理;常用于查看日志
  • **选项:
    • -f:循环读取(跟踪日志更新)
    • -n <行数>:显示行数
  • 例子(文档原例):
    • tail temp.txt(显示末尾若干行)
    • tail -3 temp.txt(显示最后 3 行)

“模拟动态日志查看”怎么理解

“模拟动态日志查看功能” ,你可以这样做(一个窗口写日志,一个窗口跟踪):

  • 窗口A:不断往文件追加内容
    while :; do echo "hello bite"; sleep 1; done >> temp.txt
  • 窗口B:实时查看更新
    tail -f temp.txt

综合:如何显示文件的某一段行号内容(文档例:[180,200])

做法:

  • head -200 temp.txt | tail -20
    它的输出是 hello 180 ... hello 199

怎么看懂这个管道?

  • head -200:先取出“前 200 行”
  • tail -20:再从这 200 行里取“最后 20 行”
  • 所以得到的是:第 181~200 行(如果你的文件第一行算第 1 行)
    但文档里内容是 hello 0 这种从 0 开始编号,所以看起来是 hello 180~199

2.16 date 指令(显示/设置时间 + 时间戳)

  • 指定格式显示时间(文档示例):date +%Y:%m:%d
  • 用法:date [OPTION]... [+FORMAT]

显示格式:常用标记(一个 + 后跟标记)

文档列出的常用标记:

  • %H:小时 (00…23)
  • %M:分钟 (00…59)
  • %S:秒 (00…61)
  • %X:相当于 %H:%M:%S
  • %d:日 (01…31)
  • %m:月份 (01…12)
  • %Y:完整年份 (0000…9999)
  • %F:相当于 %Y-%m-%d

设定时间(重点:需要 root)

只有 root 权限才能设置,其他只能查看

  • date -s:设置当前时间(root 才能设置)
  • date -s 20080523:设置日期为 20080523,时间会变为 00:00:00
  • date -s 01:01:01:只设置具体时间,不改日期
  • 以下都可以设置“完整时间”(文档列了 4 种写法)
    • date -s "01:01:01 2008-05-23"
    • date -s "01:01:01 20080523"
    • date -s "2008-05-23 01:01:01"
    • date -s "20080523 01:01:01"

时间戳(Unix timestamp)

  • 时间 → 时间戳:date +%s
  • 时间戳 → 时间:date -d @1508749502(文档写法)
  • Unix 时间戳定义:从 1970-01-01 (UTC/GMT 午夜) 起经过的秒数,不考虑闰秒

date 例子

  • date:显示常规时间
  • date +%Y/%m/%d:只显示年月日
  • date +%Y/%m/%d-%H:%M:%S:显示到秒
  • date +%s:显示时间戳
  • 时间戳转可视时间:
    • date +%Y/%m/%d-%H:%M:%S -d @0 → 1970/01/01-08:00:00(这里 08:00 是因为时区)
    • date +%Y/%m/%d-%H:%M:%S -d @100000 → 1970/01/02-11:46:40
    • date +%Y/%m/%d-%H:%M:%S -d @1000000000 → 2001/09/09-09:46:40

下面把你这页里的 cal / find / which / whereis / alias / grep 做成“复习笔记式总结”(含语法、功能、常用选项、例子),并把最常用选项加粗。我会按你图里的每个点来,不漏。


2.17 cal 指令

概念

  • cal 用来显示 公历(阳历)日历。公历也叫“格列历”,阳历也叫“太阳历”,按地球绕太阳一圈算一年,因此也叫“西历”。

命令格式

  • cal 参数 [年份]

功能与参数规则

  • 用于查看日历等时间信息:
    • 只有 1 个参数 → 表示年份(1~9999)
    • 有 2 个参数 → 表示“月份 + 年份”

常用选项

  • -3:显示 上个月 / 当前月 / 下个月 的月历
  • -j:显示“今年中的第几天”(从 1 月 1 日开始按天计)
  • -y:显示 当前年份 的全年日历

例子

  • cal:显示当前月
  • cal 1949:显示 1949 年日历
  • cal -3:显示三个月(日历横排)

2.18 find 指令(在目录树里找文件,并可执行操作)

核心特点

  • 在目录结构中搜索文件,并执行指定操作。
  • 查找条件很多,功能强大,选项也很多(很多值得花时间了解)。
  • 即使系统里有网络文件系统(NFS),只要你有权限,find 也一样有效。
  • 很消耗资源:遍历很大的文件系统会很久(比如 30G+),所以很多人会把它放后台执行。

语法

  • find pathname -options

功能

  • 在文件树中查找文件,并作出相应处理(可能访问磁盘)。

常用选项

  • -name:按文件名查找
  • 其它选项需要再查(说明 find 比较复杂)。

例子

  • find ~ -name test.c:在 ~ 下找名为 test.c 的文件,会输出路径列表

2.19 which 指令(找“命令从哪来”的:通常是路径/别名)

功能

  • 搜索系统指定的命令(告诉你它实际会执行哪个)。

例子(能看到 alias + 真正路径)

  • which ls:先显示 ls 的别名(alias),再显示真实可执行文件路径 /usr/bin/ls
  • which pwd:输出 /usr/bin/pwd

记忆点:你在终端敲的“命令名”,可能是 alias,也可能对应 PATH 里的某个可执行文件;which 就是用来查这一点。

find与which的区别:find从系统目录树直接查找,可以查找任意文件;which只能查找系统自带的可执行程序


2.20 whereis 指令(找“程序相关的一整套东西”)

功能

  • 用于找到程序的 源 / 二进制文件 / 手册(man)。

例子

  • whereis ls:能看到 ls 的二进制路径 + man 手册路径
  • whereis libc.so:能看到 libc 的库文件(.so/.a)以及 man7 手册位置

对比:which 更偏“我现在执行的是哪个”;whereis 更偏“这个东西相关文件都在哪”。


2.21 alias 指令(给命令起外号/别名)

功能

  • 设置命令的别名。

例子

  1. alias hello='ls -a -l -n':把 hello 设成一串命令的替身
  2. which hello:会显示它是 alias(并且底层还是 /usr/bin/ls)
  3. hello:实际执行 ls -a -l -n,因此你看到的是 ls 的详细列表输出

2.22 grep 指令(在文件里搜字符串,把匹配行打印出来)

语法

  • grep [选项] 搜寻字符串 文件

功能

  • 在文件中搜索字符串,把找到的行打印出来。

常用选项

  • -i:忽略大小写(大小写视为相同)
  • -n:输出行号
  • -v:反向选择——显示“不包含搜寻字符串”的那些行

例子

文件内容:temp.txt 里有
abcd / ABCD / hello / bite / 1234

基本查找

  • grep "abcd" temp.txt → 输出 abcd

忽略大小写

  • grep -i "abcd" temp.txt → 输出 abcd 和 ABCD

带行号

  • grep -n "abcd" temp.txt → 1:abcd
  • grep -ni "abcd" temp.txt → 1:abcd 与 2:ABCD

反向选择(不含 abcd 的行)

  • grep -v "abcd" temp.txt → 输出 ABCD/hello/bite/1234
  • grep -vn "abcd" temp.txt → 输出它们的行号:2/3/4/5
  • grep -vni "abcd" temp.txt → 结合三选项:忽略大小写 + 反选 + 行号 → 输出 3:hello 4:bite 5:1234

在这里插入图片描述


2.23 top(实时看系统资源/进程)

语法

top -d 1 -n 5

参数含义

  • -d:刷新时间间隔(单位:秒)
    • -d 1 = 每 1 秒刷新一次
  • -n:刷新次数
    • -n 5 = 刷新 5 次后自动退出
  • 在 top 界面里:
    • q:退出

记忆:-d 控制“多久刷一次”,-n 控制“刷几次就停”。


2.24 zip / unzip(zip 格式压缩与解压)

zip 压缩

语法

zip 压缩文件.zip  目录或文件

功能

  • 将目录或文件压缩成 .zip 格式
  • “zip 文件”本质是一个容器格式,里面每个文件都可以选择两种方式之一:
    1. stored:不压缩,原样存
    2. deflated:用压缩算法压缩后存
    3. 不管是哪一种,zip 都会把必要的元信息(文件名、大小、校验等)写进压缩包,所以 unzip 都能按记录把文件取出来。

常用选项

  • -r:递归处理(把指定目录下的所有文件和子目录一起压缩)

截图例子

zip test2.zip test2/*

含义:把 test2/ 目录下的内容打进 test2.zip。

在这里插入图片描述

adding: log.txt

  • 表示:正在把 log.txt 这个文件加入到 log_txt.zip 里。

(stored 0%) 重点

  • stored 的意思:“存储模式”,也就是不压缩,原样放进去(只是打进 zip 容器里)。
  • 0% 的意思:压缩率是 0%(等价于“没有压缩带来体积减少”)。

为什么会出现 stored 0%?

log.txt 太小(只有 2 字节,你 ll 里 Size=2),小文件压缩反而可能得不偿失,所以 zip 直接选择“存储不压缩”。

你这次生成的 log_txt.zip 反而 166 字节,是因为 zip 格式本身需要写头信息/目录结构等“包装开销”,对极小文件来说,包装比内容还大。

在这里插入图片描述

adding: temp.txt

  • 正在把 temp.txt 加入到压缩包 temp_txt.zip 里。

(deflated 15%) 是什么?

  • deflated表示:zip 对这个文件使用了常见的压缩算法 DEFLATE(也就是“真正压缩”了,而不是原样存放)。

  • 15%表示:压缩率/节省比例大约是 15%(文件体积变小了)。

一种常见的理解方式:

  • 原文件大小 = S
  • 压缩后这部分数据大概变成 S × (1 - 15%) = 0.85S

unzip 解压

常见用法

unzip test2.zip -d /tmp
  • -d:指定解压到哪个目录
    • 这里表示解压到 /tmp 目录
  • 不加 -d 时,默认解压到当前目录;压缩包后面跟的东西是“指定要解压哪些文件”,不是“解压到哪”。

2.25 rsz(本质是 lrzsz:Windows ↔ Linux 传文件)

用途

  • 用于 Windows 机器 和 远端 Linux 机器 通过 XShell 传文件
  • 安装后可以通过拖拽等方式上传/下载(常见场景)

安装

sudo yum/apt install -y lrzsz

解释:

  • yum(CentOS系)或 apt(Ubuntu系)安装软件
  • -y:自动确认安装

补充理解:lrzsz 安装后一般会提供 rz / sz(你课件写“关于 rsz”,实际通常就是指这一套 zmodem 工具)。


2.26 tar(打包/解包,可配合 gzip/bzip2 压缩)

核心概念

  • tar 用于 打包/解包
  • “不打开它(不进文件夹)直接看内容/处理内容”(就是可以直接对归档操作)

语法

tar [-cxtzjvf] 文件与目录 ...

参数含义

  • -c:建立一个压缩/打包文件(create)
  • -x:解开一个压缩/打包文件(extract)
  • -t:查看 tarfile 里面有哪些文件
  • -z:是否同时具有 gzip 属性(用 gzip 压缩/解压)
  • -j:是否同时具有 bzip2 属性(用 bzip2 压缩/解压)
  • -v:显示过程中文件(常用,verbose)
  • -f:使用档名(注意:-f 后面必须立刻接“文件名”,不要再插别的参数)
  • -C:解压到指定目录

高频组合记忆:

  • 创建打包:tar -cvf
  • 创建gzip包:tar -zcvf
  • 解压gzip包:tar -zxvf
  • 查看gzip包内容:tar -ztvf
    (带 z 的一般就是 .tar.gz/.tgz)

✅ tar 解压到目录:用 -C

✅ unzip 解压到目录:用 -d

tar -zcvf out.tgz src

仅打包,不压缩(.tar)

tar -cvf /tmp/etc.tar /etc

打包后用 gzip 压缩(.tar.gz 或 .tgz)

tar -zcvf /tmp/etc.tar.gz /etc

打包后用 bzip2 压缩(.tar.bz2)

tar -jcvf /tmp/etc.tar.bz2 /etc

扩展名习惯

  • 默认用 .tar 表示纯打包
  • 加 -z 常用 .tar.gz 或 .tgz
  • 加 -j 常用 .tar.bz2

执行时可能出现的警告

  • 可能看到:
    • tar: Removing leading '/' from member names
  • 含义:你打包的是绝对路径(比如 /etc),tar 为了安全会把成员名里的开头 / 去掉,避免解压时“强行覆盖系统根目录”。

查看压缩包里有什么

如果是 gzip 压缩的包(.tar.gz),查看内容要带 -z:

tar -ztvf /tmp/etc.tar.gz

记住:压缩格式是什么就要配什么参数:gzip→-z,bzip2→-j。


把包解到 /usr/local/src

先切目录再解包:

cd /usr/local/src
tar -zxvf /tmp/etc.tar.gz

结果:会在 /usr/local/src/ 下解出一个 etc/ 目录(即 /usr/local/src/etc)

截图还提醒:如果你直接进入 /usr/local/src/etc 会发现属性可能和系统 /etc 不同(位置不同了)。


只解出其中一个文件 etc/passwd

cd /tmp
tar -zxvf /tmp/etc.tar.gz etc/passwd

要点:

  • 先用 tar -ztvf 可以查到包里有哪些路径名
  • 只想要一个文件,就在解压命令后面写出它的路径
  • 注意:包里的路径通常是 etc/passwd(根目录 / 开头会被去掉)

备份 /etc 并保留权限

tar -zxvpf /tmp/etc.tar.gz etc

关键点:

  • -p:保留原本权限/属性(截图写“这个 -p 很重要,尤其想保留原文件属性时”)

只备份 /home 中比某日期新的文件

tar -N "2005/06/01" -zcvf home.tar.gz /home
  • -N "日期":只打包“比该日期更新(新的)”的文件

备份 /home 和 /etc,但排除某路径

tar --exclude /home/dmtsai -zcvf myfile.tar.gz /home/* /etc
  • --exclude 路径:排除不想打包的目录/文件

打包后直接解开到 /tmp,不产生中间文件

cd /tmp
tar -cvf - /etc | tar -xvf -

重点:

  • 第一个 tar -cvf - /etc:- 表示把打包内容输出到 stdout(标准输出)
  • 管道 |:把 stdout 接到下一个命令的 stdin
  • 第二个 tar -xvf -:- 表示从 stdin(标准输入) 读入并解包
  • 效果:像“把 /etc 复制到 /tmp”一样,但走的是 tar 流式传输

最终速记

  • top -d 秒 -n 次,退出按 q
  • zip -r a.zip dir,unzip a.zip -d 目录
  • lrzsz:Windows↔Linux 传文件(XShell 常用),安装 sudo yum/apt install -y lrzsz
  • tar 三板斧:
    • 打包:tar -cvf a.tar dir
    • 打包+gzip:tar -zcvf a.tar.gz dir
    • 解压gzip:tar -zxvf a.tar.gz
    • 查看gzip内容:tar -ztvf a.tar.gz
  • tar -zxvf xxx.tgz -C /tmp/test

2.27 uname

uname 用来查看内核(Kernel)和机器硬件架构相关信息。
它回答的更像是:“这台机器跑的是什么内核?什么架构?”
(注意:它不是主要用来查“Ubuntu/CentOS版本号”的,那是发行版信息。)

uname -r:只看“内核版本号(release)”

  • -r 输出的是 Kernel Release,例如:
    • 5.15.0-xx-generic
    • 3.10.0-957.el7.x86_64

你可以理解为:Linux 内核的版本线(跟系统发行版 Ubuntu/CentOS 不完全是一回事)。

✅ 例子:

root@aliyun:~/lesson1# uname -r
6.8.0-63-generic

uname -a:一次把“全部信息”都吐出来

截图里写的 -a(或 --all)会详细输出所有信息,一般包含这些字段(顺序可能略有不同):

  • 内核名称(Kernel name,通常 Linux)
  • 主机名(nodename)
  • 内核版本号(release,对应 -r)
  • 内核版本/编译信息(version)
  • 机器硬件架构(machine,如 x86_64 / aarch64)
  • 处理器类型/硬件平台类型/操作系统名(不同系统显示可能不同)

例子:

root@aliyun:~/lesson1# uname -a
Linux aliyun 6.8.0-63-generic #66-Ubuntu SMP PREEMPT_DYNAMIC Fri Jun 13 20:25:30 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

uname -a、uname -r 的区别:

  • -r 只看“内核版本号”
  • -a 看“全部信息”

3. 快捷键:Tab / Ctrl+C / Ctrl+D

(1) Tab:命令补全 + 路径补全

  • 你打命令打到一半按 Tab,shell 会尝试帮你补全:
    • 命令名补全:unzi + Tab → 可能补成 unzip
    • 路径补全:cd /ho + Tab → 可能补成 /home/
  • 如果有多个候选,再按一次 Tab,可能会列出所有候选,让你选。

✅ 例子:

cd /ho<Tab>
unzi<Tab>

(2) Ctrl + C:中断当前正在运行的前台程序(停止)

  • 含义:给正在运行的程序发一个“中断”信号(常见是 SIGINT)
  • 作用:让当前命令立刻停下来,回到命令提示符
  • 不会关掉终端,只是停掉当前命令

✅ 例子:

ping 8.8.8.8
# 想停掉 ping,就按 Ctrl+C

(3) Ctrl + D:EOF(输入结束);在 shell 里常等于退出

  • 含义:发送 EOF(End Of File / End Of Input)——“我不再输入了”
  • 场景 A:在一些程序里代表“输入结束”
  • 场景 B:在 shell 命令行里,如果你在空命令行按 Ctrl+D,通常会 退出当前 shell / 断开 ssh

✅ 例子 1(输入结束):

cat
hello
# 按 Ctrl+D 结束输入,cat 才会退出

✅ 例子 2(退出 shell/ssh,慎用):

  • 你在 ssh 里空着按 Ctrl+D,可能直接断开连接(相当于 exit)

对比记住:

  • Ctrl+C:强行打断正在跑的命令
  • Ctrl+D:告诉程序“没输入了”;在 shell 里常导致退出
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐