Jiahong 的个人博客

凡事预则立,不预则废


  • Home

  • Tags

  • Archives

  • Navigation

  • Search

Python——ArgumentParser类的使用


整体说明

  • 在 Python 里,argparse.ArgumentParser() 是标准库 argparse 模块的核心部分,其主要功能是解析命令行参数
  • 大部分优秀的开源函数都会使用这个功能

代码示例

  • ArgumentParser类使用示例
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    import argparse

    def main():
    # 创建 ArgumentParser 对象
    parser = argparse.ArgumentParser(
    description='这是一个命令行工具演示程序',
    epilog='示例: python demo.py -n Alice -a 35 --verbose'
    )

    # 添加参数
    # 位置参数 (未添加-为前缀的是位置参数,位置参数是必须给出的)
    parser.add_argument('input_file', help='输入文件路径')

    # 可选参数(添加-或--的是可选参数),同一行可以同时注册-或--,都可以作为输入参数
    # # 但代码内部名字命名规则是--优先-,没有--时,代码内部-才会生效(比如下面的定义下,parser.output 和 parser.x 生效,但是 parser.o 会报错)
    parser.add_argument('-o', '--output', default='output/result.txt', help='输出文件路径') # 调用时使用args.output调用参数
    parser.add_argument('-x', help='x') # 调用时使用args.x调用参数
    parser.add_argument('-n', '--name', default='Guest', help='用户名称') # 调用时使用args.x调用参数
    parser.add_argument('--age', type=int, choices=range(30, 40), help='用户年龄(30-39)')
    # action='store_true'表示这是布尔变量,若传入命令行存在该参数,则该 Python 参数值为 true,否则为 false;'store_false' 则功能相反
    parser.add_argument('--verbose', action='store_true', help='显示详细输出')
    parser.add_argument('--color', choices=['red', 'green', 'blue'], default='blue', help='颜色选择')
    parser.add_argument('--scale', type=float, default=*0, help='缩放比例')

    # 互斥参数组,同时指定会出错
    group = parser.add_mutually_exclusive_group()
    group.add_argument('--fast', action='store_true', help='快速模式')
    group.add_argument('--slow', action='store_true', help='慢速模式')

    # * 解析参数
    args = parser.parse_args()

    print("args对象完整属性:", args.__dict__)
    print("--end--\n")
    # * 使用参数
    print(f"输入文件: {args.input_file}")
    if args.output:
    print(f"输出文件: {args.output}")
    print(f"用户名: {args.name}")
    if args.age:
    print(f"年龄: {args.age}")
    print(f"详细模式: {'是' if args.verbose else '否'}")
    print(f"颜色: {args.color}")
    print(f"缩放比例: {args.scale}")
    if args.fast:
    print("模式: 快速")
    elif args.slow:
    print("模式: 慢速")
    else:
    print("模式: 默认")


    if __name__ == '__main__':
    main()

    # args对象完整属性: {'input_file': 'text.txt', 'output': 'output/result.txt', 'x': None, 'name': 'Guest', 'age': 33, 'verbose': False, 'color': 'blue', 'scale': *0, 'fast': False, 'slow': False}
    # --end--
    #
    # 输入文件: text.txt
    # 输出文件: output/result.txt
    # 用户名: Guest
    # 年龄: 33
    # 详细模式: 否
    # 颜色: blue
    # 缩放比例: *0
    # 模式: 默认

Python 内部变量参数命名规则

  • - 和 -- 同时存在时,优先 -- 定义的变量
    • 注:传入时都可以使用,且没有优先级,只会用后面的覆盖前面的
  • --output-path 等会自动被转换成 parser.output_path 变量访问
    • 注:传入时还是必须跟参数定义方式对齐 --output-path
    • 当然:--output_path 也是相同的参数名 parser.output_path ,若同时定义了 --output_path 和 --output-path,则两者实际上是同一个参数,且互相之间可以被覆盖

