>> >> >> Reference << << << <<<<<<Ref>>>>>>
>> >> >> Indexer << << << <<<<<<Idx>>>>>>
Matched: 0

Tags

    Categories

      Types

        Top Results

          command
          M: 2026-04-21 - ljf12825

          Command in Linux

          Linux命令系统是基于Shell(常见的有bash, zsh, fish)的交互环境

          • 命令本质上就是一个程序(可执行文件),比如/bin/ls/usr/bin/grep
          • 在命令行里输入的东西,Shell负责解析,然后调用相应的程序执行

          所以“命令系统”不是内核强制规定的,而是围绕Unix哲学发展出来的一整套生态:

          “做一件事,并且把它做好。通过管道组合小工具,完成大任务”

          命令的组成结构

          在Linux中,一个命令通常由命令名+选项+参数组成

          ls -l /home/user
          
          • ls -> 命令名
          • -l -> 选项(长列表显示)
          • /home/user -> 参数(目标目录)

          选项有两种风格

          • 短选项:-l
          • 长选项:-all

          这套风格来自GNU工具链

          命令来源

          终端命令的来源主要来自于以下几个模块

          • Shell内置
          • GNU工具集
          • 其他软件
          • 用户自定义

          /bin

          bin=binary,存放可执行程序(二进制文件)

          存在意义

          系统最小可用,即:
          在系统刚启动时、还没挂载其他分区时就能用

          /bin, /usr/bin

          目录含义
          /bin启动和救援必须
          /usr/bin普通用户命令
          /sbin管理员命令
          /usr/sbin非关键管理员命令

          在大多数现代发行版中

          /bin -> /usr/bin
          /sbin -> /usr/sbin
          
          ls -l /bin
          

          可以看到

          /bin -> usr/bin
          

          这被称作usr merge,可以简化目录结构,减少重复,容器/initramfs更干净

          bin中的程序形态

          1. ELF二进制

          file /bin/ls
          

          输出类似

          ELF 64-bit LSB executable
          

          这是编译好的C程序,由内核直接加载执行

          2. Shell脚本

          file /bin/sh
          

          可能是

          symbolic link to dash
          

          #!/bin/sh
          

          但这并不代表用户可以自己往/bin内放程序
          这需要root权限,可能破坏系统一致性,还可能导致包管理器冲突
          正确的做法是\

          目的位置
          个人脚本~/bin
          本地工具/usr/local/bin
          系统包交给 apt/pacman

          /bin中程序的来源

          /bin不是一个“统一来源”的目录,它是多个软件包 + 多种构建方式的集合

          它大致包含:

          1.GNU coreutils: GNU官方,C语言实现,所有Linux必备 2.Shell相关:来源于不同项目bash,sh,dash,zsh等 3.util-linux:系统工具集 4.发行版自带/历史遗留工具 5.符号链接

          bin 是通过PATH找到的

          echo $PATH
          

          常见包含

          /usr/local/bin:/usr/bin:/bin
          

          当敲下ls时,Shell实际做的是

          1.在/usr/local/bin找 2.再/usr/bin 3.再/bin

          Shell内置命令

          Shell内置命令是指那些直接由Shell提供支持、实现并在Shell环境中执行的命令。它们不依赖于外部可执行文件,而是内建在Shell中。内置命令执行起来非常高效,因为它们不需要启动新的进程来执行任务,直接由Shell解释执行
          不同的Shell会有不同或额外的命令,下面是bash中的内置命令,可以通过man bash显示Bash的说明书,中有一个专门的章节详细描述来所有内置命令

          • cd:改变当前工作目录
          • pwd:打印当前工作目录路径
          • echo:输出内容
          • alias:创建命令别名
          alias ll='ls -l'
          
          • unalias:删除命令别名
          unalias ll
          

          export

          export是一个Shell内置命令,它的核心作用是:将变量设置为环境变量,使其能够被当前Shell启动的任何子进程(子Shell、脚本、其他命令)继承和使用

          基本用法
          # 先定义一个普通变量(Shell变量,只在当前Shell有效)
          MY_VAR="hello"
          
          # 导出为环境变量
          export MY_VAR
          
          # 或者定义的同时导出
          export MY_VAR="hello"
          
          主要区别
          类型定义方式作用范围子进程是否能看到
          Shell 变量VAR=value仅当前Shell不能
          环境变量export VAR=value当前Shell及所有子进程
          # 定义普通变量
          A=123
          
          # 定义并导出环境变量
          export B=456
          
          # 运行一个子 Shell
          bash
          
          # 在子Shell中
          echo $A # 输出空(看不到 A)
          echo $B # 输出 456 (能看到 B)
          exit # 退出子 Shell
          
          常见使用场景
          • 让子进程获得配置:如设置PATH, JAVA_HOME, PYTHONPATH
          export PATH=$PATH:/my/custom/bin
          
          • 临时设置程序运行参数:如让npm使用代理
          export HTTP_PROXY=http://proxy.example.com:8080
          
          • 在脚本中导出变量,以便被调用的其他脚本或命令使用
          查看与删除
          # 查看所有环境变量
          export
          
          # 或
          env
          
          # 删除一个环境变量
          unset MY_VAR
          
          特别注意
          • export只影响当前Shell及未来启动的子进程,不会影响父Shell或其他已运行的Shell
          • 想要永久生效,需要将export命令写入配置文件,如~/.bashrc, ~/.zshrc~/.profile
          • 在子进程中修改export的变量,不会传回父进程

          • unset:删除环境变量或Shell变量
          • env:查看环境变量
          • set:设置Shell变量和显示当前Shell环境的所有变量
          • exit:退出Shell或脚本,返回指定的状态码
          • return:从函数中返回,指定返回值
          • wait:等待后台进程完成
          • eval:计算并执行字符串中的命令
          • trap:设置一个命令,在指定信号时执行
          trap 'echo "Caught signal!"' SIGINT
          
          • if:条件语句
          if [ condition  ]; then
              # commands
          fi
          
          • for:循环语句
          for i in {1..5}; do
              echo $i
          done
          
          • while:条件循环语句
          while [ condition  ]; do
                  # commands
          done
          
          • case:条件判断的另一种形式
          case $variable in
            pattern1) command ;;
            pattern2) command ;;
            *) command ;;
          esac
          
          • continue:跳过当前循环的剩余部分,开始下一次循环
          • break:跳出循环
          • bg:将作业放到后台运行
          bg %1 # 将作业号为1的任务放入后台
          
          • fg:将后台作业调回到前台
          fg %1
          
          • jobs:列出当前Shell会话中的作业
          • kill:发送信号到进程(通常是用来终止进程)
          kill -9 1234 # 发送 SIGKILL信号,终止PID 1234的进程
          
          • history:显示命令历史
          • source.:执行文件中的命令,通常用于加载脚本
          source ~/.bashrc
          . ~/.bashrc
          
          • type:显示命令的类型(是内置命令,外部命令、函数等)
          • read:从标准输入读取一行数据
          • test:检查条件表达式(用于脚本中)
          test -f file.txt && echo "File exists"
          
          • let:执行算术运算
          let result=5+3
          
          • exec:替换当前Shell进程为指定的命令
          exec ls -l
          

          GUN Utilities

          GUN工具集(GNU Utilities)是指GNU项目提供的一整套自由软件开发与系统工具集合,它构成了现代Unix/Linux系统的基础生产力层

          GNU Coreutils

          GNU Coreutils是GNU最核心的部分,是GNU项目提供的一组最基础、最核心的用户空间命令行工具集合。它定义了一个最小可用的Unix用户空间长什么样。它包含日常必备的基础命令,覆盖三大类

          • 文件操作类
          • 文本处理类
          • 系统操作类

          文件与目录操作

          ls

          ls(list directory contents),用于列出目录内容

          ls [options] [file/directory]
          

          选项

          -l

          详细列表格式

          -rw-r--r--  1 ljf12825 users   4096 Jan 12 20:31 main.cpp
          [1]        [2]  [3]      [4]    [5]     [6]         [7]
          权限与类型 硬链接数  所有者    所属组   大小     时间        文件名
          
          文件类型

          第1个字符

          字符含义
          -普通文件
          d目录
          l符号链接(软链接)
          c字符设备
          b块设备
          p管道
          s套接字
          权限位

          后9个字符

          • 前3位:user

          • 中3位:group

          • 后3位:others

          • r:读

          • w:写

          • x:执行

          • -:无权限

          • s:程序执行时临时获得文件所有者权限

          • t:常见于/tmp,只能删除自己创建的文件


          • h/--human-readable 人性化显示,文件大小用K, M, G表示

          • -1 每行显示一个文件

          • -m 用逗号分隔显示

          • -x 按行排列

          • -C 按列排列

          • -t 按修改时间排序(最新在前)

          • -r 反向排序,与其他参数共同使用

          • u 按访问时间排序

          • -c 按inode变更时间排序

          • --full-time 显示完整时间戳

          • -S 按文件大小降序

          • X 按扩展名排序

          • v 按版本号排序

          • U 不排序(按目录顺序)

          • -a 显示所有文件,包括隐藏文件(以.开头)

          • -A 显示所有文件,但不包括.和..

          • -R 递归显示子目录内容

          • -d 显示目录本身,而不是内容

          • F 添加文件类型标识符,/目录,*可执行文件,@符号连接,|,FIFO(管道),=套接字

          • --color=auto 用颜色区分文件类型(默认)

          • --color=always 总是显示颜色

          • --color=never 不显示颜色

          • -i 显示文件inode号

          • --author 显示文件作者

          • --hide=*.tmp 隐藏tmp文件

          • -I/--ignore 排除tmp文件


          cd

          cd(Change Directory),用于在文件系统的目录之间进行导航

          特殊符号

          • .表示当前目录(在cd中不常用,常用于其他命令)
          • ..表示父目录
          • ~表示当前用户的主目录
          • -表示上一次访问的目录(类似“后退”)

          pwd

          pwd(Print Working Directory),用于显示当前所在的目录的完整路径

          参数

          • -L(默认),显示逻辑路径(解析符号链接)
          • -P显示物理路径(不解析符号链接)

          为什么需要pwd?

          • 在多层目录中容易迷失当前位置
          • 脚本中需要绝对路径来确保操作正确
          • 排查问题时需要知道执行环境

          mkdir

          mkdir(Make Directory),用于在系统中创建新的目录

          基本语法

          mkdir [options] directoryname...
          

          基本用法

          • 创建单个目录
          mkdir folder1
          
          • 创建多个目录
          mkdir folder1 folder2 folder3
          
          • 创建带有空格的目录名
          mkdir "my folder"
          
          mkdir 'another folder'
          
          • 创建包含特殊字符的目录名
          mkdir folder-with-dash
          mkdir folder_with_underscore
          mkdir "folder with space"
          

          常用选项

          • -p, --parents:创建多层目录
          mkdir -p dir1/dir2/dir3
          

          如果父目录不存在,会自动创建,如果目录存在,不会报错

          一次性创建多层目录结构

          mkdir -p project/{src,test,docs,logs}
          # 创建:project/src, project/test, project/docs, project/logs
          
          • -m, --mode=MODE:设置目录权限
          mkdir -m 755 public_dir
          mkdir -m 700 private_dir
          
          • -v, --verbose:显示创建过程
          mkdir -v new_folder
          # 输出:mkdir: create directory 'new_folder'
          

          rmdir / rm -r

          • rmdir

          删除空目录,空是指,只含...,哪怕有任何文件或子目录(即使是隐藏的),都会失败

          rmdir存在的意义就是安全性优先,防止误操作

          rmdir -p a/b/c
          
          # a/
          # |__b/
          #    |__c/
          

          删除c -> b变空了删除b -> a变空了删除a,否则停下

          rm -r递归删除目录

          cp:复制文件或目录

          cp用来复制文件/目录

          cp [options] source destination
          cp [options] source... directory
          
          情况行为
          目标不存在新建
          目标是文件覆盖
          目标是目录复制到目录里

          OPTIONS

          -r/-R 递归复制
          cp -r src dst
          

          没有这个选项不能复制目录,-r-R在GNU cp中基本等价
          会跟随目录结构,不会自动保留元数据

          -a 归档模式
          cp -a src dst
          

          等价于

          cp -dR --preserve=all
          

          会保留以下内容

          • 权限
          • 所有者/组
          • 时间戳
          • 符号链接(不解引用)
          • 设备文件、FIFO

          复制目录,90%场景都应该使用-a

          -f/-i 覆盖行为控制
          • -f 强制覆盖不提示
          • -i 覆盖前询问
          cp -i a b
          cp -f a b
          
          -d/-P 不解引用软连接
          cp -d link dst
          

          复制的是link本身,而不是link指向的文件

          -L 解引用软连接
          cp -L link dst
          

          复制链接指向的内容,得到的是普通文件

          --preserve
          cp --preserve=mode,ownership,timestamps file dst
          

          cp -p file dst
          

          可保留属性

          属性说明
          mode权限
          ownershipuid/gid
          timestamps时间
          links硬链接
          xattr扩展属性
          contextSELinux

          -a = 全保留

          --no-preserve 不保留

          cp -a --no-preserve=ownership src dst
          
          -u 只在更新时复制
          cp -u src dst
          

          目标不存在或源比目标新时执行

          --remove-destination
          cp --remove-destination src dst
          

          先删dst再复制,可避免只读文件覆盖失败

          --sparse
          cp --sparse=always src dst
          

          保留空洞

          cp --reflink-auto a b
          
          • Btrfs/XFS
          • O(1)复制
          • 写时复制
          -v 显示过程
          --parents 将dst作为父目录
          cp --parents a/b/c.txt dst
          

          结果

          dst/a/b/c.txt
          
          cp vs rsync
          场景推荐
          简单复制cp
          大目录增量rsync
          断点续传rsync
          网络rsync
          保留全部属性cp -a / rsync -a

          mv:移动或重命名

          mv(move),用于移动或重命名文件和目录

          基本功能

          1.移动文件/目录:将文件从一个位置移动到另一个位置 2.重命名文件/目录:在原地更改文件/目录名 3.覆盖文件:如果目标文件已存在,默认会覆盖(无警告)

          基本语法

          mv [options] src/dir src/dir
          
          选项
          选项描述
          -i交互模式,覆盖前询问确认
          -f强制模式,不询问(默认行为)
          -n不覆盖已存在的文件
          -u只移动比目标文件新的文件
          -v详细模式,显示操作过程
          -b覆盖前为目标文件创建备份
          -t dir先将目标目录指定,然后是要移动的文件

          使用

          1.重命名文件

          mv oldfile.txt newfile.txt
          # 将 oldfile.txt 重命名为 newfile.txt
          

          2.移动单个文件

          mv file.txt /home/user/documents/
          # 将 file.txt 移动到 documents 目录
          

          3.移动多个文件到目录

          mv file1.txt file2.txt file3.txt /target/directory/
          # 将三个文件移动到目标目录
          

          4.移动目录

          mv dir1/ dir2/
          # 如果 dir2 不存在:将 dir1 重命名为 dir2
          # 如果 dir2 存在:将 dir1 移动到 dir2/ 目录下
          

          5.交互模式(避免误覆盖)

          mv -i source.txt target.txt
          # 如果 target.txt 已存在,会询问是否覆盖
          

          6.显示移动过程

          mv -v file.txt /backup/
          # 输出:'file.txt' -> '/backup/file.txt'
          

          7.不覆盖现有文件

          mv -n file.txt existing.txt
          # 如果 existing.txt 存在,则不移动/覆盖
          

          8.只移动较新的文件

          mv -u newfile.txt oldfile.txt
          # 只当 newfile.txt 比 oldfile.txt 新时才移动
          

          9.覆盖前创建备份

          mv -b source.txt target.txt
          # 如果 target.txt 存在,会先备份为 target.txt~
          

          rm:删除文件

          rm(remove),用于删除文件或目录

          rm删除的文件通常无法恢复,不像图形界面会进回收站

          Linux没有回收站,除非特殊配置,删除操作立即生效

          基本语法

          rm [options] file/dir...
          
          常用选项
          选项描述
          -f强制删除,不提示
          -r-R递归删除(用于目录)
          -i交互模式,删除前询问
          -v显示详细过程
          -d删除空目录
          --preserve-root不删除根目录(默认)
          --no-preserve-root允许删除根目录

          rm不是把文件内容清零,而是删除目录项(文件名),减少inode的引用技术,当引用计数为0 -> 数据库可被复用
          rm内部调用unlink()/unlinkat()
          rm为什么不提示成功:No news is good news rm可以删除正在使用的文件,进程仍能访问,文件名消失,程序结束后才真正释放空间

          cat

          cat(concatenate),把输入的内容原样输出到标准输出(stdout)

          用法

          查看文件内容
          cat a.txt
          

          a.txt的内容一次性全部输出,不分页,不暂停

          同时查看多个文件
          cat a.txt b.txt
          

          输出顺序

          a.txt内容
          b.txt内容
          

          中间不会自动加分隔符

          合并文件
          cat a.txt b.txt > all.txt
          
          • >:覆盖
          • >>:追加

          cat与重定向

          从标准输入读取
          cat
          

          然后输入

          hello
          world
          

          ^D(EOF)
          终端输出

          hello
          world
          
          手动创建文件
          cat > test.txt
          

          输入内容 -> ^D结束

          Here Document
          cat << EOF > config.ini
          [server]
          port=8080
          host=127.0.0.1
          EOF
          

          shell把内容交给cat

          参数

          • n 显示行号,所有行
          • b 只给非空行编号
          • A 显示不可见字符,$行尾,^ITab, ^MCR

          cat 不适合大文件,它会一次全部输出,终端会被卡住

          tac,cat的反向,输出方向和cat相反,从文档末尾->文档开头

          more/less

          moreless都是用于分页查看文件内容的工具,通常被称为分页器(pagers)

          特性moreless
          诞生时间1978年1984年
          名称含义显示更多更少即是更多
          向后滚动不支持支持
          向前搜索不支持支持
          向后搜索不支持支持
          行号显示有限支持支持
          文件内跳转有限灵活
          查看多个文件支持支持
          跟随模式不支持支持
          内存使用较少较多
          默认位置通常默认安装更现代的默认

          lessmore的增强版,现在基本都用less

          more

          基本语法
          more [options] file
          
          常用选项
          选项说明
          -d显示提示信息
          -f不折叠长行
          -l忽略换页符
          -p从指定行开始
          -s将多个空行压缩为一行
          +n从第n行开始显示
          +/pattern从匹配模式的第一行开始
          基本操作
          按键功能
          空格f向下翻一页
          Enter向下翻一行
          =显示当前行号
          :f显示文件名和行号
          qQ退出
          /字符串向前搜索字符串(有限)

          less

          Less is more 少即是多,功能比more更多

          基本语法
          less [options] file
          
          常用选项
          选项说明
          -N显示行号
          -i搜索时忽略大小写
          -I搜索时智能忽略大小写
          -S不换行(水平滚动)
          -F如果文件小于一屏,自动退出
          -X退出时不清理屏幕
          -R显示原始控制字符(如颜色)
          -M显示更多提示信息
          +/pattern从匹配模式开始
          +G直接跳转到文件末尾
          操作
          导航命令
          按键功能
          空格f向前翻一页
          b向后翻一页
          u向后翻半页
          Enterej向前一行
          yk向后一行
          g跳到文件开头
          G跳到文件末尾
          10g跳到第10行
          50%跳到文件的50%位置
          搜索命令
          按键功能
          /pattern向前搜索匹配模式
          ?pattern向后搜索匹配模式
          n重复上一次搜索(同方向)
          N重复上一次搜索(反方向)
          &pattern仅显示匹配的行
          Esc+u关闭高亮显示
          文件操作
          按键功能
          :e file打开新文件
          :n查看下一个文件(多文件时)
          :p查看上一个文件(多文件时)
          :x查看第一个文件
          h显示帮助
          qZZ退出
          标记和跳转
          按键功能
          mchar用字母标记当前位置
          'char跳转到标记的位置
          ''跳转到上次的位置
          特殊功能
          按键功能
          v用默认编辑器打开当前文件
          !command执行shell命令
          s file保存当前内容到文件
          F跟随模式(实时查看日志,类似tail -f
          使用示例

          1.查看文件并显示行号

          less -N lgofile.txt
          

          2.查看压缩文件

          # less可以直接查看压缩文件
          less access.log.gz
          less error.log.bz2
          zcat file.gz | less # 替代方法
          

          3.实时监控日志(跟随模式)

          less +F /var/lgo/syslog
          # 按 ^C 停止跟随,再按F恢复
          

          4.查看命令输出

          # 保留颜色输出
          ls --color=always | less -R
          grep --color=always "error" log.txt | less -R
          
          # 查看进程,按内存排序
          ps aux --sort=-%mem | less
          

          5.查看多个文件

          less file1.txt file2.txt file3.txt
          # 使用 :n 和 :p 在文件间切换
          

          6.查看文件特定部分

          # 只查看包含"ERROR"的行
          less -p ERROR log.txt
          
          # 查看第100-200行
          less +100 -p200 log.txt  # 从100行开始,显示到200行附近
          

          7.在less中执行命令

          # 在 less 中按 ! 然后输入命令
          !ls -la  # 查看当前目录,按回车返回less
          

          为什么需要分页器

          • more几乎不用
          • less广泛使用
          • most另一个分页器,功能介于more和less之间
          • bat 现代替代品,需要安装

          分页器在特定场景下有不可替代的作用

          • 只读查看
          • 启动和退出速度快
          • 可通过管道

          head/tail

          查看文件开头

          基本用法
          # 查看文件前10行(默认)
          head filename.txt
          
          # 查看指定行数(如5行)
          head -n 5 filename.txt
          head -5 filename.txt # 简写形式
          
          常用选项
          # 查看前100个字节
          head -c 100 filename.txt
          
          # 查看前1KB的内容
          head -c 1k filename.txt
          
          # 查看前1MB的内容
          head -c 1M filename.txt
          
          # 查看多个文件
          head file1.txt file2.txt
          
          # 显示文件名标题
          head -v filename.txt
          
          # 不显示文件名标题(默认多个文件时才显示)
          head -q file1.txt file2.txt
          

          tail

          查看文件结尾

          基本用法
          # 查看文件最后10行(默认)
          tail filename.txt
          
          # 查看指定行数(如20行)
          tail -n 20 filename.txt
          tail -20 filename.txt # 简写形式
          
          常用选项
          # 实时监控文件变化(日志监控神器)
          tail -f /var/log/syslog
          # 当文件新增内容时,实时输出
          
          # 监控文件变化,即使文件被重命名或重新创建
          tail -F /var/log/app.log
          
          # 查看最后100个字节
          tail -c 100 filename.txt
          
          # 从第10行开始显示到文件末尾
          tail -n +10 filename.txt
          
          # 查看最后50行并实时监控
          tail -n 50 -f access.log
          

          示例

          # 查看第11-20行(先取前20行,再取最后10行)
          head -n 20 file.txt | tail -n 10
          
          # 查看第5到15行
          sed -n '5,15p' file.txt # 替代方法
          

          wc

          wc(word count) 用来统计输出中的

          • 行数(lines)
          • 单词数(words)
          • 字节数(bytes)
          • 字符数(chars)

          默认输出三项

          wc file.txt
          

          输出

           120     900     6321 file.txt
          lines   words   bytes
          

          常用参数

          • -l 行数
          • -w 单词数
          • c 字节数
          • m 字符数(考虑Unicode)

          只看行数

          wc -l main.cpp
          

          同时看多个

          wc -l -w main.cpp
          

          底层本质

          wc -l
          

          统计的是换行符\n数量

          echo "你好" | wc -c # 7
          echo "你好" | wc -m # 3
          
          • -c是UTF-8字节数
          • -m是实际字符数

          wc本质就是一个

          while(read(buf)) {
              count '\n'
              count space-sep words
              count bytes
          }
          
          • 顺序IO

          • 状态机(单词边界判断)

          • 时间复杂度:O(n

          • 空间复杂度:O(1)

          也就是说,wc是最理想的流式算法范例

          grep

          grep(Global Regular Expression Print),从文本流中,按规则筛选你想要的行

          grep接受两种输入:

          1. 文件参数:grep pattern filename
          2. 标准输入:其他命令的输出

          示例

          grep "ERROR" server.log
          

          server.log中,找出包含ERROR的所有行

          参数

          • -i 忽略大小写
          • -n 显示行号
          • -v 取反(显示不匹配的行)
          • -r 递归目录
          • -l 只显示文件名
          • -L 只显示不包含匹配项的文件名
          • -c 统计匹配行数
          • -E 扩展正则
          • -F 当作普通字符串(不解析正则)
          • -w 精确匹配整个单词
          • -x 精确匹配整行
          • -o 只显示匹配部分
          • -h 不显示文件名前缀
          • -H 显示文件名前缀(默认)
          • A NUM 显示匹配行后的NUM行
          • B NUM 显示匹配行前的NUM行
          • C NUM 显示匹配行先后各NUM行

          grep与正则表达式

          正则表达式是grep的灵魂

          1. 匹配任意一个字符
          grep "pla.er" file.txt
          

          匹配

          • player
          • placer
          • plaXer
          2. 行首/行尾
          grep "^ERROR" log.txt
          

          以ERROR开头

          grep "failed$" log.txt
          

          以failed结尾

          3. 数量限定(需要-E)
          grep -E "a{3,5}" file.txt
          

          匹配

          • aaa
          • aaaa
          • aaaaa
          4. 或条件
          grep -E "ERROR|WARN" log.txt
          

          其他

          1. 显示高亮
          grep --color=auto ERROR log.txt
          
          2. 显示上下文
          grep -C 3 ERROR log.txt
          

          显示错误行前后3行

          3. 多条件过滤
          grep ERROR log.txt | grep timeout
          

          等价于:同时包含ERROR和timeout

          底层本质

          grep本质是

          while(read_line()) {
              if (regex_match(line))
                  print(line);
          }
          

          关键是

          • 正则状态机(DFA/NFA)
          • 流式处理
          • 不缓存全文件

          touch

          touch用来创建空文件,或者修改文件的时间戳(时间属性)

          它主要做两件事情

          1. 文件不存在 -> 创建新文件
          2. 文件存在 -> 更新访问时间/修改时间

          常见用法

          创建空文件
          touch a.txt
          

          效果

          • 如果a.txt不存在 -> 创建一个0字节文件
          • 如果存在 -> 不改内容,只改时间

          等价于

          > a.txt
          

          touch更语义化,也更安全

          一次创建多个文件
          touch a.txt b.txt c.txt
          

          时间戳相关

          Linux每个文件至少有三个时间

          时间含义
          atime最后访问时间
          mtime最后修改内容时间
          ctime最后状态改变时间(权限等)

          touch主要影响的是

          • atime
          • mtime
          1. 只改访问时间
          touch -a file.txt
          
          2. 只改修改时间
          touch -m file.txt
          
          3. 设置为指定时间
          touch -t 202401231530 file.txt
          

          格式

          YYYYMMDDhhmm
          
          4. 对齐另一个文件的时间
          touch -r source.txt target.txt
          

          target.txt的时间戳=source.txt

          本质

          touch就是一次open + utimensat系统调用封装

          核心行为

          1. 如果文件不存在 -> open(0_CREAT)
          2. 如果存在 -> utime / utimensat 修改inode时间戳

          diff

          diff用来比较两个文件(或目录),输出它们之间的差异(difference)

          基本用法

          比较两个文件

          diff a.txt b.txt
          

          输出的是行级别的差异

          a.txt

          hello
          world
          

          b.txt

          hello
          linux
          world
          

          diff输出

          1a2
          > linux
          

          意思是:在a.txt的第1行后,增加了一行linux

          统一格式

          diff -u a.txt b.txt
          

          输出(unified diff)

          --- a.txt
          +++ b.txt
          @@ -1,2 +1,3 @@
           hello
          +linux
           world
          
          • --- a.txt 原文件名
          • +++ b.txt 新文件名
          • @@ -1,2 +1,3 @@ hunk header
            • 格式是固定的 @@ -old_start,old_len +new_start,new_len @@
            • -1,2 旧文件:从第1行开始,共2行
            • +1,3 新文件:从第1行开始,共3行

          这就是Git, patch, code review, PR背后统一使用的格式

          git diff本质上就是一个高级版的diff + 内部算法 + 语义增强

          输出符号

          符号含义
          +新增
          -删除
          未变化
          @@变更块位置
          ---原文件
          +++新文件

          目录diff

          diff -r dir1 dir2
          

          递归比较整个目录树

          比如用于比较两次构建产物差哪了

          参数

          | 参数 | 含义 | | -u | 统一格式 | | -r | 递归比较目录 | | -q | 只告诉你是否不同 | | -w | 忽略所有空白 | | -b | 忽略多个空格差异 | | -B | 忽略空行 | | -i | 忽略大小写 | | -I | 忽略匹配行 |

          diff背后的算法

          diff本质是一个经典CS问题:最长公共子序列(LCS)

          给你两行文本

          A B C D E F
          A B X D E Y
          

          找最长公共子序列

          A B D E
          

          然后推导出

          • C -> X 是修改
          • F -> Y 是修改

          这就是diff的数学本质

          Git内部是优化版

          • Myers diff algorithm
          • O(ND)时间复杂度

          打包压缩

          Compress_Archive

          权限与用户

          • chmod:修改权限
          • chown:修改文件所有者
          • id:查看当前用户信息
          • whoami:当前登录的用户名
          • su:切换用户
          • sudo:以管理员权限执行命令
          • hostname:显示或设置系统主机名
          • last:显示用户登录日志
          • history:显示命令历史记录
          • passwd:修改用户密码
          • exit/logout:退出当前登录会话
          • shutdown:关闭或重启系统
          • reboot:重启系统
          • useradd/adduser:添加新用户
          • usermod:修改用户属性
          • userdel:删除用户

          系统与进程管理

          • ps:查看进程
          • top/htop:实时监控系统资源
          • kill:终止进程
          • pkill:按进程名终止进程
          • bg/fg:将进程置于后台/前台运行
          • jobs:查看当前后台任务列表
          • nohup:使进程在用户退出登录后继续运行
          • df:查看磁盘空间
          • du:统计目录大小
          • uptime:系统运行时间
          • uname:显示系统信息
          • date:显示或设置系统时间
          • mount/umount:挂载/卸载文件系统

          输入输出与管道

          常用工具命令

          • find:查找文件
          • sort:排序
          • uniq:去重
          • cut:按列截取
          • xargs:批量传递参数
          • awk:文本处理利器
          • sed:流编辑器,做文本替换、删除

          显示文件树

          tree

          这是最简单最通用的方案,一般Linux环境有,没有就apt install tree

          常用参数
          tree
          tree -L 2 # 限制深度
          tree -a # 包含隐藏文件
          tree -I "build" # 忽略目录
          tree > tree.txt # 导出到文件
          

          treel

          • Python CLI
          • 支持颜色、排序、大小、导出等
          pip install treel
          treel -d 2
          

          比tree现代

          treely

          • 支持.gitignore
          • 还能输出代码内容

          tree-node-cli

          npx tree-node-cli
          
          • 类似tree
          • 支持Node项目

          tree-maker-cli

          pip install tree-maker-cli
          tree-maker .
          
          • 可导出
          • 支持过滤/深度

          file

          file命令用于检测文件类型,在Linux中,文件不依赖扩展名来标识类型,file命令通过读取文件内容(如文件头、魔术数字等)来判断实际类型

          file [option] filename
          
          选项说明
          -b不显示文件名,只显示类型
          -i显示MIME类型(如text/plain
          -z查看压缩文件内部
          -L追踪符号链接的原文件
          -f从文件读取要检测的文件列表
          -s读取块设备或特殊文件

          示例

          基本用法

          $ file example.txt
          example.txt: ASCII text
          
          $ file srcipt.sh
          srcipt.sh: Bourne-Again shell srcipt, ASCII text executable
          
          $ file image.jpg
          image.jpg: JPEG image data, JFIF standard 1.01
          
          $ file /bin/ls
          /bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=daa5130f2a41f7fbc8662048f3294f3d439ca7ff, for GNU/Linux 3.2.0, stripped
          

          不显示文件名

          $ file -b example.txt
          ASCII text
          

          显示MIME类型

          $ file -i example.txt
          example.txt: text/plain; charset=us-ascii
          
          $ file -i image.png
          image.png: image/png; charset=binary
          

          查看压缩文件内容

          $ file -z archive.tar.gz
          archive.tar.gz: POSIX tar archive (GNU) (gzip compress data, from Unix)
          

          批量检测

          $ file *
          

          工作原理

          file和文件后缀完全不同

          mv test.txt test.jpg
          file test.jpg
          

          输出

          test.jpg: ASCII text
          

          file不相信扩展名,只相信内容

          file的判断逻辑主要靠

          1. Magic Number
          2. 文本检测
          3. 特殊格式解析

          Magic Number

          魔术数字是文件开头的特定字节序列

          文件格式魔术数字(开头字节)ASCII表示
          PNG89 50 4E 47 0D 0A 1A 0A‰PNG␍␊␚␊
          JPEGFF D8 FFÿØÿ
          PDF25 50 44 46%PDF
          ELF7F 45 4C 46␇ELF
          ZIP50 4B 03 04PK␃␄
          GZIP1F 8B-
          BMP42 4DBM
          MP3FF FB49 44 33ÿûID3

          file会读取头文件,然后匹配这些规则

          这些规则定义在

          /usr/share/misc/magic
          

          文本检测

          如果不是已知二进制,就判断是不是:

          • ASCII
          • UTF-8
          • Unicode

          特殊格式解析

          它还能识别

          • 压缩文件(zip, gzip)
          • 可执行文件(ELF)
          • 脚本(bash/python),通过shebang

          stat

          stat用来查看文件或文件系统的详细元信息,它比ls的输出更细致,更底层,更全面

          语法

          stat filename
          

          输出类似

            File: filename
            Size: 16088     	Blocks: 32         IO Block: 4096   regular file
          Device: 259,6	Inode: 8141737     Links: 1
          Access: (0775/-rwxrwxr-x)  Uid: ( 1000/username)   Gid: ( 1000/username)
          Access: 2025-12-30 10:01:34.697442095 +0800
          Modify: 2025-12-07 21:04:45.777580704 +0800
          Change: 2025-12-07 21:04:45.777592199 +0800
           Birth: 2025-12-07 21:04:45.764553639 +0800
          
          • File:文件名
          • Size:文件大小(Byte),(可以用read()读到的字节数)
          • Blocks / IO Block
            • Blocks:占用磁盘块数量
            • IO Blocks:文件系统块大小(比如 4096 bytes)
          • regula file:文件类型
          • Device:主设备号,次设备号;说明文件所在磁盘/分区
          • Inode:唯一编号,存储权限,拥有者,磁盘位置,时间信息;不存文件名
          • Links:硬链接数
          • Access:权限
          • Uid:用户信息
          • Gid:组信息
          • Access:最后访问时间,例如cat, less,程序读取
          • Modify:文件内容最后内容修改时间
          • Change:状态变化,inode matadata变化
          • Birth:创建时间,不是所有文件系统都支持,ext4/btrfs支持较好,有些系统会显示-

          常用参数

          简洁输出

          stat -c "%s %n" file
          

          输出文件大小 + 文件名

          自定义格式

          stat -c "Size: %s bytes, Inode: %i" file
          

          常见格式占位符

          格式含义
          %ssize
          %nfilename
          %iinode
          %Uuser name
          %Ggroup
          %apermissions
          %ymodify time

          查看文件系统信息

          stat -f .
          

          会显示文件系统容量,inode总数,剩余空间

          stat本质

          stat不是读文件内容,而是读filesystem metadata layer

          对应系统调用

          int stat(const char *path, struct stat *buf);
          

          Linux内核直接返回 inode 信息


          --

          command [options] -- [arguments]
          

          --是选项结束标志,意为后面所有内容都不再当作参数,而是当作普通输入

          Unix的设计哲学有:文件名可以是任何字符串,这就导致很多命令都会出现以下问题

          rm -f file.txt
          
          • -f是选项
          • file.txt是文件

          但如果文件名刚好是 -f 怎么办

          rm -f -f
          

          shell会误以为第二个-f也是参数
          结果可能变成

          • 强制模式
          • 或错误解析
          • 或直接行为不符合预期

          此时--可以告诉命令,后面的内容不要当参数解析

          rm -f -- -f
          

          -f就被当作普通文件

          示例

          删除奇怪名字文件

          rm -- -file
          

          grep 搜索内容

          grep -- -pattern file.txt
          

          搜索字符串-pattern,而不是参数

          编译器场景

          gcc -- -Wall
          

          这里-Wall会被当成源文件名

          本质

          shell的解析规则是

          command [options] [arguments]
          

          --是切换解析状态的分隔符

          等价于

          parse_mode = ARGUMENT_ONLY
          

          网络相关

          • ping:测试网络
          • curl/wget:下载文件、调接口
          • scp:跨机器复制文件
          • ssh:远程登录
          • ifconfig/ip:查看和配置网络接口
          • netstat:显示网络状态信息
          • ss:比netstat更快,功能类似

          软件包管理

          帮助

          • --help:命令自带的帮助
            • 定位:命令行内置的简易帮助
            • 用法:ls--help
            • 特点:
              • 内容最短小,直接列出常用参数
              • 基本上每个GNU命令都会支持
              • 不需要跳页,结果一屏幕看完,查参数非常快
          • man:manual
            • 定位:Unix传统命令参考手册
            • 用法:man ls就能看到ls命令的完整文档
            • 特点:
              • 内容比较标准化,每个命令的介绍基本都包括:NAME、SYNOPSIS、DESCRIPTION、OPTIONS、EXAMPLES
              • 结构清晰,适合快速查参数
            • 小技巧:
              • 翻页:空格(下翻),b(上翻)
              • 搜索:/关键字
              • 跳出:q
          • info:GNU info文档
            • 定位:GNU项目提供的“扩展手册”,比man更详细
            • 用法:info ls
            • 特点:
              • 支持“超链接”导航,像一本电子书,可以在不同章节间跳转
              • 内容往往比man全,比如coreutils的命令(ls,cp,mv等)在info里有更完整的介绍和教程感
            • 操作方式:
              • n=next(下一章),p=previous(上一章),u=up(回到上层),q=quit

          命令查看

          • compgen(在Bash下)
            • -c:列出当前Shell能执行的所有命令(内置 + 外部)
            • -b:列出所有内置命令
            • -a:列出所有别名
          • ls /bin /usr/bin /usr/local/bin:列出这些目录里的可执行文件(大多数命令就在那里)
          • which <命令>:查看某个命令的真实路径