Linux 基础常用指令万字详解(下)|一切皆文件:重定向、管道、日志 与 Shell 原理

目录

引言:

重要的几个热键

[Tab 按键------命令补全与搜索](#[Tab] 按键——命令补全与搜索)

[Ctrl-c 按键------终止异常任务](#[Ctrl]-c 按键——终止异常任务)

上下键------查看历史命令

[Ctrl-r 按键------搜索历史命令](#[Ctrl]-r 按键——搜索历史命令)

[Ctrl-d 按键------退出登录](#[Ctrl]-d 按键——退出登录)

Shell命令以及运行原理

命令行长什么样?

命令行是谁提供的?

[为什么要多一层 Shell?](#为什么要多一层 Shell?)

类比:王婆说媒

[Shell vs Bash](#Shell vs Bash)

[第一次理解 Shell:感性认识](#第一次理解 Shell:感性认识)

[拓展:安卓也是 Shell?](#拓展:安卓也是 Shell?)

echo与printf指令

一:Linux理论知识:一切皆文件

[一:Linux 的核心理念:一切皆文件](#一:Linux 的核心理念:一切皆文件)

1.1:标准输入输出本质上是文件操作

[从 C/C++ 的视角理解](#从 C/C++ 的视角理解)

1.2:为什么不用手动"打开"这些文件

三个默认打开的文件流

[为什么之前没见过 stdin/stdout?](#为什么之前没见过 stdin/stdout?)

如何理解"系统帮我们打开"?

系统为什么要默认打开?

为什么不把其他文件也默认打开?

1.3:小结

二:重定向操作

[2.1.输出重定向 >](#2.1.输出重定向 >)

[2.2.追加重定向 >>](#2.2.追加重定向 >>)

[2.3.输入重定向 <](#2.3.输入重定向 <)

[2.4.重定向与 C 语言文件操作的联系](#2.4.重定向与 C 语言文件操作的联系)

三.重新回归"一切皆文件"------终端也是文件

用命令验证

[用 C 代码验证](#用 C 代码验证)

[四:Linux 文件类型详解](#四:Linux 文件类型详解)

[4.1 已见过的文件类型](#4.1 已见过的文件类型)

[4.2 其他文件类型(拓展)](#4.2 其他文件类型(拓展))

[4.3. Linux 不以文件后缀作为区分文件类型](#4.3. Linux 不以文件后缀作为区分文件类型)

mv指令(重要)

二:Linux理论知识:日志

什么是系统日志?

为什么要有日志?

[Linux 与 Windows 都有日志](#Linux 与 Windows 都有日志)

查日志是程序员的日常

文本查看指令

cat指令

tac指令

more指令

less指令(推荐)

head指令

tail指令

三:Linux理论知识:管道

时间与查找指令

date指令

cal指令

which指令

whereis指令

find指令(重要)

grep指令

四:Linux理论知识:打包和压缩

[1. 打包压缩是什么?](#1. 打包压缩是什么?)

[2. 为什么要进行打包压缩?](#2. 为什么要进行打包压缩?)

打包压缩指令

zip/unzip指令(重要)

rz/sz指令(Linux与Windows互传文件)

安装

[Linux → Windows:使用 sz](#Linux → Windows:使用 sz)

[Windows → Linux:使用 rz](#Windows → Linux:使用 rz)

快捷方式:拖拽上传

tar指令(重要)

[1. tar 与 zip 的区别](#1. tar 与 zip 的区别)

[2. tar 的基本使用](#2. tar 的基本使用)

常用选项

打包压缩

解压解包

显示详细过程

解压到指定目录

解压到指定目录

[一个小细节:选项前的 - 号](#一个小细节:选项前的 - 号)

总结

Linux与Linux互传文件

bc指令

uname指令

关机

以下命令为拓展命令

结语:


引言:

Linux 指令是后端开发、运维工程师的必备基本功。不同于 Windows 的图形化操作,Linux 通过命令行与系统交互,高效且强大。本文从"一切皆文件"的核心理念出发,系统讲解重定向、管道、打包压缩等核心概念,并覆盖文件操作、文本处理、系统管理等常用指令。内容兼顾原理与实战,适合初学者建立完整的 Linux 指令知识体系。

接下来进入正文------------>


重要的几个热键

Tab 按键------命令补全与搜索

Tab 键具有命令补全命令搜索的功能。

wh 为例,如果你忘了指令怎么拼,双击 Tab 键 ,系统会把以 wh 开头的所有指令列出来:

cpp 复制代码
[root@VM-0-2-centos ~]# wh
whatis    whereis   which     while     whiptail  who       whoami   

如果只匹配到一个指令,它会自动补全该指令,不用你手动敲完。


Ctrl-c 按键------终止异常任务

程序卡住或异常时,按 Ctrl+c 可以强制终止当前任务。


上下键------查看历史命令

上键 可以调出之前执行过的命令,方便复用。


Ctrl-r 按键------搜索历史命令

给一个片段,它会找到对应的命令。此时回车就会运行找到的命令。


Ctrl-d 按键------退出登录

Ctrl+d 代表键盘输入结束 (End Of File, EOF 或 End Of Input),可以用来退出当前登录,但不关闭终端窗口。功能上等同于输入 exit


Shell命令以及运行原理

命令行长什么样?

复制代码
[root@VM-0-2-centos ~]# 

这串输出包含几个部分:

部分 含义
root 当前用户名
VM-0-2-centos 主机名(可用 hostname 修改)
~ 当前所在目录
# 提示符,用来分隔系统信息和你输入的内容

提示符分两种:# 代表超级用户(root),$ 代表普通用户。

我们在命令行上输入的 pwdll /root 等,统称为用户命令


命令行是谁提供的?

这个能输入命令的界面,不是操作系统内核直接提供的 ,而是一个叫**外壳程序(Shell)**的软件层提供的。

狭义上理解:

  • 操作系统内核(Kernel) = 真正干活的
  • 外壳程序(Shell) = 包在内核外面的一层软件,负责读取命令、识别命令

流程如下:

复制代码
用户输入命令(字符串)
    ↓
Shell(外壳程序)接收并解析
    ↓
交给操作系统内核执行
    ↓
内核返回结果
    ↓
Shell 把结果翻译给用户

为什么要多一层 Shell?

  1. 方便用户操作------用户不擅长直接跟内核打交道
  2. 保护内核------如果输入了非法指令(如不存在的命令),Shell 会直接拦截,避免内核崩溃
  3. 稳定性 ------Shell 本身不能挂,挂了就要重新登录。所以 Shell 执行新命令时,会创建子进程去执行,子进程挂了不影响 Shell 本身

类比:王婆说媒

你是个闷骚害羞的程序员,看上了村头漂亮的 MM 小花(操作系统内核),但不好意思直接表白。

于是你找了媒婆 (Shell)帮忙传话。这个媒婆姓王,叫王婆 ------对应我们常用的 Bash

所有事情你跟王婆沟通,由她转达给小花。王婆要是自己亲自去跑腿,万一搞砸了名声就坏了,所以她招实习生(子进程)去干,自己稳坐中军。


Shell vs Bash

概念 说明
Shell 所有外壳程序的统称(媒婆这个行业)
Bash Linux 下具体的 Shell 实现,最常用的一个(王婆这个人)

每次登录成功,系统会启动一个 Bash 进程。它内部是个死循环,不断进行命令行解释、分析和执行。


第一次理解 Shell:感性认识

只要记住下面这张图:

复制代码
用户 ←→ Shell(Bash) ←→ 内核(Kernel)
  • 用户只跟 Shell 打交道
  • Shell 负责翻译命令给内核
  • 内核执行完,Shell 再把结果翻译回来

这个外壳程序我会讲三次:第一次在这里(感性认识),第二次在进程部分,第三次在自己实现 Shell 的时候。逐步加深理解。


拓展:安卓也是 Shell?

安卓的底层是 Linux 内核,那安卓本身是什么?

安卓就是包裹在 Linux 内核外部的一层 Shell ------只不过它不是命令行,而是图形化界面。这套界面形成了一套自己的操作方法,打包成库后,就可以让你做安卓开发了。

所以:

  • Linux 上 = 命令行 Shell(Bash)
  • Windows 上 = 图形化 Shell(GUI)
  • 安卓上 = 图形化 Shell(Android 系统)

外壳程序的本质是一样的:让用户更方便地操作内核。


echo与printf指令

echo 指令的作用很简单:把后面的内容原样输出到屏幕上(内容需要用 ' ' 或 " " 包起来)。用法如下:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# echo 'hello linux'
hello linux

注意:echo 打印字符串时默认会在末尾加上换行符。

printf 的用法和 C 语言基本一致,支持格式化输出:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# printf "hello %d,hello %s,hello %f\n" 100 "linux" 0.721000
hello 100,hello linux,hello 0.721000

如果只是想单纯地在显示器上回显一个字符串,echoprintf 都能胜任。


一:Linux理论知识:一切皆文件

一:Linux 的核心理念:一切皆文件

在Linux系统中,一切皆文件

除了常见的 .c.cpp.txt 这类普通文件外,键盘、鼠标、显示器、磁盘、网卡等硬件设备,在 Linux 的系统层面也被抽象成了文件(具体细节等讲到文件系统时再展开)。

基于这个理念,我们可以推导出一个重要结论------标准输入输出本质上是文件操作

1.1:标准输入输出本质上是文件操作

我们平时最常用的输入输出方式有两种:一是自己创建的文件,二是系统默认提供的设备文件 。其中最重要的是三个:键盘显示器显示器

这里需要解释一下:后两个"显示器"并不是同一个东西,它们分别对应标准输出(stdout)和标准错误(stderr),后面会详细区分。

从 C/C++ 的视角理解

学 C/C++ 时,我们用 cin/coutscanf/printf 进行输入输出。以 printf/cout 为例,它们的本质是把数据输出到显示器;而显示器在 Linux 中就是一个文件。因此,printf/cout 的本质其实就是文件操作

之前我们常说"从标准输入流读取数据""向标准输出流输出数据",这是站在语言层面 的理解,没错,但不够深入。在"一切皆文件"的指导下,我们应该认识到:printf/scanfcout/cin 本质上都是在操作文件。

1.2:为什么不用手动"打开"这些文件

任何文件在被访问前都需要先打开。比如 C 语言中访问 test.txt,要先 fopen;C++ 中要用 fstream 打开文件流。那么,键盘和显示器作为文件,被访问前自然也需要打开

但问题来了:我们之前写 C/C++ 代码时,并没有手动打开键盘或显示器的文件,为什么 printf/scanfcin/cout 能直接用?

答案是:系统在启动程序时,已经默认帮我们打开了这三个设备文件。

三个默认打开的文件流

那么我就以C语言为例来进行解释

在系统当中,会有三个设备文件会在程序启动的时候默认被打开,我们可以通过man指令来查看,打开的分别是这三个

cpp 复制代码
#include <stdio.h>

extern FILE *stdin;   // 标准输入流 ------ 对应键盘
extern FILE *stdout;  // 标准输出流 ------ 对应显示器
extern FILE *stderr;  // 标准错误流 ------ 对应显示器(另一个)

这三个默认对应的就是三个硬件

  • stdin 对应键盘(标准输入)

  • stdoutstderr 都对应显示器(标准输出和标准错误),暂时先不做区分

这三个被打开的文件最终会以我们对应的FILE*的形式来给我们呈现出来,程序就可以通过它们自动访问对应的设备文件。

为什么之前没见过 stdin/stdout

因为 printfscanf 在内部已经帮我们封装好了。C 语言还提供了 fprintffscanf,它们的第一个参数就是文件流。当我们把文件流显式指定为 stdoutstdin 时,效果就和 printf/scanf 完全一致:

cpp 复制代码
       int printf(const char *format, ...);
       int fprintf(FILE *stream, const char *format, ...);
如何理解"系统帮我们打开"?

代码写完后,还要经过编译、链接,最后由操作系统加载运行。程序最终跑起来的时候,操作系统完全有能力在幕后做一些准备工作------其中就包括默认打开三个设备文件(等后面学了进程管理,你会理解得更透彻)。

可以这么简单地理解:我们写的代码从 main 函数开始执行,这是用户代码 的入口;但操作系统在加载程序时,会在 main 函数之前插入一段初始化代码,帮我们完成打开标准输入输出文件等工作。所以当我们调用 printf/scanf 时,这些文件已经是打开好的状态了。

系统为什么要默认打开?

原因很简单:我们写程序,无非是把数据交给程序运算,再把结果展示出来。系统默认打开这三个文件,是为了让用户在不做任何额外配置的情况下,就能直接输入和输出------这是为了方便使用。如果系统不打开,每次写程序都得自己先打开键盘和显示器,那就太繁琐了。

为什么不把其他文件也默认打开?

因为这三个文件已经覆盖了绝大多数程序的基本需求:输入数据、输出结果、输出错误信息。其他文件如果有需要,程序员自己打开即可。

1.3:小结

  • Linux 下一切皆文件:键盘、显示器等硬件也被抽象为设备文件。

  • 标准 IO 本质是文件操作printf/scanfcout/cin 底层都是在读写文件。

  • 系统默认打开三个文件stdin(键盘)、stdout(显示器)、stderr(显示器),程序启动后即可直接使用。

  • 为什么能直接用 :系统在 main 函数之前完成了初始化,帮我们把这三个设备文件打开了。


二:重定向操作

2.1.输出重定向 >

先看这条命令:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# echo 'hello linux'
hello linux

echo 默认把字符串写到了显示器文件里,所以我们能在屏幕上看到输出。

现在,我们可以用 > 把它重定向到别的文件里:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# echo 'hello linux' > hello.txt
[root@VM-0-2-centos 2026_8_26]#

加了 > 之后,本来应该写到显示器的内容,不再往显示器里写了,而是写入了 hello.txt。如果该文件不存在,系统会新建它。所以显示器上没有看到这个hello linux。

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# ll
total 8
-rw-r--r-- 1 root root 12 Aug 26 12:16 hello.txt
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello linux

这种把本来写入显示器的内容转向指定文件的操作,叫做输出重定向

再做一次输出重定向(> 左右加不加空格都可以):

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# echo 'hello qiu' > hello.txt
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello qiu

可以看到,原来的内容被替换掉了。

由此可以总结出输出重定向 > 的两个特点:

  1. 目标文件不存在时,自动新建

  2. 写入前先清空原有内容

基于这两个特点,> 还有两个实用技巧:

技巧一:用 > 快速新建空文件

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# touch 1.txt
[root@VM-0-2-centos 2026_8_26]# >2.txt
[root@VM-0-2-centos 2026_8_26]# ll
total 8
-rw-r--r-- 1 root root  0 Aug 26 12:37 1.txt
-rw-r--r-- 1 root root  0 Aug 26 12:37 2.txt
-rw-r--r-- 1 root root 10 Aug 26 12:32 hello.txt
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c

> 2.txt 的效果和 touch 2.txt 一样,都是创建一个空文件。

技巧二:用 > 清空已有文件

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello qiu
[root@VM-0-2-centos 2026_8_26]# >hello.txt
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
[root@VM-0-2-centos 2026_8_26]# ll
total 4
-rw-r--r-- 1 root root  0 Aug 26 12:37 1.txt
-rw-r--r-- 1 root root  0 Aug 26 12:37 2.txt
-rw-r--r-- 1 root root  0 Aug 26 12:42 hello.txt
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c

> hello.txt 就是把 hello.txt 清空,但不写入任何新内容。


2.2.追加重定向 >>

如果不想每次写入都先清空,而是在原有内容后面追加 ,可以用 >>

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# echo 'hello linux' > hello.txt
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello linux
[root@VM-0-2-centos 2026_8_26]# echo 'hello qiu' >> hello.txt
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello linux
hello qiu

我们把这种重定向叫做追加重定向


2.3.输入重定向 <

先来看 cat 命令的一个特性。正常情况下,cat 后面接文件名,会显示文件内容:

bash 复制代码
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello linux
hello qiu

但如果不接文件名,直接回车:

bash 复制代码
[root@VM-0-2-centos 2026_8_26]# cat

命令行会阻塞在这里,等待输入。此时你输入什么,它就回显什么:

bash 复制代码
aa        # 输入 aa
aa        # 回显 aa
bb
bb

这是因为 cat 默认从键盘文件stdin)读取内容,然后把读到的内容写回显示器文件stdout)。

现在来看 < 的用法。下面的两条命令,效果看起来一样:

bash 复制代码
[root@VM-0-2-centos 2026_8_26]# cat hello.txt
hello linux
hello qiu
[root@VM-0-2-centos 2026_8_26]# cat < hello.txt
hello linux
hello qiu

但它们的本质是不同的:

  • cat hello.txtcat命令行参数 获取文件名(也就是 main 函数的 argcargv),然后在程序内部自己打开这个文件。

  • cat < hello.txt:Shell 先把 hello.txt 打开,然后把 cat标准输入 从键盘重定向到这个文件。cat 以为自己还是从 stdin 读数据,只不过此时的 stdin 已经被换成了 hello.txt

这种把标准输入从键盘转向指定文件的操作,叫做输入重定向

简单说:以前没有输入重定向时,程序从键盘文件里读;现在做了输入重定向,程序就从指定的磁盘文件里读。

这两种方式的区别,现在了解即可。深入理解需要等到后面学习进程命令行参数应用层通信时才能完全讲透。


2.4.重定向与 C 语言文件操作的联系

至此,三个重定向操作也讲解完了

总结一下,以C语言为例

Shell 在执行重定向时,会先把目标文件打开。这个打开文件的策略 ,和 C 语言的 fopen 模式是一一对应的:

重定向符号 C 语言模式 打开策略
> "w"(write) 写入,文件不存在则新建,存在则先清空
>> "a"(append) 追加,每次写入都添加到文件末尾
< "r"(read) 只读,从文件开头读取

但这只是第一步。打开文件之后,Shell 还会做一件更关键的事------把标准输入/输出的流向切到这个文件上 (底层通过 dup2 实现)。所以:

  • 打开文件的策略 → 和 C 语言的 w/a/r 一致

  • 重定向的核心 → 改变标准 IO 的流向

如果你已经学过 C 语言的文件 IO,会发现 Linux 的重定向并不是什么全新的概念。>>>< 这些符号,本质上就是你熟悉的 fopen 模式在命令行层面的封装和延伸。

三.重新回归"一切皆文件"------终端也是文件

前面两点讲完后,我们重新来谈:什么叫"一切皆文件"?

用命令验证

其实,我们现在用的 Xshell 终端,在 Linux 里也是文件------具体来说是字符设备文件 (以 c 开头),位于 /dev/pts 目录下:

cpp 复制代码
[root@VM-0-2-centos ~]# ll /dev/pts
total 0
crw--w---- 1 root tty  136, 0 Aug 26 15:57 0
crw--w---- 1 root tty  136, 1 Aug 26 16:00 1
crw--w---- 1 root tty  136, 2 Aug 26 15:20 2
c--------- 1 root root   5, 2 Jul 30 16:11 ptmx

这里的 0 就是我们当前终端对应的设备文件名。如果同时开多个终端,文件名会按 1234 递增:

我们也可以通过重定向来验证"终端是文件"这个概念。比如在 0 号终端执行:

cpp 复制代码
[root@VM-0-2-centos ~]# echo '我是0号终端' > /dev/pts/0
[root@VM-0-2-centos ~]# echo '我是1号终端' > /dev/pts/1
[root@VM-0-2-centos ~]# echo '我是2号终端' > /dev/pts/2

甚至,如果你想在 0 号终端执行 tree,但把结果显示在 1 号终端的屏幕上,也可以这样做:

cpp 复制代码
[root@VM-0-2-centos ~]# tree > /dev/pts/1

这也解释了为什么 echols 这类指令默认会显示在我们当前终端上------因为系统默认的输出路径就是当前终端对应的字符设备文件。新建终端时会自动生成对应的字符文件,之后输出内容直接写入该文件即可。

所以,系统默认帮我们打开的 stdinstdout,本质上就是打开了对应的字符设备文件,程序就可以从键盘读取、向显示器写入了。

终端也是文件,一切皆文件。

用 C 代码验证

对于代码而言,同样可以操作终端设备文件。下面这段代码默认会把内容输出到当前终端:

cpp 复制代码
#include <stdio.h>

int main()
{
    int	cnt = 10;
    while(cnt--) 
    {
        printf("%d\n",cnt);
       	sleep(1);
    }
    return 0;
}

如果想让输出显示在 1 号终端上,只需要把 stdout 改成指向 /dev/pts/1

cpp 复制代码
#include <stdio.h>

const char *dev = "/dev/pts/1";

int main()
{
    int	cnt = 10;
    FILE *fp = fopen(dev,"w");
    if(fp==NULL)
    {
       	printf("open error\n");
        return 1;
    }
    while(cnt--) 
    {
        fprintf(fp,"%d\n",cnt);
       	sleep(1);
    }
    fclose(fp);
    return 0;
}

现在我们 就有一个简单的C语言文件了

编译运行后,输出就会出现在 1 号终端上:

所以,终端也是文件。Linux 系统把所有东西都抽象成了文件,未来在 Linux 里做的很多操作,最终都会转化为对文件的操作。

进一步想:如果连网络设备也是文件,那么未来对网络进行读写时,在用户看来不需要学习新的接口,直接通过文件操作就可以向网络里写数据。这就是 Linux 设计"一切皆文件"的初衷------统一接口,方便操作


四:Linux 文件类型详解

Linux 基础常用指令万字详解(上)|文件目录命令,结合底层原理剖析-CSDN博客我们已经讲了如何看文件类型,这里做进一步补充。

4.1 已见过的文件类型

目前我们见过的文件类型包括以下三种:

表格

类型标识 名称 说明 典型代表
- 普通文件 存放数据、代码、配置等 .txt、可执行程序、库、图片、视频
d 目录文件 存放文件名和 inode 的映射关系 文件夹
c 字符设备文件 按字符顺序读写 键盘、显示器、终端

字符设备文件c 开头)的典型代表就是键盘、显示器和终端。字符设备的特点是按顺序读写 ,输入的字符具有顺序性


4.2 其他文件类型(拓展)

除此之外,Linux 还有以下几种文件类型,这里先做简单了解:

表格

类型标识 名称 说明 典型代表
b 块设备文件 支持随机读写 磁盘
l 链接文件 指向另一个文件 软链接、硬链接(类似 Windows 快捷方式)
p 管道文件 进程间通信 mkfifo 创建的文件
s 套接字文件 网络通信 网络编程时遇到

块设备文件b 开头)的典型代表是磁盘,一般存在于 /dev/vda 目录下:

cpp 复制代码
[root@VM-0-2-centos ~]# ls /dev/vda
/dev/vda
[root@VM-0-2-centos ~]# ls /dev/vda*
/dev/vda  /dev/vda1

/dev/vda 就是一块物理磁盘。一般配置较低的云服务器只有一块磁盘,就像 Windows 电脑虽然能看到 C、D、E、F 盘,但实际上只有一块物理硬盘,只是分了几个区。Linux 同理,/dev/vda1 就是 /dev/vda 的一个分区。

ll 查看,它们是以 b 开头的块设备文件:

cpp 复制代码
[root@VM-0-2-centos ~]# ll /dev/vda*
brw-rw---- 1 root disk 253, 0 Jul 30 16:12 /dev/vda
brw-rw---- 1 root disk 253, 1 Jul 30 16:12 /dev/vda1

块设备支持随机读写。那么,既然 Linux 下一切皆文件,我们能直接打开磁盘文件往里面写东西吗?

绝对不行。 打开磁盘文件直接写入,类似于在 Windows 下直接对物理硬盘操作------你不知道数据写到了哪里,很可能把系统文件、分区表等重要数据覆盖掉。相当于绕过了文件系统,直接对物理硬件操作,一旦出错系统就可能崩溃。虽然它也是文件,也能打开,但不能这么操作

链接文件l 开头)分为软链接和硬链接,很像 Windows 的快捷方式。Windows的那个快捷方式其实也是一种链接文件

管道文件p 开头)用于进程间通信,在系统里比较少见,可以用 mkfifo 手动创建:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# mkfifo gd
[root@VM-0-2-centos 2026_8_26]# ll
total 8
-rw-r--r-- 1 root root  0 Aug 26 12:37 1.txt
-rw-r--r-- 1 root root  0 Aug 26 12:37 2.txt
prw-r--r-- 1 root root  0 Aug 26 16:28 gd
-rw-r--r-- 1 root root 23 Aug 26 12:45 hello.txt
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c

套接字文件s 开头)用于网络通信,等讲到网络编程时再说。


4.3. Linux 不以文件后缀作为区分文件类型

重点:Linux 不以文件的后缀来区分文件类型。

普通文件包含很多种类------文本、可执行程序、库、图片、视频,在 Linux 眼里它们都是普通文件(- 开头)。这跟 Windows 差别很大。

我们来验证一下。之前写入 1 号终端的 C 程序,因为 1 号终端已关闭,所以会显示打开失败:

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# ls /dev/pts
0  ptmx
[root@VM-0-2-centos 2026_8_26]# cd ~
[root@VM-0-2-centos ~]# ./test
open error

现在把可执行程序改个名字(改成 .txt 后缀),发现仍然可以运行:

cpp 复制代码
[root@VM-0-2-centos ~]# mv test test.txt
[root@VM-0-2-centos ~]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug 26 16:28 2026_8_26
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
-rwxr-xr-x 1 root root 8600 Aug 26 15:46 test.txt
[root@VM-0-2-centos ~]# ./test.txt
open error

可见,在 Linux 下,可执行程序的运行与文件后缀没有任何关系

但这里要注意区分:系统不关心后缀,不代表工具不关心。

比如,我们把源代码 test.c 的后缀改成 .txt,内容不变,但 gcc 就无法编译了:

cpp 复制代码
[root@VM-0-2-centos ~]# mv test.c test.txt
mv: overwrite 'test.txt'? y
[root@VM-0-2-centos ~]# gcc test.txt -o test
test.txt: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

报错说得很清楚:文件格式无法识别,gcc 不认识 test.txt

改回 .c 后缀,又能正常编译了:

cpp 复制代码
[root@VM-0-2-centos ~]# mv test.txt test.c
[root@VM-0-2-centos ~]# gcc test.c -o test

这看起来矛盾:不是说 Linux 不看后缀吗?为什么 gcc 只认 .c

原因在于:系统不关心后缀,不代表应用程序不关心。 Linux 系统本身通过 ls -l 第一列来判断文件类型,但 gcc 作为编译器,需要根据后缀来决定调用哪个编译前端(C 编译器还是其他)。所以:

  • Linux 系统:不依赖后缀区分文件类型,你想用就用,不想用就不用。

  • 具体工具 (如 gcc):可能会根据后缀做不同的处理。

对于文件类型,系统只看 ls -l 第一列的标识。所以文件名该怎么写就怎么写,只是系统不会把后缀名当作文件类型判断的依据。

Linux 中的文件类型其实很少,最常见的就是 -(普通文件)。普通文件内部还可以细分很多种类,但在 Linux 眼里,它们统统都是普通文件。至于系统是如何做到这一点的,现在理解还早,等后面学到文件系统就明白了。

Linux理论知识先到这里,接下来我们回到指令


mv指令(重要)

mv 是 move 的缩写,可以用来移动文件 或者重命名文件,功能类似于 Windows 中的"剪切"。

语法:

cpp 复制代码
mv [选项] 源文件或目录 目标文件或目录

在 Linux 中,由于"一切皆文件",这里不需要刻意区分源和目标到底是文件还是目录,统一按文件处理即可。

功能:

  1. mv 命令中第二个参数类型的不同(是目标文件还是目标目录),mv 命令将文件重命名或将其移至一个新的目录中。

  2. 当第二个参数类型是普通文件 时,mv 命令完成文件重命名。此时,源文件只能有一个(也可以是源目录名),它将所给的源文件或目录重命名为给定的目标文件名。

  3. 当第二个参数是已存在的目录名称 时,源文件或目录参数可以有多个,mv 命令将各参数指定的源文件均移至目标目录中。------即移动(剪切)。如果目录名不存在,那依旧是重命名。

常用选项:

  • -f:force,强制的意思。如果目标文件已经存在,不会询问而直接覆盖。

  • -i:若目标文件已经存在时,就会询问是否覆盖。

移动普通文件

cpp 复制代码
[root@VM-0-2-centos 2026_8_26]# mv hello.txt ..
[root@VM-0-2-centos 2026_8_26]# ll ..
total 24
drwxr-xr-x 2 root root 4096 Aug 27 09:16 2026_8_26
-rw-r--r-- 1 root root   23 Aug 26 12:45 hello.txt
-rwxr-xr-x 1 root root 8600 Aug 26 16:49 test
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
[root@VM-0-2-centos 2026_8_26]# ll
total 4
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c
[root@VM-0-2-centos 2026_8_26]# mv ../hello.txt .
[root@VM-0-2-centos 2026_8_26]# ll
total 8
-rw-r--r-- 1 root root 23 Aug 26 12:45 hello.txt
-rw-r--r-- 1 root root 11 Aug 26 09:46 test.c

移动目录文件

cpp 复制代码
[root@VM-0-2-centos ~]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug 27 09:23 2026_8_26
-rwxr-xr-x 1 root root 8600 Aug 26 16:49 test
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
[root@VM-0-2-centos ~]# mv 2026_8_26 ..
[root@VM-0-2-centos ~]# ls ..
2026_8_26  boot  dev  home  lib64       media  opt   root  sbin  sys  usr
bin        data  etc  lib   lost+found  mnt    proc  run   srv   tmp  var
[root@VM-0-2-centos ~]# mv ../2026_8_26 .
[root@VM-0-2-centos ~]# ls
2026_8_26  test  test.c

如果当前路径存在同名文件,移动即覆盖

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   `-- test.c
|-- test.c
`-- test.txt

1 directory, 4 files
[root@VM-0-2-centos ~]# cat test.c
#include <stdio.h>

const char *dev = "/dev/pts/1";

int main()
{
    int cnt = 10;
    FILE *fp = fopen(dev,"w");
    if(fp==NULL)
    {
        printf("open error\n");
	return 1;
    }
    while(cnt--)
    {
        fprintf(fp,"%d\n",cnt);
        sleep(1);
    }
    fclose(fp);
    return 0;
}
[root@VM-0-2-centos ~]# cat 2026_8_27/test.c
aaaa
bbbbb
[root@VM-0-2-centos ~]# mv test.c 2026_8_27
mv: overwrite '2026_8_27/test.c'? y
[root@VM-0-2-centos ~]# ls
2026_8_27  test.txt
[root@VM-0-2-centos ~]# ls 2026_8_27
hello.txt  test.c
[root@VM-0-2-centos ~]# cat 2026_8_27/test.c
#include <stdio.h>

const char *dev = "/dev/pts/1";

int main()
{
    int cnt = 10;
    FILE *fp = fopen(dev,"w");
    if(fp==NULL)
    {
        printf("open error\n");
	return 1;
    }
    while(cnt--)
    {
        fprintf(fp,"%d\n",cnt);
        sleep(1);
    }
    fclose(fp);
    return 0;
}

文件重命名

cpp 复制代码
[root@VM-0-2-centos ~]# mv test test.txt #普通文件重命名
[root@VM-0-2-centos ~]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug 27 09:23 2026_8_26
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
-rwxr-xr-x 1 root root 8600 Aug 26 16:49 test.txt
[root@VM-0-2-centos ~]# mv 2026_8_26 2026_8_27 #目录文件重命名 
[root@VM-0-2-centos ~]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug 27 09:23 2026_8_27
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
-rwxr-xr-x 1 root root 8600 Aug 26 16:49 test.txt

重命名时若目标已存在,同样会覆盖

cpp 复制代码
[root@VM-0-2-centos ~]# > test.c
[root@VM-0-2-centos ~]# ll
total 16
drwxr-xr-x 2 root root 4096 Aug 27 09:52 2026_8_27
-rw-r--r-- 1 root root    0 Aug 27 10:03 test.c
-rwxr-xr-x 1 root root 8600 Aug 26 16:49 test.txt
[root@VM-0-2-centos ~]# mv test.c test.txt
mv: overwrite 'test.txt'? y
[root@VM-0-2-centos ~]# ll
total 4
drwxr-xr-x 2 root root 4096 Aug 27 09:52 2026_8_27
-rw-r--r-- 1 root root    0 Aug 27 10:03 test.txt

总结:mv 到底是剪切还是重命名,看两点:

  1. 目标是不是已存在的目录 ?如果是,就是移动(剪切)。

  2. 目标是不是普通文件(或不存在) ?如果是,就是重命名

注意:mv 默认是递归的。如果移动目录,会把整个目录及其子内容一并移动。


二:Linux理论知识:日志

我们在 Linux 下做的大部分操作,都会被系统记录下来。

什么是系统日志?

在 Linux 中,可以通过 /var/log/messages 等文件查看系统日志。这些日志会记录诸如谁登录了系统、何时何地登录、对文件执行了哪些操作等信息。

除此之外,我们在终端输入过的历史命令,也可以通过 history 查看。

简单来说:我们在系统中所做的几乎一切工作,都会被记录在案。

为什么要有日志?

在工程领域,日志是必不可少的------它的核心作用就是把系统或程序运行过程中的关键操作全部记录下来。

一份规范的日志通常包含以下要素:

  • 时间:什么时候发生的

  • 内容:具体发生了什么

  • 主体:哪个用户或哪个进程执行的

  • 等级:事件的严重程度(这个概念后面讲多线程时会细说,届时我会手写一个简单的日志系统)

Linux 与 Windows 都有日志

/var/log/messages 就是 Linux 系统自身的日志文件之一,由 Linux 内核在操作系统运行过程中持续写入。

Windows 系统其实也有日志。在运行 APP 或应用程序的过程中,本地会不断产生日志信息。这也是为什么手机或电脑用久了,存储空间会慢慢变少的原因之一。

当然,日志文件不会无限膨胀。当写到一定程度时,系统会进行日志轮转(log rotation)------要么覆盖最旧的记录,要么备份归档后再从头开始写。

查日志是程序员的日常

作为一名程序员,未来排查线上问题时,查看日志是最常见的操作之一。

但日志文件通常体量很大,直接用 cat 查看会直接刷屏,根本看不过来。比如想看系统最早的登录记录,或者只想看最新的报错,这时候就需要借助专门的文本查看工具:

  • 从后往前 看?用 tac

  • 逐页浏览 ?用 moreless

  • 只看中间某一段 ?用 headtail 配合管道

接下来,我们就来介绍这些文本查看指令。


文本查看指令

cat指令

cat 命令适合查看短文件 ,主要用于不想用 vim 打开文件进行编辑,只想快速看一下文件内容的场景。

语法: cat [选项] [文件]

功能: 查看目标文件的内容。

常用选项:

  • -b:对非空输出行编号,空行不做编号。

  • -n:对输出的所有行编号。

  • -s:不输出多行空行,将多行空行压缩成一行。

示例:

cpp 复制代码
[root@VM-0-2-centos ~]# ll
total 8
drwxr-xr-x 2 root root 4096 Aug 27 10:11 2026_8_27
-rw-r--r-- 1 root root  298 Aug 26 15:46 test.c
-rw-r--r-- 1 root root    0 Aug 27 10:03 test.txt

[root@VM-0-2-centos ~]# cat -b test.c
     1	#include <stdio.h>

     2	const char *dev = "/dev/pts/1";

     3	int main()
     4	{
     5	    int cnt = 10;
     6	    FILE *fp = fopen(dev,"w");
     7	    if(fp==NULL)
     8	    {
     9	        printf("open error\n");
    10		return 1;
    11	    }
    12	    while(cnt--)
    13	    {
    14	        fprintf(fp,"%d\n",cnt);
    15	        sleep(1);
    16	    }
    17	    fclose(fp);
    18	    return 0;
    19	}

tac指令

taccat 功能类似,也是显示文件内容,但它是反向显示(按行倒序):

cpp 复制代码
#include <stdio.h>[root@VM-0-2-centos ~]# tac test.c
}
    return 0;
    fclose(fp);
    }
        sleep(1);
        fprintf(fp,"%d\n",cnt);
    {
    while(cnt--)
    }
	return 1;
        printf("open error\n");
    {
    if(fp==NULL)
    FILE *fp = fopen(dev,"w");
    int cnt = 10;
{
int main()

const char *dev = "/dev/pts/1";

#include <stdio.h>

有了 tac 指令,查看日志时想从最新记录往回看就很方便。


more指令

语法: more [选项] 文件

功能: 类似 cat,但不会一次性把文件内容全部显示出来,而是按屏显示,打满一屏后暂停。

常用选项:

  • -n:指定输出行数。

  • q:退出 more

举例

最下面的 --More--(0%) 表示当前已显示文件的百分比。按回车 可以逐行向下查看。按 q 退出。

more 只能向后翻,不能向前翻,现在不太推荐使用。


less指令(推荐)

less 是对文件或其它输出进行分页显示的工具,是 Linux 正统查看文件内容的工具,功能极其强大。

  • less 的用法比 more 更有弹性。使用 more 时没有办法向前面翻,只能往后面看。

  • 使用 less 时,可以使用 [PageUp][PageDown] 等按键前后翻看文件,更容易用来查看一个大文件的内容。

  • 除此之外,less 还拥有更多的搜索功能,不止可以向下搜,也可以向上搜。

语法: less [参数] 文件

功能: lessmore 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,不能向后移动,而且 less 在查看之前不会加载整个文件。

选项:

  • -i:忽略搜索时的大小写。

  • -N:显示每行的行号。

  • /字符串:向下搜索"字符串"的功能。

  • ?字符串:向上搜索"字符串"的功能。

  • n:重复前一个搜索(与 /? 有关)。

  • N:反向重复前一个搜索(与 /? 有关)。

  • q:quit,退出。

这里就不演示了


head指令

head 用来显示档案的开头内容至标准输出中。

语法: head [参数]... [文件]...

功能: 默认打印相应文件的开头 10 行。

选项:

  • -n:显示的行数。

tail指令

tail 命令从指定点开始将文件写到标准输出。使用 tail 命令的 -f 选项可以方便地查阅正在改变的日志文件,tail -f filename 会把 filename 里最尾部的内容显示在屏幕上,并且不断刷新,使你看到最新的文件内容。

语法: tail [必要参数] [文件]

功能: 用于显示指定文件末尾内容,不指定文件时,作为输入信息进行处理。常用于查看日志文件。

选项:

  • -f:循环读取(实时追踪日志)。

  • -n:显示行数。

查看中间部分的日志

head 能看前 n 行,tail 能看后 n 行。那如果我想看中间部分呢?

先生成一份模拟日志:

cpp 复制代码
[root@VM-0-2-centos ~]# nano test.c
[root@VM-0-2-centos ~]# cat test.c
#include <stdio.h>

int main()
{
    int cnt = 0;
    while(cnt!=1000)
    {
        printf("%d\n",++cnt);
    }
    return 0;
}
[root@VM-0-2-centos ~]# gcc test.c -o test
[root@VM-0-2-centos ~]# ll
total 20
drwxr-xr-x 2 root root 4096 Aug 27 10:11 2026_8_27
-rwxr-xr-x 1 root root 8360 Aug 27 12:02 test
-rw-r--r-- 1 root root  127 Aug 27 12:02 test.c
-rw-r--r-- 1 root root    0 Aug 27 10:03 test.txt
[root@VM-0-2-centos ~]# cat test.txt
[root@VM-0-2-centos ~]# ./test > test.txt
[root@VM-0-2-centos ~]# ll
total 24
drwxr-xr-x 2 root root 4096 Aug 27 10:11 2026_8_27
-rwxr-xr-x 1 root root 8360 Aug 27 12:02 test
-rw-r--r-- 1 root root  127 Aug 27 12:02 test.c
-rw-r--r-- 1 root root 2893 Aug 27 12:03 test.txt

这里通过运行程序,将 1 到 1000 的输出重定向到 test.txt,模拟日志文件。

查看前 10 行和后 10 行:

cpp 复制代码
[root@VM-0-2-centos ~]# ./test > test.txt
[root@VM-0-2-centos ~]# head -10 test.txt
1
2
3
4
5
6
7
8
9
10
[root@VM-0-2-centos ~]# tail -10 test.txt
991
992
993
994
995
996
997
998
999
1000

如果想看第 500 到 510 行,可以借助一个中间文件:

cpp 复制代码
[root@VM-0-2-centos ~]# head -510 test.txt > lin.txt
[root@VM-0-2-centos ~]# tail -10 lin.txt
501
502
503
504
505
506
507
508
509
510

但这样需要额外创建临时文件,不够优雅。此时就可以用管道 |:| 能把左右指令隔开,指令从左往右执行下去,左指令执行完后,右指令在左指令的基础上继续往下执行,如下

cpp 复制代码
[root@VM-0-2-centos ~]# head -510 test.txt | tail -10
501
502
503
504
505
506
507
508
509
510

接下来我就来讲讲这个 |


三:Linux理论知识:管道

我们上面写了这么 一行指令

cpp 复制代码
[root@VM-0-2-centos ~]# head -510 test.txt | tail -10

| 将左右两条指令连接起来:左侧指令的执行结果经过 | 传给右侧指令,右侧指令在左侧结果的基础上继续处理。

Linux 一切皆文件,那么 | 是什么呢?| 我们称之为管道,它的本质也是个文件。

举个例子,就像现实中的自来水管道:一端灌水,一端出水。对应到命令上,就是左侧指令的结果写入到管道中,右侧指令再从管道中读取数据

所以,管道可以用来做命令的级联,实现批量化的文本处理。如果想把显示出来的内容逆序打印,再加一层管道即可:

cpp 复制代码
[root@VM-0-2-centos ~]# head -510 test.txt | tail -10 | tac
510
509
508
507
506
505
504
503
502
501

有了管道后,未来就可以通过命令组合,做各种文本或相关信息的分析。

这里对 |(管道)的理解和重定向一样,先不做原理性深入。要原理性理解,需要学到进程和进程间通信部分。

注意:管道也是要开辟空间的,相当于一个隐式的临时文件,系统会自动把前后指令的输出和输入重定向到这个管道上,用完后自动清理(管道是内存级的,不是磁盘级的)。


时间与查找指令

date指令

指定格式显示时间: date +%Y:%m:%d+ 必须是 +,后面的分隔符可以自己改)

用法: date [OPTION]... [+FORMAT]

1. 显示方面

使用者可以设定欲显示的格式,格式设定为一个加号后接数个标记,常用标记列表如下:

  • %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

举例:

cpp 复制代码
[root@VM-0-2-centos ~]# date #系统的默认时间格式
Thu Aug 27 12:57:52 CST 2026

看当前具体时间(精确到秒)

cpp 复制代码
[root@VM-0-2-centos ~]# date +%Y-%m-%d_%H:%M:%S
2026-08-27_13:02:20

掌握时间获取后,可以做很多事情,比如写日志、统计程序运行时长等。

2. 设定时间方面

  • date -s:设置当前时间,只有 root 权限才能设置,其他用户只能查看。

  • date -s 20080523:设置成 20080523,这样会把具体时间设置成空 00:00:00。

  • date -s 01:01:01:设置具体时间,不会对日期做更改。

  • 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":设置全部时间。

  1. 时间戳

3. 时间戳

  • 时间 → 时间戳:date +%s

  • 时间戳 → 时间:date -d@1508749502

Unix 时间戳(Unix epoch / Unix time / POSIX time / Unix timestamp)是从 1970 年 1 月 1 日(UTC/GMT 的午夜------格林威治)开始所经过的秒数,不考虑闰秒。

计算机能显示时间就是因为这个时间戳。计算机内部会维持一个线性递增的计数器,这个计数器的值就是时间戳,显示的时间都是从时间戳转换过来的。

时间戳除了能转换为时间,还能用来区间查找。有些日志直接用时间戳存储时间,想看上周的日志,只需要算出上周的时间戳区间即可。

举例:

cpp 复制代码
[root@VM-0-2-centos ~]# date +%s
1787808194
[root@VM-0-2-centos ~]# date +%Y-%m-%d_%H:%M:%S -d @1787808194
2026-08-27_13:23:14

验证时间戳是否从 1970 年 1 月 1 日开始:

cpp 复制代码
[root@VM-0-2-centos ~]# date +%Y-%m-%d_%H:%M:%S -d @0
1970-01-01_08:00:00
[root@VM-0-2-centos ~]# date +%Y-%m-%d_%H:%M:%S -d @1
1970-01-01_08:00:01
[root@VM-0-2-centos ~]# date +%Y-%m-%d_%H:%M:%S -d @2
1970-01-01_08:00:02

显示为 8 点开始,是因为各地有时差。0 点对应的是 UTC/GMT 的午夜,北京和格林威治有 8 个小时的时差。这样设计可以保证各个地区的时间不会混乱。

注意: 时间戳是会溢出的。因为时间戳以计数器形式存储,目前最大能存到 long long(8 字节),所以未来会有时间戳溢出的风险。现实中很多系统(银行、消费等)都基于时间戳运行,这是一个需要关注的问题。

拓展: 计算机已经关机了,为什么开机后还能准确识别时间?

这是因为不管是笔记本还是台式机,主板上都有一颗纽扣电池(CMOS 电池),可以让主板在断电时继续记录时间。所以一开机时间就是准的。但如果把电源拔掉,放置半年后再开机,时间可能就不对了,因为纽扣电池没电了。后面讲操作系统启动原理时会再回归这个问题。


cal指令

cal 命令现在基本用得不多了,它可以用来显示公历(阳历)日历。

命令格式: cal [参数] [年份]

功能: 用于查看日历等时间信息。如只有一个参数,则表示年份(1-9999);如有两个参数,则表示月份和年份;如果没有参数,表示显示当月日历。

常用选项:

  • -3:显示系统前一个月、当前月、下一个月的月历。

  • -j:显示在当年中的第几天(一年日期按天算,从 1 月 1 号算起)。

  • -y:显示当前年份的日历。

这个日历其实也是根据时间戳计算出来的。

举例:

cpp 复制代码
[root@VM-0-2-centos ~]# cal
     August 2026    
Su Mo Tu We Th Fr Sa
                   1
 2  3  4  5  6  7  8
 9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31
[root@VM-0-2-centos ~]# cal 2000
                               2000                               

       January               February                 March       
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5             1  2  3  4
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    5  6  7  8  9 10 11
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   12 13 14 15 16 17 18
16 17 18 19 20 21 22   20 21 22 23 24 25 26   19 20 21 22 23 24 25
23 24 25 26 27 28 29   27 28 29               26 27 28 29 30 31
30 31
        April                   May                   June        
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1       1  2  3  4  5  6                1  2  3
 2  3  4  5  6  7  8    7  8  9 10 11 12 13    4  5  6  7  8  9 10
 9 10 11 12 13 14 15   14 15 16 17 18 19 20   11 12 13 14 15 16 17
16 17 18 19 20 21 22   21 22 23 24 25 26 27   18 19 20 21 22 23 24
23 24 25 26 27 28 29   28 29 30 31            25 26 27 28 29 30
30
        July                  August                September     
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
                   1          1  2  3  4  5                   1  2
 2  3  4  5  6  7  8    6  7  8  9 10 11 12    3  4  5  6  7  8  9
 9 10 11 12 13 14 15   13 14 15 16 17 18 19   10 11 12 13 14 15 16
16 17 18 19 20 21 22   20 21 22 23 24 25 26   17 18 19 20 21 22 23
23 24 25 26 27 28 29   27 28 29 30 31         24 25 26 27 28 29 30
30 31
       October               November               December      
Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa   Su Mo Tu We Th Fr Sa
 1  2  3  4  5  6  7             1  2  3  4                   1  2
 8  9 10 11 12 13 14    5  6  7  8  9 10 11    3  4  5  6  7  8  9
15 16 17 18 19 20 21   12 13 14 15 16 17 18   10 11 12 13 14 15 16
22 23 24 25 26 27 28   19 20 21 22 23 24 25   17 18 19 20 21 22 23
29 30 31               26 27 28 29 30         24 25 26 27 28 29 30
                                              31

[root@VM-0-2-centos ~]# cal -3
      July 2026            August 2026         September 2026   
Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa  Su Mo Tu We Th Fr Sa
          1  2  3  4                     1         1  2  3  4  5
 5  6  7  8  9 10 11   2  3  4  5  6  7  8   6  7  8  9 10 11 12
12 13 14 15 16 17 18   9 10 11 12 13 14 15  13 14 15 16 17 18 19
19 20 21 22 23 24 25  16 17 18 19 20 21 22  20 21 22 23 24 25 26
26 27 28 29 30 31     23 24 25 26 27 28 29  27 28 29 30         
                      30 31  

which指令

功能: 搜索系统指定的命令路径。

举例:

cpp 复制代码
[root@VM-0-2-centos ~]# which pwd
/usr/bin/pwd

which 有一定局限性,主要用于查找命令。它会在系统指定的目录(一般是 /usr/bin 等)下查找指令。不确定某个指令是否存在时,which 一下即可。


whereis指令

这个命令是所有查找命令里出场率最低的,很少用。

功能: 用于找到程序的源码、二进制文件或手册页。

举例:

cpp 复制代码
[root@VM-0-2-centos ~]# whereis man
man: /usr/bin/man /usr/share/man /usr/share/man/man7/man.7.gz /usr/share/man/man1/man.1.gz /usr/share/man/man1p/man.1p.gz

whereis会在系统指定的目录下查


find指令(重要)

这是真正会在 Linux 树形结构里进行查找的指令。

Linux 下 find 命令在目录结构中搜索文件,并执行指定的操作。

  • find 命令提供了相当多的查找条件,功能很强大,选项也很多。

  • 即使系统中含有网络文件系统(NFS),find 命令在该文件系统中同样有效,只要你具有相应的权限。

  • 在运行一个非常消耗资源的 find 命令时,很多人都倾向于把它放在后台执行,因为遍历一个大的文件系统可能会花费很长时间。

语法: find pathname -options

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

常用选项:

  • -name:按照文件名查找文件。

  • 其他选项需要时再查,这个命令比较复杂。

举例:

目前只需要掌握下面这种用法:find 目录 -name 目标文件

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   `-- test.c
|-- test
|-- test.c
`-- test.txt

1 directory, 5 files
[root@VM-0-2-centos ~]# find ~ -name test.c
/root/2026_8_27/test.c
/root/test.c

从查找结果的输出顺序可以看出,它走的是深度优先遍历的方式。

当然也能查找指令,但因为是从根目录开始找,所以会花比较多的时间:

cpp 复制代码
[root@VM-0-2-centos ~]# find / -name pwd
/usr/local/qcloud/YunJing/bin/pwd
/usr/bin/pwd

grep指令

grep 指令又叫做行文本过滤工具,它会把包含某种关键字段的行整行保留下来,帮助我们做内容筛选。

注意:关键字段带 " "' ',或不带引号都可以。如果关键字段有空格,最好带上双引号或单引号。

语法: grep [选项] 搜寻字符串 文件

功能: 在文件中搜索字符串,将找到的行打印出来。

常用选项:

  • -i:忽略大小写的不同,所有大小写视为相同。

  • -n:顺便输出行号(原始文件所对应的行号)。

  • -v:反向选择,亦即显示出没有"搜寻字符串"内容的那一行。

以日志为例演示:

在日志里有很多信息,查看时可能只想看有没有报错。有两种做法:

第一种:通过管道

cpp 复制代码
[root@VM-0-2-centos ~]# cat /var/log/messages | grep "err"
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: Using IOAPIC for interrupt routing
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 10
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKB] enabled at IRQ 10
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 11
Jul 30 16:12:01 VM-0-2-centos ntpd[601]: Deferring DNS for ntpupdate.tencentyun.com 1
Aug  4 10:39:56 VM-0-2-centos yum[15045]: Installed: man-pages-overrides-7.9.0-1.el7.x86_64

第二种:grep 直接读取文件

cpp 复制代码
[root@VM-0-2-centos ~]# grep "err" /var/log/messages
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: Using IOAPIC for interrupt routing
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKA] (IRQs 5 *10 11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKB] (IRQs 5 *10 11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKC] (IRQs 5 10 *11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKD] (IRQs 5 10 *11)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKS] (IRQs *9)
Jul 30 16:11:58 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKD] enabled at IRQ 11
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKA] enabled at IRQ 10
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKB] enabled at IRQ 10
Jul 30 16:11:59 VM-0-2-centos kernel: ACPI: PCI Interrupt Link [LNKC] enabled at IRQ 11
Jul 30 16:12:01 VM-0-2-centos ntpd[601]: Deferring DNS for ntpupdate.tencentyun.com 1
Aug  4 10:39:56 VM-0-2-centos yum[15045]: Installed: man-pages-overrides-7.9.0-1.el7.x86_64

通过 grep 就可以分门别类地把想要的信息直接筛选出来。

grep 除了查日志,后面还可以在系统中筛选指定的进程(进程部分后面具体讲,现在有个印象即可)。我们用 ps 命令能查到系统中所有启动的进程,top 也可以查进程:

cpp 复制代码
top -d 1 -n 5
  • -d:刷新的时间间隔。

  • -n:刷新的次数。

  • q:退出。


四:Linux理论知识:打包和压缩

在 Linux 中,文件传输是非常常见的操作。

比如:

  • 项目部署
  • 上传服务器
  • 下载程序
  • 备份数据

如果直接传输一个包含大量文件的目录,会存在两个问题:

  1. 文件数量太多,不方便管理。
  2. 文件没有经过压缩,占用空间较大,传输速度慢。

因此 Linux 中通常会先对文件进行:

打包 + 压缩

其实在 Windows 系统下,我们已经接触过打包压缩。这里要明确几个问题:

1. 打包压缩是什么?

很多人会把打包和压缩混为一谈,其实它们是两个不同的概念。

打包压缩分为两步:打包压缩

  • 打包:把多个文件合并成一个文件。比如 Windows 下下载的软件很多是压缩包,里面包含很多文件,把这些文件合并到一个文件中的过程就是打包。

  • 压缩:打包后的文件体积可能比较大,使用压缩算法可以减小体积。

2. 为什么要进行打包压缩?

  • 打包:可以在拷贝文件时防止文件丢失,本质是把多文件变成一个文件,这是一种计算机技术。

  • 压缩:减小体积的目的有两个:

    • 节省本地存储空间。压缩后下载更快,使用时再解压,相当于用时间换空间

    • 所有文件经过网络传送时,压缩可以有效减少网络传输时间。

放到现实中理解:公司做出一款软件,体积越小,用户下载速度越快,使用成本越低。一个软件 10MB,一个软件 10GB,用户肯定会更倾向于 10MB 的。

所以我们必须了解 Linux 中的打包压缩。未来如果写好了项目或软件,需要在 Linux 环境下部署,就要先传到 Linux 上,这时打包压缩就必不可少了。

接下来讲解打包和压缩的指令。注意:打包和压缩在实际操作中不做明显区分。

对于打包压缩的方式,主要讲两套:

  • zip / unzip 方式

  • tar 方式

打包压缩形成的文件种类很多,有 .zip.tar.gz.tar.bz2 等。这里讲的这两套方案是 Linux 中最常用的打包压缩方案,没有之一。


打包压缩指令

zip/unzip指令(重要)

使用 zip 之前,先安装一下:

cpp 复制代码
[root@VM-0-2-centos ~]# yum install -y zip unzip

通过 zip --version 查看版本,能查看到版本说明命令已安装成功。当然也可以用 which 查看。

语法: zip 压缩文件.zip 源文件

功能: 将目录或文件压缩成 zip 格式。

常用选项:

  • -r:递归处理,将指定目录下的所有文件和子目录一并处理。

举例:

2026_8_27 目录压缩:

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
`-- tmp

2 directories, 4 files
[root@VM-0-2-centos ~]# zip test1.zip 2026_8_27 
  adding: 2026_8_27/ (stored 0%)
[root@VM-0-2-centos ~]# ll
total 12
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root  170 Aug 27 16:50 test1.zip
drwxr-xr-x 2 root root 4096 Aug 27 16:48 tmp

zip test1.zip 2026_8_27 中,test1.zip 是压缩后的文件名,2026_8_27 是想要压缩的源目录。

压缩后的 test1.zip 也是普通文件,这也印证了 Linux 一切皆文件。

解压到 tmp 目录:

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
`-- tmp
    `-- test1.zip

2 directories, 5 files
[root@VM-0-2-centos ~]# cd tmp
[root@VM-0-2-centos tmp]# unzip test1.zip
Archive:  test1.zip
   creating: 2026_8_27/
[root@VM-0-2-centos tmp]# ll
total 8
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root  170 Aug 27 16:50 test1.zip

我们把这个压缩包移动到tmp目录里,我们进入tmp目录进行解压,他默认会解压到用户所在地目录

但这时发现一个问题:

cpp 复制代码
[root@VM-0-2-centos tmp]# ll 2026_8_27
total 0

解压出来的目录是空的 !这说明打包时遗漏了目录内的文件。因为 zip 默认只打包指定的目录本身,不会递归处理子文件。要打包目录及其内部所有内容,需要加 -r 选项:

cpp 复制代码
[root@VM-0-2-centos ~]# zip -r 27.zip 2026_8_27  
  adding: 2026_8_27/ (stored 0%)
  adding: 2026_8_27/test.c (deflated 22%)
  adding: 2026_8_27/test.txt (deflated 53%)
  adding: 2026_8_27/test (deflated 72%)
  adding: 2026_8_27/hello.txt (deflated 9%)
[root@VM-0-2-centos ~]# ll
total 16
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root 5089 Aug 27 18:01 27.zip
drwxr-xr-x 2 root root 4096 Aug 27 18:00 tmp

deflated 后面显示的就是压缩比例。再解压验证:

cpp 复制代码
[root@VM-0-2-centos ~]# mv 27.zip tmp
[root@VM-0-2-centos ~]# cd tmp
[root@VM-0-2-centos tmp]# ll
total 8
-rw-r--r-- 1 root root 5089 Aug 27 18:01 27.zip
[root@VM-0-2-centos tmp]# unzip 27.zip
Archive:  27.zip
   creating: 2026_8_27/
  inflating: 2026_8_27/test.c        
  inflating: 2026_8_27/test.txt      
  inflating: 2026_8_27/test          
  inflating: 2026_8_27/hello.txt     
[root@VM-0-2-centos tmp]# ll
total 12
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root 5089 Aug 27 18:01 27.zip
[root@VM-0-2-centos tmp]# tree ~
/root
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
`-- tmp
    |-- 2026_8_27
    |   |-- hello.txt
    |   |-- test
    |   |-- test.c
    |   `-- test.txt
    `-- 27.zip

3 directories, 9 files

文件没有缺失,打包压缩和解压都没问题了。

解压到指定目录

如果不想解压到当前目录,可以用 -d 选项指定目标目录:

cpp 复制代码
unzip 压缩文件 -d 目标目录

就以上面的压缩包为例

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
`-- tmp
    |-- 2026_8_27
    |   |-- hello.txt
    |   |-- test
    |   |-- test.c
    |   `-- test.txt
    `-- 27.zip

2 directories, 5 files
[root@VM-0-2-centos ~]# cd tmp
[root@VM-0-2-centos tmp]# unzip 27.zip -d ../
Archive:  27.zip
   creating: ../2026_8_27/
  inflating: ../2026_8_27/test.c     
  inflating: ../2026_8_27/test.txt   
  inflating: ../2026_8_27/test       
  inflating: ../2026_8_27/hello.txt  
[root@VM-0-2-centos tmp]# tree ~
/root
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
`-- tmp
    |-- 2026_8_27
    |   |-- hello.txt
    |   |-- test
    |   |-- test.c
    |   `-- test.txt
    `-- 27.zip

3 directories, 9 files

总结:

  • 打包压缩单个普通文件:zip 压缩文件名 源文件名

  • 打包压缩目录(多文件):zip -r 压缩文件名 源目录名

所以平时直接用 zip -r 即可,兼容单文件和多文件场景。

解压分两种:

  • 解压到当前目录:unzip 压缩文件名

  • 解压到指定目录:unzip 压缩文件名 -d 目标目录


rz/sz指令(Linux与Windows互传文件)

rzsz 是一对用于在 Windows 和远端 Linux 之间传输文件的工具,基于 ZMODEM 协议。

  • sz (send ZMODEM):从 Linux 发送文件到 Windows

  • rz (receive ZMODEM):从 Windows 接收文件到 Linux

安装

使用前需要先安装 lrzsz 包:

cpp 复制代码
[root@VM-0-2-centos tmp]# yum install -y lrzsz

安装完成后,可以通过 sz --versionwhich sz 验证是否安装成功。

Linux → Windows:使用 sz

想把 Linux 上的文件传到 Windows,只需执行 sz 文件名。以上面打包好的 27.zip 为例:

cpp 复制代码
[root@VM-0-2-centos tmp]# sz 27.zip

执行后,Windows 端会弹出文件保存对话框,选择保存路径(如 E 盘)即可。

传输完成后,在 Windows 的对应路径下可以找到该文件,解压验证内容无误。

Windows → Linux:使用 rz

想把 Windows 上的文件传到 Linux,在 Linux 终端执行 rz

cpp 复制代码
[root@VM-0-2-centos ~]# rz

执行后会弹出文件选择对话框,选中 Windows 上的文件即可上传。

上传的文件默认会放到当前执行 rz 命令的目录下

cpp 复制代码
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
|-- haha.zip
`-- tmp

2 directories, 5 files

然后可以正常解压验证:

cpp 复制代码
[root@VM-0-2-centos ~]# unzip haha.zip -d tmp
Archive:  haha.zip
   creating: tmp/2026_8_27/
  inflating: tmp/2026_8_27/test.c    
  inflating: tmp/2026_8_27/test.txt  
  inflating: tmp/2026_8_27/test      
  inflating: tmp/2026_8_27/hello.txt  
[root@VM-0-2-centos ~]# tree
.
|-- 2026_8_27
|   |-- hello.txt
|   |-- test
|   |-- test.c
|   `-- test.txt
|-- haha.zip
`-- tmp
    `-- 2026_8_27
        |-- hello.txt
        |-- test
        |-- test.c
        `-- test.txt

3 directories, 9 files

文件没有缺失,传输成功。

快捷方式:拖拽上传

除了使用 rz 命令,Xshell 还支持直接拖拽 :把 Windows 上的文件拖到 Xshell 终端窗口里,会自动调用 rz 命令完成上传,无需手动输入指令。

注:后面讲的tar所压缩的文件也可以用这个指令进行Windows和Linux的文件互传


tar指令(重要)

前面我们介绍了 zip/unzip,它是一种跨平台性较好的压缩工具,在 Windows 和 Linux 之间使用比较方便。但是在 Linux 环境中,实际开发和部署场景里,使用更加广泛的是 tar。

Linux 中大量源码包、软件包以及日志备份文件,都采用 .tar.gz 格式。因此,tar 是 Linux 中必须掌握的打包压缩工具。

1. tar 与 zip 的区别

在讲 tar 之前,先回顾一下前面的 zip。

zip 本身就是一个完整的压缩工具:

复制代码
zip
=
打包 + 压缩

例如:

复制代码
zip -r test.zip 2026_8_27

会直接把目录打包并压缩。

而 tar 的设计思想不同:

tar 本身主要负责:

把多个文件归档成一个文件。

也就是:

复制代码
多个文件
      |
      ↓
    tar
      |
      ↓
 一个归档文件

然后再结合 gzip 进行压缩:

复制代码
tar
+
gzip
=
tar.gz

所以:

复制代码
.tar.gz

实际上表示:

先 tar 打包
再 gzip 压缩

这也是为什么 Linux 中的软件包大多采用 .tar.gz 格式。


2. tar 的基本使用

tar 命令打包压缩出来的包,后缀全称是 .tar.gz,但选项写起来比较分散。通常简写为 .tgz,也就是打包压缩后的文件。

语法:

cpp 复制代码
tar 选项 目标文件名.tgz 源目录或文件

打包压缩的具体行为由选项控制。

常用选项
选项 含义 说明
-c create 建立(创建)一个压缩文件
-x extract 解开(解压)一个压缩文件
-t list 查看压缩包内的文件列表
-z gzip 使用 gzip 格式进行压缩/解压
-j bzip2 使用 bzip2 格式进行压缩/解压
-v verbose 显示压缩/解压过程中的文件信息
-f file 指定压缩包的文件名。注意:-f 后面必须立即接文件名,不能再跟其他选项
-C directory 解压到指定目录
打包压缩

创建压缩包时,最常用的是 -czf 组合:

  • -c:创建新包

  • -z:用 gzip 压缩

  • -f:指定生成的文件名

示例:

cpp 复制代码
[root@VM-0-2-centos ~]# tar -czf test1.tgz 2026_8_27
[root@VM-0-2-centos ~]# ll
total 16
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root 4912 Aug 27 21:08 test1.tgz
drwxr-xr-x 2 root root 4096 Aug 27 21:08 tmp

此时就生成了打包压缩后的 .tgz 文件。

解压解包

解压时,只需把 -c 换成 -x(extract),其余不变:

cpp 复制代码
[root@VM-0-2-centos tmp]# tar -xzf test1.tgz
[root@VM-0-2-centos tmp]# ll
total 12
drwxr-xr-x 2 root root 4096 Aug 27 16:44 2026_8_27
-rw-r--r-- 1 root root 4912 Aug 27 21:08 test1.tgz

tar 与 zip 的一个重要区别tar 默认会递归 处理目录,自动把子文件全部打包;而 zip 需要加 -r 选项才会递归。

显示详细过程

如果想查看压缩或解压的详细进度,可以加上 -v(verbose)选项:

压缩时显示详情:

cpp 复制代码
[root@VM-0-2-centos ~]# tar -cvzf test.tgz 2026_8_27
2026_8_27/
2026_8_27/test.c
2026_8_27/test.txt
2026_8_27/test
2026_8_27/hello.txt
解压到指定目录
cpp 复制代码
[root@VM-0-2-centos tmp]# tar -xvzf test1.tgz
2026_8_27/
2026_8_27/test.c
2026_8_27/test.txt
2026_8_27/test
2026_8_27/hello.txt
解压到指定目录

默认解压到当前目录。如果想解压到指定目录,使用 -C 选项:

cpp 复制代码
[root@VM-0-2-centos tmp]# tar -xvzf test1.tgz -C ../
2026_8_27/
2026_8_27/test.c
2026_8_27/test.txt
2026_8_27/test
2026_8_27/hello.txt
一个小细节:选项前的 -

实际使用中,有些终端环境对选项前的 - 号支持不同:

  • 有的终端支持 -czf-xzf 这种写法

  • 有的终端去掉 - 号也能识别(如 tar czf

  • 极少数终端只支持其中一种

如果遇到报错,可以尝试去掉 - 号:

总结

初学者只需记住两组核心组合

场景 命令
打包压缩 tar -czf 文件名.tgz 源目录
解压解包 tar -xzf 文件名.tgz

tar 不像 lspwd 那样是高频命令,顶多算中频命令,所以选项不需要全部死记硬背,够用即可。


Linux与Linux互传文件

既然 Linux 与 Windows 互传文件没问题,那两台 Linux 机器之间能不能互相传输文件呢?当然可以。

右侧是Ubuntu机器,左侧是CentOS机器

现在要把 CentOS 上的压缩包传到 Ubuntu 机器上。Linux 系统之间互传,需要用到 scp 指令(secure copy,系统通常默认已安装)。

scp 叫做远程拷贝 ,作用和本地用的 cp 命令类似,只不过拷贝的目标在另一台机器上。

语法:

bash

复制代码
scp 源文件 用户名@目标IP:目标路径

因为是远程拷贝,目标位置需要明确三要素:用户名公网 IP目标路径 。这和 ssh 远程登录的格式很像,只是前面多了要拷贝的源文件以及要拷贝到的目标路径。

示例:

复制代码
[root@VM-0-2-centos ~]# scp test.tgz user@192.168.1.100:/home/user/

执行后,输入目标机器的密码,文件就开始传输了。

补充说明

  • Linux 与 Windows 互传 .tgz.zip 文件时,Windows 上的压缩软件(如 7-Zip、Bandizip)对这些格式都支持,解压无兼容性问题。

  • 压缩包最大的意义在于方便传输:把多个文件打包成一个、体积压缩变小,无论是跨系统(Linux ↔ Windows)还是跨机器(Linux ↔ Linux),都能高效完成文件迁移。


bc指令

bc 命令可以很方便地进行浮点运算,它其实就相当于 Linux 里的一个简易计算器。

示例如下:

cpp 复制代码
[root@VM-0-2-centos tmp]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
1+1
2
10.9+2.3
13.2
9.8/2.0
4

不过上面这种交互式用法我们很少用,更常见的是配合管道来使用:

cpp 复制代码
[root@VM-0-2-centos tmp]# echo "1+2+3+4+5+6+7" | bc
28

bc也可以控制精度,但是太低频了,就不讲了


uname指令

语法: uname [选项]

功能: 获取电脑和操作系统的相关信息。

补充说明: 可显示 Linux 主机所用的操作系统版本、硬件名称等基本信息。

常用选项:

选项 说明
-a 详细输出所有信息,依次为内核名称、主机名、内核版本号、内核版本、硬件名、处理器类型、硬件平台类型、操作系统名称
-r 仅显示内核版本

这个指令本身日常使用频率不高,但面试时经常被问到。

对应的问题一般是:怎么查看 Linux 的体系结构和内核版本?

内核版本之前讲过了,这里重点说说体系结构。所谓体系结构,传统意义上问的就是这台计算机用的芯片------说人话就是 CPU 是什么架构。CPU 架构非常多,但最常见的其实就两三种,比如 Intel、x86、x64、AMD。

这块说来话长,计算机硬件里最重要的就是芯片,芯片特性直接决定了操作系统的内存布局等很多底层设计,所以体系结构就是芯片架构。我们可以在我的电脑当中查看Windows的结构

这个东西就对应我当前整个系统对应的体系结构,硬件最重要的就是处理器,软件最重要的就是操作系统

在 Linux 中,查看云服务器的体系结构,用的就是 uname -a

cpp 复制代码
[root@VM-0-2-centos tmp]# uname -a
Linux VM-0-2-centos 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

输出包括操作系统类别、主机名、内核版本、体系结构等。

如果不想看那么多,只看内核版本,用 -r 选项即可:

cpp 复制代码
[root@VM-0-2-centos tmp]# uname -r
3.10.0-1160.119.1.el7.x86_64

其中 el7 就是 CentOS 7 的意思。

现在服务器主流依旧是 x86。如果看到 x86_32x86_64,要知道 x86_64 就是 x64,这俩是等价的。

小常识:企业一般喜欢用老内核充当操作系统,求的是稳定。

至此,Linux 部分常见的指令我们就全部讲完了。


关机

Linux 下关机有多种方法:shutdownhalt(挂起)、reboot(重启)等。

⚠️ 云服务器永不关机,除非维护或弃用。

云服务器未来要部署我们自己写的服务。你能随时随地刷抖音、逛淘宝,就是因为公司的服务器一直开着 。这也体现了 Linux 的强大------一个操作系统可以稳定运行几年,桌面级的 Windows 完全扛不住。

语法: shutdown [选项]

选项 说明
-h 将系统服务停掉后,立即关机
-r 将系统服务停掉后,重新启动
-t sec 过几秒后关机

这类关机指令在 Windows 中也有对应实现。

Linux 没有开机指令,开机由硬件/服务器商管理。


以下命令为拓展命令

类别 命令
安装和登录 loginshutdownhaltrebootinstallmountumountchshexitlast
文件处理 filemkdirgrepddfindmvlsdiffcatln
系统管理 dftopfreequotaatlpaddusergroupaddkillcrontab
网络操作 ifconfigippingnetstattelnetftprouterloginrcpfingermailnslookup
系统安全 passwdsuumaskchgrpchmodchownchattrsudopswho
其他 tarunzipgunzipunarjmtoolsmanunendcodeuudecode

结语:

至此,Linux 常用指令部分就全部讲完了。回顾一下,我们从 Shell 命令行的运行原理出发,理解了"一切皆文件"的设计哲学;掌握了重定向、管道等核心机制;学习了文件操作、文本查看、打包压缩、系统信息查询等实用指令。

这些指令不需要死记硬背,关键在于多练多用。建议在学习过程中多动手实验,把每个指令都敲几遍,配合管道组合使用,逐步形成肌肉记忆。后续进程管理、权限控制、网络配置等进阶内容,都会在此基础上展开。

希望以上内容对你有所帮助,感谢观看,若觉得写的还可以,可以分享给朋友一起来看哦,毕竟一起进步更有动力嘛,当然能关注一下就更好啦。

相关推荐
ouynagda23 分钟前
Linux信号与进程间通信学习笔记
linux·笔记·学习
祖力5524 分钟前
进程间通信(IPC机制):无名通道与有名通道
linux·运维·服务器·进程·通信·进程间通信·ipc
XR12345678826 分钟前
连锁多分支办公网络怎么选?统一运维与快速开局是关键
运维·网络·php
kkkkkkkkkk_Z33 分钟前
学嵌入式和Linux应用编程|学习日记Day26:Linux进程完整学习笔记
linux·笔记·学习
天远数科37 分钟前
零信任架构实战:基于天远风控经营异常预警构建自动化企业准入网关
运维·人工智能·架构·自动化
kmomo..44 分钟前
Linux 进程间通信(IPC)学习笔记
linux·笔记·学习
华科大胡子1 小时前
Codex 实战:用 AI 写运维脚本
运维·人工智能
今天AI了吗1 小时前
AI工作流的自动化趋势:从手动实验到自主Agent的研究范式转变
运维·数据库·人工智能·sql·机器学习·自动化·github
奶油喜多多1 小时前
教育小程序定制开发指南:从需求梳理到上线运维
运维·小程序