ArgumentParser 类其他使用注意事项

  • 参数类型 :
    • 默认情况下参数是字符串类型,可以使用 type 指定其他类型
    • 常用类型:int, float, str (默认)
  • 参数种类 :
    • 位置参数:没有前缀,必须提供
    • 可选参数:以 - 或 -- 开头,可选提供
    • 注:位置参数是必须的,可选参数可通过增加 required=True 来设定为必须参数
  • 常用参数选项 :
    • help:参数的帮助信息
    • default:参数的默认值
    • choices:限制参数的取值范围
    • action:参数的动作,常见值:
      • store:存储参数值(默认)
      • store_true/store_false:存储布尔值
      • append:允许多次使用参数并存储为列表
  • 互斥参数 :
    • 使用 add_mutually_exclusive_group() 创建互斥组
    • 组内的参数不能同时使用
  • 帮助信息 :
    • description:程序的简要描述
    • epilog:帮助信息末尾的文本
    • 自动生成的帮助信息可以通过 -h 或 --help 查看
  • 错误处理 :
    • 当用户输入无效参数时,argparse 会自动生成错误信息并退出,会抛出 ArgumentError 或 SystemExit 异常
  • 子命令 :
    • 对于复杂的命令行工具,可以使用 add_subparsers() 实现子命令功能
    • 类似 git 的 commit, push 等子命令
  • 参数前缀 :
    • 通常单字母参数用 - 前缀,完整单词用 -- 前缀
    • 但这不是强制要求,只是约定俗成

Python——signal.signal函数处理OS信号


整体说明

  • signal.signal() 是 Python 中用于设置信号处理方式的核心函数
  • signal.signal()主要用于捕获和处理操作系统发送的各种信号(如中断信号、子进程状态变化信号等)

signal.signal 函数说明

  • 基本语法如下:

    1
    2
    3
    import signal

    signal.signal(signalnum, handler)
  • 参数说明:

    • signalnum:需要处理的信号类型(如 signal.SIGINT 表示键盘中断,signal.SIGCHLD 表示子进程状态变化等)
    • handler:信号处理函数(或特殊常量),用于定义收到信号后的行为

信号类型(signalnum)

  • 常见的信号常量包括:
    • signal.SIGINT:程序终止(Interrupt)信号,通常由 Ctrl+C 触发
    • signal.SIGTERM:终止请求,默认可以被捕获和处理
    • signal.SIGCHLD:子进程状态改变(终止、暂停等)时触发
    • signal.SIGKILL:强制终止信号(无法被捕获或忽略)
    • signal.SIGSTOP:暂停信号(无法被捕获或忽略)
  • 完整信号列表可通过 signal.__dict__ 查看
    • 也可以参考 Python 官方文档: signal — Set handlers for asynchronous events

处理函数(handler)

  • handler 可以是以下三种类型之一:

  • 自定义函数类型:

    • 函数需接收两个参数:signum(信号编号)和 frame(当前栈帧对象,可选)
    • 使用示例:
      1
      2
      3
      4
      5
      6
      def handle_sigint(signum, frame):
      print(f"\n收到信号 {signum},程序即将退出")
      exit(0)

      # 注册 SIGINT 信号的处理函数
      signal.signal(signal.SIGINT, handle_sigint)
  • 使用默认处理方式 ,即取值 signal.SIG_DFL

    • 此时表示使用默认处理方式(系统预设行为,如 SIGINT 默认终止程序)
    • 使用示例:
      1
      2
      # 恢复 SIGINT 的默认处理(取消自定义函数)
      signal.signal(signal.SIGINT, signal.SIG_DFL)
  • 使用忽略该信号处理方式 ,即取值 signal.SIG_IGN

    • 表示忽略该信号(不做任何处理)
    • 使用示例:
      1
      2
      # 忽略 SIGINT 信号(Ctrl+C 无效)
      signal.signal(signal.SIGINT, signal.SIG_IGN)

使用注意事项

  • 信号处理函数应尽量简单,避免包含复杂逻辑(如 I/O 操作、长时间阻塞等),否则可能导致程序不稳定
  • 部分信号(如 SIGKILL、SIGSTOP)无法被捕获或忽略,用于强制终止/暂停程序
  • 信号处理函数通常在主线程中执行,多线程程序中需谨慎处理信号,避免线程安全问题
  • 部分信号(如 SIGCHLD)在 Windows 系统中可能不支持,使用时需注意平台兼容性

Pyhton——有限迭代器转无限迭代器


整体说明

  • 本文记录一个非常有用的特别函数,可用于将有限的迭代器包装变成无限的迭代器(不停重复)

