Linux 学习笔记二摘要在 Linux 命令行中文本过滤、文件归档与命令解释器是三个紧密相关的基础主题。grep可以从文件、标准输入或其他命令的输出中筛选匹配行zip和tar用于组织、压缩和传输文件Shell 则负责读取、解析并执行用户输入的命令。本文以WSL Ubuntu 24.04.1 LTS Bash为环境系统介绍grep的常用选项、正则表达式与递归搜索讲清 ZIP 与 tar 归档的区别并进一步分析 Shell、Bash、内建命令、外部程序和子进程之间的关系。一、grep按行搜索与过滤文本grep是 Linux 中常用的文本搜索工具。它读取输入内容检查每一行是否与给定模式匹配并默认输出匹配成功的整行。基本语法如下grep[选项]模式[文件...]例如假设application.log中包含server started database connected error: connection timeout request completed执行greperrorapplication.log输出error: connection timeout根据 GNU Grep 官方文档grep的基本形式是grep [option]... [patterns] [file]...模式通常应在 Shell 中使用引号保护。1. 直接读取文件与通过管道读取下面的命令可以正常工作catapplication.log|greperror数据流向是application.log ↓ cat ↓ 标准输出 管道 ↓ 标准输入 grep但grep本身能够直接读取文件因此可以简化为greperrorapplication.log如果输入本来就来自其他命令管道则非常合适dmesg|grep-ierror因此可以使用下面的原则判断是否需要管道搜索文件优先把文件名直接交给grep搜索另一个命令的输出使用管道把输出交给grep。2. 使用英文半角引号Bash 能识别的常用引号是英文半角单引号和双引号greperrorapplication.loggreperrorapplication.log不要使用中文排版引号grep“error” application.log对于不需要变量展开的模式单引号通常更稳妥因为它可以阻止 Bash 解释大部分特殊字符。3.grep默认匹配的是模式grep默认将模式解释为基本正则表达式而不只是普通字符串。例如grep^errorapplication.log其中^表示行首所以该命令只匹配以error开头的行。如果只想把输入内容当成固定字符串不希望其中的正则符号产生特殊含义可以使用-Fgrep-F1.5data.txt不使用-F时正则表达式中的.可以匹配任意单个字符使用-F后1.5按照字面字符串进行搜索。GNU grep 支持几种常见匹配模式选项匹配方式说明-G基本正则表达式默认模式-E扩展正则表达式支持更方便的、?、-F固定字符串不解释正则表达式元字符-PPerl 兼容正则表达式GNU 扩展并非所有环境都支持4. 常用选项-n显示行号grep-nerrorapplication.log输出示例3:error: connection timeout行号从 1 开始计算。-i忽略大小写grep-ierrorapplication.log这可以同时匹配error Error ERROR-v反向匹配grep-verrorapplication.log-v不表示删除文件中的内容而是反转选择结果输出所有不匹配error的行。原文件不会被修改。-w匹配完整单词grep-wcatwords.txt它可以匹配独立单词cat但不会把category中的cat当成完整单词。-x匹配整行grep-xsuccessresult.txt只有整行内容恰好匹配success时才会输出。-c统计匹配行数grep-cerrorapplication.log输出的是匹配行的数量不是模式在文件中出现的总次数。如果同一行出现多次error-c仍然只把这一行计为一行。-o只输出匹配部分grep-oerrorapplication.log默认情况下grep输出整个匹配行使用-o后只输出实际匹配到的部分。组合选项多个短选项可以组合使用grep-niverrorapplication.log等价于grep-n-i-verrorapplication.log它会忽略大小写输出不匹配error的行并显示行号。二、搜索当前目录与子目录1.grep error *的实际含义greperror*这里的*不是由grep展开的而是先由 Bash 进行文件名展开。它通常匹配当前目录下的非隐藏名称。这意味着默认不匹配以.开头的隐藏文件不会自动搜索子目录中的文件如果展开结果包含目录grep可能报告目录相关错误。如果只想搜索当前目录下的普通文件可以根据实际文件类型限定名称例如grep-nerror./*.log2. 递归搜索搜索当前目录及所有子目录grep-rnerror.其中-r表示递归读取目录-n表示显示行号.表示当前目录。忽略大小写递归搜索grep-rnierror.只搜索.log文件grep-rn--include*.logerror.排除某个目录grep-rn--exclude-dir.giterror.GNU grep 将-r定义为递归读取目录中的文件同时允许通过--include、--exclude和--exclude-dir控制搜索范围。GNU Grep 文件与目录选择三、使用grep过滤进程信息grep不理解进程本身但可以过滤ps等命令输出的文本。例如psaux|grepnginx数据流向如下ps aux 输出的进程列表 ↓ 管道 ↓ grep 选择包含 nginx 的文本行这种写法可能同时匹配到grep nginx自身。常见规避写法是psaux|grep[n]ginx如果系统提供pgrep可以直接按照进程名或完整命令行搜索pgrep-afnginx其中-a显示完整命令行-f匹配完整命令行而不只匹配进程名。因此“使用 grep 过滤进程”的准确含义是使用grep过滤进程查询命令产生的文本。四、grep的退出状态grep不仅会输出文本还会通过退出状态告诉 Shell 匹配结果退出状态含义0至少选择到一行1没有选择到任何行2发生错误执行命令后可以通过$?查看上一条命令的退出状态grep-qerrorapplication.logecho$?-q表示安静模式不输出匹配内容适合只判断“是否存在匹配”。在 Bash 条件语句中可以直接使用ifgrep-qerrorapplication.log;thenecho发现错误记录elseecho没有发现错误记录fi根据 GNU Grep 官方说明正常情况下选中至少一行时返回0没有选中行时返回1发生错误时返回2。五、归档与压缩的区别归档和压缩经常一起使用但它们不是同一个概念。1. 归档或打包归档是把多个文件、目录及其结构组织到一个归档文件中。主要作用包括将多个文件组织成一个文件保留目录层级便于统一传输、备份和恢复根据归档格式保存权限、时间等元数据。2. 压缩压缩是通过压缩算法减少数据体积。主要作用包括减少存储空间减少网络传输的数据量在网络带宽有限时可能缩短总体传输时间。压缩不会改变网络信号或数据包的物理传播速度。最终是否节省时间还取决于压缩和解压消耗的 CPU 时间。ZIP 格式通常同时完成归档和压缩tar的核心功能是归档但可以调用 gzip、bzip2、xz 或 zstd 等压缩程序处理归档数据。六、zip与unzip1. 安装命令先检查命令是否已经存在zip--versionunzip-v如果提示命令不存在可以在 Ubuntu 中安装sudoaptupdatesudoaptinstallzipunzip2. 压缩单个文件ziparchive.zip file.txtarchive.zip是生成的 ZIP 文件file.txt是要加入归档的文件。一次压缩多个文件ziparchive.zip file1.txt file2.txt3. 递归压缩目录zip-rarchive.zip source_dir-r表示递归遍历目录。归档中会保留source_dir这一层目录名称及其内部结构。Ubuntu 的zip手册将-r定义为递归遍历目录结构。Ubuntuzip手册4. 查看 ZIP 内容unzip-larchive.zip该命令只列出归档内容不进行解压。5. 解压到当前目录unziparchive.zip不指定-d时默认解压到当前目录及其相应子目录。6. 解压到指定目录unziparchive.zip-dtarget_dir这里的-d target_dir表示将内容解压到target_dir不是“解压到当前目录”。Ubuntuunzip手册7. 测试 ZIP 文件完整性unzip-tarchive.zip该命令会检查归档成员能否正常读取但不会把内容正式解压到工作目录。七、tar创建和处理归档tar最初用于把多个文件按顺序保存到一个归档中。现在它常与压缩算法组合使用。基本形式为tar[操作选项][其他选项]-f归档文件[文件或目录...]-f表示后面的参数是归档文件名。1. 主要操作选项选项长选项功能-c--create创建新归档-x--extract从归档中提取文件-t--list查看归档成员列表-r--append向已有归档末尾追加成员-u--update追加不存在或版本更新的文件-d--diff、--compare比较归档成员与文件系统内容GNU tar 将-c、-t、-x定义为最常用的创建、查看和提取操作。GNU tar 官方手册2. 创建未压缩的 tar 归档tar-cfarchive.tar source_dir这个命令只创建归档没有使用 gzip、xz 等压缩算法。查看归档内容tar-tfarchive.tar解包tar-xfarchive.tar解包到指定目录mkdir-ptarget_dirtar-xfarchive.tar-Ctarget_dir3.-v显示处理过程-v表示 verbose可以显示正在处理的成员名称tar-cvfarchive.tar source_dirtar-xvfarchive.tar它不是创建或解压所必需的只用于显示更详细的信息。八、tar 与压缩算法1. gzip-z创建.tar.gztar-czfarchive.tar.gz source_dir查看内容tar-tzfarchive.tar.gz解压tar-xzfarchive.tar.gzgzip 的兼容性较好压缩和解压速度通常较快。2. bzip2-jtar-cjfarchive.tar.bz2 source_dirtar-xjfarchive.tar.bz2bzip2 通常比 gzip 更慢在部分数据上可以获得更好的压缩率但不能把这一点视为对所有数据都成立的绝对规律。3. xz-Jtar-cJfarchive.tar.xz source_dirtar-xJfarchive.tar.xzxz 通常可以获得较高压缩率但压缩过程可能消耗更多时间和内存。是否适合大文件要根据 CPU、内存、解压速度和兼容性要求决定。4. zstd--zstdtar--zstd-cfarchive.tar.zst source_dirtar--zstd-xfarchive.tar.zstzstd 通常在压缩速度、解压速度和压缩率之间具有较好的平衡但实际表现仍然取决于数据类型和压缩等级。5. 不要把算法特点写成绝对排名常见倾向可以概括为tar 选项格式常见特点-zgzip兼容性好速度较快-jbzip2速度较慢部分数据上压缩率优于 gzip-Jxz常见压缩率较高但压缩时间和内存开销较大--zstdzstd通常具有较好的速度与压缩率平衡压缩效果应通过实际文件测试不能脱离数据类型和参数给出绝对结论。九、向 tar 归档追加和更新文件1. 向未压缩归档追加文件tar-rfarchive.tar new_file.txt2. 只追加较新的文件tar-ufarchive.tar file.txt-u会在文件不存在于归档中或者文件系统中的版本更新时将其追加到归档末尾。3. 压缩归档通常不能直接追加下面的写法通常不能正常工作tar-rfarchive.tar.gz new_file.txt原因是 gzip、xz 等格式压缩的是整个 tar 数据流不能像普通.tar文件一样直接在归档末尾追加成员。如果需要频繁追加文件可以选择先维护未压缩的.tar完成后再压缩解压并重新创建归档使用更适合增量备份或版本管理的工具。GNU tar 官方文档明确说明普通压缩归档不能直接使用常规的更新或删除操作。十、什么是 ShellShell 是命令解释器同时也是一种脚本编程环境。它位于用户与操作系统提供的命令、程序和系统接口之间。Shell 的主要工作包括读取用户输入或脚本内容按照语法把输入解析成命令、参数和操作符展开变量、通配符和命令替换建立重定向与管道执行内建命令查找并启动外部程序等待同步命令结束并取得退出状态提供变量、条件、循环、函数等编程能力。GNU Bash 文档将 Shell 描述为命令解释器和编程语言它既能交互执行命令也能执行脚本。GNU Bash什么是 ShellShell 不是“保护内核”的安全外壳“外壳”这个名称可以帮助理解它位于用户和系统功能之间但不能把 Shell 描述成内核的安全保护层。Shell 可以让用户不必直接编写系统调用但它执行的命令仍然会根据当前用户权限访问内核提供的系统调用和资源。真正的安全边界还涉及用户身份、文件权限、Capabilities、命名空间、安全模块等机制。十一、Shell 与 Bash 的关系Shell 是一类程序Bash 是其中一种具体实现。常见 Shell 包括Shell ├── sh ├── Bash ├── dash ├── ksh ├── zsh └── fishBash 的全称是Bourne-Again Shell。它与传统的sh大体兼容并加入了许多交互和编程功能。GNU Bash 官方说明因此下面的说法不够准确Shell 是命令行程序的统称Bash 是 Linux 命令行的名称。更准确的说法是Shell 是命令解释器和脚本语言的一类实现Bash 是 Linux 与其他类 Unix 系统上常见的一种 Shell。Linux 并不强制所有用户使用 Bash。例如Ubuntu 的交互式用户 Shell 通常可以是 Bash而部分系统脚本中的/bin/sh可能由 dash 提供。十二、Bash 如何查找和执行命令输入下面的命令时greperrorapplication.logBash 不只是简单地“创建子进程”。它需要先完成一系列处理读取输入将输入拆分为单词和操作符处理引号执行参数、变量、通配符等展开设置重定向和管道判断命令是别名、函数、内建命令还是外部程序执行命令等待同步命令完成并取得退出状态。可以使用type查看一个名称由 Bash 如何解释typecdtypegrep输出可能类似cd is a shell builtin grep is /usr/bin/grep1. 内建命令cd是 Bash 内建命令cd/tmp它需要改变当前 Shell 自身的工作目录。如果在一个与当前 Shell 无关的子进程中执行子进程退出后当前 Shell 的目录不会发生变化。其他常见内建命令包括cd export alias history read type2. 外部程序grep通常是外部可执行程序typegrepBash 会按照命令名称进行查找。如果它既不是函数也不是内建命令并且命令名中没有/Bash 会在$PATH中查找可执行文件。查看当前搜索路径echo$PATHGNU Bash 文档说明Bash 会依次判断函数、内建命令和$PATH中的外部程序找到外部可执行文件后会在独立的执行环境中运行它。Bash 命令查找与执行3. 不是每条命令都会创建新子进程下面的描述过于绝对Shell → 创建子进程 → 执行所有命令更准确的描述是Shell 读取并解析命令 ↓ 判断命令类型 ↓ ├── 内建命令通常由当前 Shell 直接执行 └── 外部程序通常在独立执行环境中运行另外管道、后台任务、子 Shell、命令替换和 Shell 优化都会影响具体进程结构因此不能用一条固定流程覆盖全部情况。十三、常见误区误区一grep只能搜索普通字符串错误。grep默认使用基本正则表达式。需要按固定字符串搜索时可以显式使用-F。误区二必须先使用cat才能让grep搜索文件错误。grep可以直接接收文件名greperrorapplication.log管道适合处理其他命令产生的输出。误区三中文弯引号可以代替 Shell 引号错误。应使用英文半角或不能使用“ ”。误区四grep error *会递归搜索整个当前目录错误。*由 Bash 展开通常只匹配当前目录下的非隐藏名称。递归搜索应使用grep-rnerror.误区五grep -v会删除匹配内容错误。-v只是输出不匹配的行不会修改原文件。误区六unzip archive.zip -d target表示解压到当前目录错误。它表示解压到target不加-d才默认解压到当前目录。误区七tar就是压缩命令不准确。tar首先是归档工具。只有配合-z、-j、-J或--zstd等选项时才会进一步调用相应压缩方式。误区八压缩能够减少网络传播速度错误。压缩减少的是待传输数据量可能减少传输时间和网络流量不会降低物理传播速度。误区九xz 对所有大文件都是最佳选择错误。压缩格式选择需要综合考虑压缩率、压缩时间、解压速度、内存、兼容性和数据类型。误区十Shell 的作用是保护内核不准确。Shell 主要是命令解释器和脚本语言不是内核安全边界。误区十一Bash 就是 Linux 命令行的统一名称错误。Bash 是 Shell 的一种实现Linux 还可以使用 dash、zsh、fish 等其他 Shell。误区十二Shell 执行任何命令都会创建子进程错误。cd、export等内建命令通常由当前 Shell 执行外部程序通常在独立执行环境中运行。总结本次内容可以归纳为三个核心部分。第一grep是按行搜索与过滤文本的工具。它既可以直接读取文件也可以通过管道处理其他命令的输出。-n、-i、-v、-F、-r等选项分别控制行号、大小写、反向选择、固定字符串和递归搜索。第二归档与压缩需要分开理解。ZIP 通常同时负责归档和压缩tar主要负责组织归档并可以配合 gzip、bzip2、xz 和 zstd。压缩减少的是数据体积和传输量不会改变网络的物理传播速度。第三Shell 是命令解释器和脚本语言Bash 是一种具体 Shell。Bash 会解析命令、展开参数、建立重定向与管道并区分内建命令和外部程序。内建命令不一定创建子进程外部程序通常由 Bash 在独立的执行环境中启动。掌握这些关系后就能把文本过滤、管道、归档和命令执行机制连成一个整体而不是只记忆孤立的命令格式。参考资料GNU Grep调用语法GNU Grep完整官方手册GNU Grep文件与目录选择Ubuntu ManpageszipUbuntu ManpagesunzipGNU tar官方手册GNU tar全部选项GNU Bash什么是 ShellGNU Bash什么是 BashGNU Bash命令查找与执行