Python 生成器回顾

  • 斐波那契数列生成器定义和使用示例:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 以后调用这个函数不能再简单的理解为函数调用,要理解为创建生成器
    def fibonacci_generator(n):
    a, b = 0, 1
    count = 0
    while count < n:
    yield a # 返回当前值,并暂停函数执行
    a, b = b, a + b
    count += 1

    # 使用生成器
    fib_gen = fibonacci_generator(10) # 创建生成器对象
    for num in fib_gen: # for 循环访问 fib_gen即可,不需要再访问原始函数,原始函数调用一次足以
    print(num, end=" ")
    print("\n")

    # 0 1 1 2 3 5 8 13 21 34

代码外简单解释

  • 下面的程序定义了一个函数 infinite_iterator,可以对任意有限迭代器(如列表)无限次循环遍历
  • 每遍历一轮,先输出 “this”,再依次输出迭代器的所有元素
  • 整个过程是无限循环,除非手动终止
  • 代码示例:
    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
    from itertools import repeat

    def infinite_iterator(finite_iterator):
    """
    实现对有限迭代器的无限循环遍历
    每次循环开始时,先打印 "this",然后依次输出迭代器的所有元素

    参数:
    finite_iterator: 任意可迭代对象(如列表、元组等)

    实现原理:
    1. 使用 itertools.repeat(finite_iterator) 实现对同一个迭代器对象的无限重复
    2. 外层 for 循环每次进入时,先打印 "this"
    3. 使用 yield from finite_iterator,将 finite_iterator 的所有元素依次生成,finite_iterator 被访问完以后,才会进入下一个 yield(即下个 for 迭代)
    4. 这样,每次完整遍历 finite_iterator 后,又会重新开始新一轮遍历,整个过程无限循环
    注意:
    如果 finite_iterator 是可迭代但不可重复遍历的(如生成器),第二轮开始时将不再有元素
    """
    for _ in repeat(finite_iterator): # 无限循环
    print("this") # 每轮遍历前打印
    yield from finite_iterator # 依次输出所有元素

    # 创建生成器,循环遍历 [1, 2, 4]
    iter_x = infinite_iterator([1, 2, 4])

    # 无限输出 "this, 1, 2, 4, this, 1, 2, 4, this, ...",直到手动终止
    for i in iter_x:
    print(i)

预估——CTR预估中的样本采样

  • 参考链接:
    • 参考文献:ctr 校准的方式
    • 论文:《Practical Lessons from Predicting Clicks on Ads at Facebook》

CTR 预估的样本采样

  • CTR 预估任务中,正负样本可能偏差很多,此时需要做样本采样,以提升训练速度和效果
    • “负采样可以提升训练速度和模型效果”来自论文《Practical Lessons from Predicting Clicks on Ads at Facebook》

CTR 预估样本采样后的校准

  • 方法一
    • 参见ctr 校准的方式中的推导
  • 方法二【常用方式】
    • 假设负采样比例为 \(w\),原始预估值为 \(p\),则校准后的预估值 \(q\) 为:
      $$
      \begin{align}
      q = \frac{p}{p+(1-p)/w}
      \end{align}
      $$
    • 具体实现如下:
      1
      2
      3
      logits = ctr_mlp_layer(input)
      pctr = tf.nn.sigmoid(logits)
      final_pctr = pctr / (pctr + (1 - pctr) / negative_downsampling_rate)

Linux——在root用户下也无法删除文件

本文介绍Linux中即使是root用户,某些特殊文件也无法删除的问题

  • 相关指令:
    • chattr
    • lsattr

问题来源

  • chattr命令给予用户权限去修改文件属性已提高系统的安全性
    • 注意chattr命令不能保护/, /dev, tmp, var目录(本身)
  • 其中一个属性i可以使得文件无法被删除,重命名,设置链接,同时不能修改内容等
    • 添加i属性指令: chattr +i [filename]
    • 移除i属性指令: chattr -i [filename]
  • 问题特征表现为,在root用户权限下,某些文件无法删除,报错为:

    rm: cannot remove ‘[filename]’: Operation not permitted


解决方案

  • 查看文件属性

    1
    lsattr [filename]
    • 此时文件属性中会多一个i属性
  • 删除文件i属性

    1
    chattr -i [filename]
    • 文件i属性删除后可以正常修改或者删除文件了

相关说明

  • 参考博客链接为: http://www.ha97.com/5172.html

    + :在原有参数设定基础上,追加参数
    - :在原有参数设定基础上,移除参数
    = :更新为指定参数设定
    A:文件或目录的 atime (access time)不可被修改(modified), 可以有效预防例如手提电脑磁盘I/O错误的发生
    S:硬盘I/O同步选项,功能类似sync
    a:即append,设定该参数后,只能向文件中添加数据,而不能删除,多用于服务器日志文件安全,只有root才能设定这个属性
    c:即compresse,设定文件是否经压缩后再存储。读取时需要经过自动解压操作
    d:即no dump,设定文件不能成为dump程序的备份目标
    i:设定文件不能被删除、改名、设定链接关系,同时不能写入或新增内容。i参数对于文件 系统的安全设置有很大帮助
    j:即journal,设定此参数使得当通过mount参数:data=ordered 或者 data=writeback 挂 载的文件系统,文件在写入时会先被记录(在journal中)。如果filesystem被设定参数为 data=journal,则该参数自动失效
    s:保密性地删除文件或目录,即硬盘空间被全部收回
    u:与s相反,当设定为u时,数据内容其实还存在磁盘中,可以用于undeletion
    各参数选项中常用到的是a和i。a选项强制只可添加不可删除,多用于日志系统的安全设定。而i是更为严格的安全设定,只有superuser (root) 或具有CAP_LINUX_IMMUTABLE处理能力(标识)的进程能够施加该选项


评论补充说明

  • 参考地址: http://www.ha97.com/5172.html 的评论部分

    i: 将无法对文件进行修改,若对目录设置后则仅能修改子文件而不能新建或删除
    a: 仅允许补充(追加)内容.无法覆盖/删除(Append Only)
    S: 文件内容变更后立即同步到硬盘(sync)
    s: 彻底从硬盘中删除,不可恢复(用0填充原文件所在硬盘区域)
    A: 不再修改这个文件的最后访问时间(atime)
    b: 不再修改文件或目录的存取时间
    D: 检查压缩文件中的错误
    d: 当使用dump命令备份时忽略文件/目录
    c: 默认将文件或目录进行压缩
    u: 当删除此文件后依然保留其在硬盘中的数据,方便日后恢复
    t: 让文件系统支持尾部合并(tail-merging)
    X: 可以直接访问压缩文件的内容。

ML——各种数据分析图介绍.md

[日常编辑]
Python数据分析时可能用到各种各样的图,本文将简单介绍数据分析中常用的几种基本图


直方图(Hist-plot)


柱形图(Dist-plot)

seaborn.distplot

  • 集合了matplotlib的hist()与核函数估计kdeplot的功能

核密度估计图(KDE-plot)

seaborn.kdeplot


箱式图(Box-plot)

  • 箱式图,是指—种描述数据分布的统计图
  • 是表述最小值、第一四分位数、中位数、第三四分位数与最大值的一种图形方法
  • 可以粗略地看出数据是否具有对称性,分布的分散程度等信息

异常值

又称离群值(Outlier), 指不在区间[Q1-1.5IQR, Q3+1.5IQR]中的值

  • Q1为25%中位数,也称为下四分位数
  • Q3为75%中位数,也称为上四分位数
  • IQR为Q3-Q1,四分数间距

绘图方法

去除离群值之后的部分计入图中,分别标记五个特征值

  • 特征值 最小值,Q1,中位数,Q3,最大值
  • 将五个数值描绘在一个图上,五个特征值在一个直线上
  • 最小值和Q1连接起来,Q1、中位数、Q3分别作平行等长线段
  • 连接两个四分位数构成箱子
  • 连接两个极值点与箱子,形成箱式图
  • 最后点上离群值

实例

  • 箱式图示例:

小提琴图(Violin-plot)

  • 用于显示数据分布及其概率密度
  • 竖向显示类似于箱式图,横向表征密度分布,越宽的地方密度分布越高

ML——课程学习


整体说明

  • 在机器学习领域,课程学习(Curriculum Learning,CL) 训练策略,适用场景广泛,包括监督学习,强化学习等场景
  • 课程学习的核心思想是让模型从简单任务逐步过渡到复杂任务,如同人类在学习新知识时先掌握基础概念,再逐渐挑战更难的内容
  • 思路 :人类学习遵循“从易到难”的顺序,课程学习希望通过模拟这一过程,提升机器学习模型的学习效率和泛化能力
  • 定义 :通过设计一个“课程”,即按照任务难度排序的训练数据序列,让模型先在简单任务上学习,再逐步增加任务复杂度,最终掌握目标任务
  • 优点:
    • 从简单任务入手可帮助模型更快收敛,减少训练时间(如CV中先学识别简单物体边缘,再学完整物体)
    • 逐步积累的知识体系让模型更适应复杂场景,减少过拟合(如语音识别中先学干净语音,再学带噪声语音)
    • 复杂任务直接训练可能陷入局部最优,课程学习通过分阶段优化降低难度(如神经网络训练中的逐层预训练)
  • 它不仅适用于传统监督学习,还在强化学习、多任务学习等领域展现出潜力。随着算法对“任务难度”理解的深化,未来课程学习可能成为解决复杂AI任务的关键策略之一

课程学习中的核心概念

  • 任务难度定义 :衡量任务的“难易程度”,常通过数据的特征复杂度、样本数量和模型在任务上的预测准确率等来评估任务难度
  • 课程设计策略 :人工划分或自动划分
    • NLP 中先学短文本分类,再学长文本(人工划分)
    • 基于数据相似度聚类,先训练简单簇,再逐步引入复杂簇(自动划分)
    • 根据模型当前表现,动态选择下一个合适的任务(自动划分)
  • 训练过程 :模型在每阶段完成后,保留已学知识,并将新知识与旧知识结合,避免“灾难性遗忘”

典型示例

  • CV-图像分类:先学识别猫狗等简单动物,再学区分稀有物种
  • CV-目标检测:先学大尺寸物体检测,再学小尺寸物体检测
  • NLP-机器翻译:先学短句翻译,再学复杂长句翻译
  • NLP-问答系统:先回答事实性问题,再处理推理类问题
  • RL-游戏AI:如 AlphaGo 先学基础落子规则,再学复杂策略
  • RL-机器人控制:先学基础动作(如行走),再学复杂任务(如避障)
  • 推荐系统:先学基础用户偏好,再学个性化长尾推荐

一些相关名词辨析

  • 课程学习
    • 主动按难度排序任务,强调“从易到难”的顺序性,适用于复杂任务分步训练
  • 迁移学习
    • 从源任务迁移知识到目标任务,重点在知识迁移而非任务排序,主要强调跨领域知识复用
  • 元学习
    • 强调学习“如何学习”,关注快速适应新任务的能力,着重在少样本学习场景中使用
  • 增量学习
    • 逐步添加新数据,防止遗忘旧知识,重点在记忆保留,主要在动态数据场景

Python——如何优雅的导入自定义的Python包


对于IDEA的管理

  • 在IDEA中运行文件时,当前项目根目录会默认被添加为Python的搜索路径
  • 根目录下的文件可以直接被访问
  • 根目录的子目录需要每一层都添加__init__.py文件,将其编译为包

IDEA项目用命令行运行

  • 在运行的第一个文件中添加IDEA项目的根目录作为搜索路径

    • 这里的根目录最好是绝对路径
      1
      2
      import sys
      sys.path.append("/home/xxx/xxx/xxx")
  • 如果是想使用相对路径,从而方便移植也行,但需要获取当前文件的文件路径,然后从当前文件与根目录的关系解析出根目录

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import os
    thisFileDir = os.path.split(os.path.realpath(__file__))[0]
    # we have to modify the tail if we change the path of this python file
    tail = 6
    rootPath = thisFileDir[0:-tail]
    if rootPath[-1] != "/" and rootPath[-1] != "\\":
    message = "Error root path [%s]\n\tPlease check whether you changed the path of current file" % rootPath
    raise Exception(message)
    print "Current root path: %s" % rootPath

    import sys
    sys.path.append(rootPath)
  • 其他的和在IDEA中运行一样,需要添加的库加上__init__.py即可

Linux——find命令详解


整体说明

  • tee 命令是 Linux 中的一个常用工具,主要功能是将标准输入同时输出到两个地方 :
    • 一个是标准输出(stdout,通常是终端屏幕)
    • 另一个是指定的文件
  • tee 命令的作用类似于“三通管”,既让数据在屏幕上可见,又能保存到文件中,避免了“输出重定向(>)会隐藏屏幕显示”的问题
  • TLDR:tee 的核心价值就是“一份输入,双重输出(屏幕 + 文件)”,在需要同时查看和保存命令结果时非常方便

基本用法示例:

  • 查看系统信息并保存到文件:

    1
    uname -a | tee system_info.txt
    • 屏幕上会显示 uname -a 的输出结果
    • 同时会创建 system_info.txt 文件,内容与屏幕输出一致
  • 使用 -a 选项可以追加内容(默认是覆盖文件):

    1
    echo "新内容" | tee -a system_info.txt
    • 屏幕显示“新内容”
    • 同时将“新内容”追加到 system_info.txt 末尾,原有内容保留

技巧:配合 sudo 编辑无写入权限的文件

  • 这是 tee 非常实用的场景

  • 例如,普通用户想向 /etc 目录下的文件写入内容(需要 root 权限):

    1
    echo "配置内容" | sudo tee /etc/some_config.conf
  • 避免了直接用 sudo echo "..." > /etc/... 因权限问题失败的情况

  • 既能看到输出,又能正确写入有权限要求的文件

Linux——tmux工具使用说明


整体说明

  • tmux(Terminal Multiplexer 的缩写)是 Linux/Unix 系统的一款优秀的终端复用工具 (一般 Linux 系统默认自带,无需封装),也是 GNU Screen 的升级版,功能更强大、设计更优雅
  • tmux 的核心作用包括:
    • 1)借助 tmux,在远程连接服务器时,即使 断开 SSH 连接、终端关闭、网络中断 ,tmux 里运行的程序也不会停止,重新连接后可无缝恢复会话继续操作
    • 2)一个终端窗口中,创建 多个会话、多个窗口、多个分屏面板 ,无需开多个终端窗口,高效管理多个任务
    • 3)支持会话分离/接入、窗口切换、面板缩放、快捷键操作等,是后端开发/运维必备工具

安装 tmux

  • 几乎所有 Linux 发行版都能通过包管理器一键安装,系统默认一般不带,执行对应命令即可

  • CentOS / RHEL / Fedora (yum/dnf)

    1
    2
    yum install -y tmux  # CentOS7
    dnf install -y tmux # CentOS8+/Fedora
  • Ubuntu / Debian / Deepin (apt)

    1
    apt update && apt install -y tmux
  • MacOS (brew)

    1
    brew install tmux
  • 安装完成后,终端输入 tmux -V 验证版本,显示版本号即安装成功


tmux 核心概念

  • tmux 的结构是 会话 > 窗口 > 面板 三层嵌套,从大到小 包含关系

会话 (Session)

  • 最顶层的独立运行环境,一个 tmux 可以创建多个相互独立的会话
  • 每个会话有唯一的「会话名」或「会话ID」,可以随时分离(detach) 或接入(attach)
  • 分离会话:会话在后台继续运行,当前终端退出 tmux 界面
  • 接入会话:重新进入之前分离的会话,恢复所有操作界面,程序正常运行

窗口 (Window)

  • 一个会话里可以创建多个 窗口 ,默认占满整个屏幕,窗口之间可以快速切换
  • 类似浏览器的 标签页,比如:一个窗口跑项目日志、一个窗口执行代码部署、一个窗口做文件编辑

面板 (Pane)

  • 一个窗口里可以分割成多个 面板(分屏),所有面板在同一个窗口中显示,共享当前会话环境
  • 类似终端的「分屏功能」,比如:左边面板编辑代码、右边面板实时运行程序,上下面板分别查看日志和执行命令

tmux 通用操作规则

  • tmux 所有的功能操作,都依赖 前缀键+ 功能键 的组合方式,这是 tmux 的核心操作逻辑:

前缀键 (Prefix Key)

  • 默认的前缀键是: Ctrl + b (先按住 Ctrl 和 b 一起松开,再按后面的功能键)

tmux 命令两种执行方式

  • 快捷键方式 :前缀键 + 功能键,效率最高,日常使用99%的场景都用这个;
  • 命令行方式 :在 tmux 终端中输入 tmux 命令参数,适合会话管理(创建/接入/删除)等场景

基础核心操作

  • 会话是 tmux 最核心的功能,所有操作都围绕会话展开,以下命令全部在系统原生终端执行(未进入 tmux 时)

  • 创建新会话

    1
    2
    tmux  # 创建无名称会话,默认会话ID从0开始
    tmux new -s 会话名 # 推荐!创建指定名称的会话,比如 tmux new -s project
  • 分离当前会话(核心!不会停止程序)

    • 方式一:进入 tmux 会话后,执行快捷键:Ctrl+b d(放开 CTRL+b 后再按 d)
    • 方式二:在 tmux 终端输入 tmux detach
    • 方式三:在其他外部终端输入 tmux detach -t 会话名/会话ID
    • 方式四:直接关闭窗口(SSH 或 网页窗口),不建议这种方式,可能存在问题?
    • 注:以上四种方式下,当前终端退出 tmux 界面,回到系统原生终端,tmux 会话在后台继续运行 ,里面的程序不会停止
  • 彻底关闭当前会话:

    1
    2
    exit # 简单命令
    tmux kill-session # 明确关闭当前 session
  • 查看所有后台会话

    1
    tmux ls  # 列出所有会话,格式:会话名: 窗口数 (创建时间) [终端大小]
  • 接入/恢复指定会话(核心)

    1
    2
    tmux a  # 简写,接入最近的一个会话
    tmux a -t 会话名/会话ID # 推荐!精准接入指定会话,比如 tmux a -t project
  • 关闭/杀死指定会话

    1
    2
    tmux kill-session -t 会话名/会话ID  # 比如 tmux kill-session -t project
    tmux kill-server # 慎用!杀死所有 tmux 会话,停止 tmux 服务
  • 重命名当前会话

    • 进入 tmux 会话后,快捷键:Ctrl+b $,然后输入新的会话名即可

窗口管理(待测试)

  • 窗口 = tmux 的 标签页,一个会话可以创建多个窗口,所有操作均在 tmux 会话内执行(快捷键为主)
  • 核心快捷键(均需先按 Ctrl+b 松开,再按对应键):
    • 1)c → 创建一个新的窗口(默认名称为当前路径)
    • 2)w → 弹出窗口列表,按上下键选择,回车切换
    • 3)n → 切换到下一个窗口(按创建顺序)
    • 4)p → 切换到上一个窗口(按创建顺序)
    • 5)数字键 0~9 → 快速切换到指定序号的窗口(窗口默认从0开始编号)
    • 6), → 重命名当前窗口(比如给窗口命名为 log、deploy、edit)
    • 7)& → 关闭当前窗口(会有确认提示,按 y 确认)
  • 注:这里有个 小技巧,tmux 底部状态栏会显示当前会话的所有窗口,* 标记的是当前激活的窗口

面板管理(待测试)

  • 面板 = tmux 的 分屏,一个窗口可以分割成多个面板,所有操作均在 tmux 会话内执行 ,这是 tmux 提升效率的核心功能
  • 核心快捷键(均需先按 Ctrl+b 松开,再按对应键):
  • 面板分割(创建面板)
    • %:垂直分割 ,将当前面板分成左右两个面板(最常用)
    • ":水平分割 ,将当前面板分成上下两个面板
  • 面板切换(重点)
    • 方向键 ↑ ↓ ← →,切换到对应方向的面板(最直观,推荐)
    • o,按顺序循环切换所有面板
    • ;, 切换到上一次操作的面板
  • 面板调整/操作
    • Ctrl + 方向键 , 调整当前面板的边框大小(按住 Ctrl+b 不放,再按方向键,持续调整)
    • x , 关闭当前面板(光标所在面板,会有确认提示,按 y 确认)
    • z , 面板最大化/还原 :当前面板占满整个窗口,再按一次恢复原大小(看日志/长代码必备)
    • ! , 将当前面板独立成新窗口 :适合需要单独放大某个面板的场景
1…293031…66
Joe Zhou

Joe Zhou

Stay Hungry. Stay Foolish.

659 posts
53 tags
GitHub E-Mail
© 2026 Joe Zhou
Powered by Hexo
|
Theme — NexT.Gemini v5.1.4