<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <author>
    <name>WangNingkai</name>
  </author>
  <generator uri="https://hexo.io/">Hexo</generator>
  <id>https://imwnk.cn/</id>
  <link href="https://imwnk.cn/" rel="alternate"/>
  <link href="https://imwnk.cn/atom.xml" rel="self"/>
  <rights>All rights reserved 2026, WangNingkai</rights>
  <subtitle>王宁凯的个人技术博客</subtitle>
  <title>个人技术分享站</title>
  <updated>2026-04-04T01:39:49.970Z</updated>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="ghostty" scheme="https://imwnk.cn/tags/ghostty/"/>
    <category term="terminal" scheme="https://imwnk.cn/tags/terminal/"/>
    <category term="productivity" scheme="https://imwnk.cn/tags/productivity/"/>
    <category term="starship" scheme="https://imwnk.cn/tags/starship/"/>
    <category term="zsh" scheme="https://imwnk.cn/tags/zsh/"/>
    <content>
      <![CDATA[<blockquote><p><strong>我无法再忍受 Oh My Zsh 的速度了。</strong> 这是我决定切换到 Starship 的根本原因。</p></blockquote><p>终端是开发者每天打交道最多的工具。一个快速、美观、高效的终端环境，能让开发体验提升好几个档次。这篇文章记录了我从 Oh My Zsh 到 Starship 的迁移过程，以及 Ghostty 终端的选择理由。</p><h2 id="为什么放弃-Oh-My-Zsh？"><a href="#为什么放弃-Oh-My-Zsh？" class="headerlink" title="为什么放弃 Oh My Zsh？"></a>为什么放弃 Oh My Zsh？</h2><p>用了五年 Oh My Zsh，它的生态和插件确实强大，但性能问题一直是个痛点：</p><table><thead><tr><th>痛点</th><th>具体表现</th></tr></thead><tbody><tr><td><strong>启动慢</strong></td><td>新终端窗口打开需要 1-2 秒，甚至更久</td></tr><tr><td><strong>延迟明显</strong></td><td>输入命令时有可感知的卡顿</td></tr><tr><td><strong>插件膨胀</strong></td><td>装了 20+ 插件，很多只是”可能用到”</td></tr><tr><td><strong>配置臃肿</strong></td><td><code>.zshrc</code> 超过 200 行，维护成本高</td></tr></tbody></table><p><strong>测试对比</strong>（我的 MacBook Pro M3 Pro）：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Oh My Zsh 启动时间</span></span><br><span class="line"><span class="keyword">time</span> zsh -i -c <span class="built_in">exit</span></span><br><span class="line"><span class="comment"># 0.85s - 1.2s</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Starship 启动时间  </span></span><br><span class="line"><span class="keyword">time</span> zsh -i -c <span class="built_in">exit</span></span><br><span class="line"><span class="comment"># 0.15s - 0.25s</span></span><br></pre></td></tr></tbody></table></figure><p><strong>5-8 倍的性能提升</strong>，这就是切换的最好理由。</p><h2 id="最终方案：Ghostty-ZSH-Starship"><a href="#最终方案：Ghostty-ZSH-Starship" class="headerlink" title="最终方案：Ghostty + ZSH + Starship"></a>最终方案：Ghostty + ZSH + Starship</h2><h3 id="整体架构"><a href="#整体架构" class="headerlink" title="整体架构"></a>整体架构</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">┌─────────────────────────────────────────────┐</span><br><span class="line">│                  Ghostty                     │</span><br><span class="line">│           (终端模拟器，渲染层)                │</span><br><span class="line">│   - GPU 加速渲染                             │</span><br><span class="line">│   - 透明背景 + 毛玻璃效果                    │</span><br><span class="line">│   - 现代字体渲染                             │</span><br><span class="line">└────────────────┬────────────────────────────┘</span><br><span class="line">                 │</span><br><span class="line">┌────────────────┴────────────────────────────┐</span><br><span class="line">│                   ZSH                        │</span><br><span class="line">│           (Shell，基础层)                    │</span><br><span class="line">│   - 极简配置 (~80 行)                        │</span><br><span class="line">│   - 只加载必要工具                           │</span><br><span class="line">│   - 无框架，原生体验                         │</span><br><span class="line">└────────────────┬────────────────────────────┘</span><br><span class="line">                 │</span><br><span class="line">┌────────────────┴────────────────────────────┐</span><br><span class="line">│                 Starship                     │</span><br><span class="line">│           (Prompt，展示层)                   │</span><br><span class="line">│   - Rust 编写，极速渲染                      │</span><br><span class="line">│   - 跨 Shell 兼容                           │</span><br><span class="line">│   - 高度可配置                              │</span><br><span class="line">└─────────────────────────────────────────────┘</span><br></pre></td></tr></tbody></table></figure><h3 id="为什么是-Ghostty？"><a href="#为什么是-Ghostty？" class="headerlink" title="为什么是 Ghostty？"></a>为什么是 Ghostty？</h3><p>之前用过 iTerm2、Alacritty、Kitty、Warp，最终选择 Ghostty 的原因：</p><table><thead><tr><th>特性</th><th>Ghostty</th><th>iTerm2</th><th>Alacritty</th><th>Kitty</th></tr></thead><tbody><tr><td><strong>启动速度</strong></td><td>⚡ 极快</td><td>慢</td><td>⚡ 极快</td><td>快</td></tr><tr><td><strong>渲染性能</strong></td><td>GPU</td><td>CPU</td><td>GPU</td><td>GPU</td></tr><tr><td><strong>内存占用</strong></td><td>~30MB</td><td>~200MB</td><td>~25MB</td><td>~40MB</td></tr><tr><td><strong>配置方式</strong></td><td>文件</td><td>GUI + 文件</td><td>文件</td><td>文件</td></tr><tr><td><strong>macOS 集成</strong></td><td>原生</td><td>原生</td><td>一般</td><td>一般</td></tr><tr><td><strong>中文支持</strong></td><td>完美</td><td>完美</td><td>需配置</td><td>需配置</td></tr></tbody></table><p>Ghostty 由 HashiCorp 创始人 Mitchell Hashimoto 开发，追求<strong>开箱即用的最佳实践</strong>，配置简单但功能强大。</p><h3 id="为什么是-Starship？"><a href="#为什么是-Starship？" class="headerlink" title="为什么是 Starship？"></a>为什么是 Starship？</h3><p>对比了 Powerlevel10k、Pure、Spaceship 后选择 Starship：</p><ul><li>⚡ <strong>极速</strong>：Rust 编写，渲染时间 &lt; 10ms</li><li>🔧 <strong>配置简单</strong>：一个 TOML 文件搞定</li><li>🌍 <strong>跨平台</strong>：支持 Bash、Zsh、Fish、PowerShell</li><li>📦 <strong>开箱即用</strong>：无需复杂配置就能很好看</li><li>🎨 <strong>高度可定制</strong>：想怎么改就怎么改</li></ul><h2 id="我的配置分享"><a href="#我的配置分享" class="headerlink" title="我的配置分享"></a>我的配置分享</h2><h3 id="Ghostty-配置"><a href="#Ghostty-配置" class="headerlink" title="Ghostty 配置"></a>Ghostty 配置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/Library/Application Support/com.mitchellh.ghostty/config</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 主题与字体</span></span><br><span class="line"><span class="attr">theme</span>                          = Aura</span><br><span class="line"><span class="attr">font-family</span>                    = Maple Mo<span class="literal">no</span> NF CN</span><br><span class="line"><span class="attr">font-size</span>                      = <span class="number">15</span></span><br><span class="line"><span class="attr">font-thicken</span>                   = <span class="literal">true</span></span><br><span class="line"><span class="attr">font-feature</span>                   = calt, cv01, cv03, ss01, ss02, ss03</span><br><span class="line"></span><br><span class="line"><span class="comment"># 窗口设置</span></span><br><span class="line"><span class="attr">window-height</span>                  = <span class="number">20</span></span><br><span class="line"><span class="attr">window-width</span>                   = <span class="number">100</span></span><br><span class="line"><span class="attr">window-padding-balance</span>         = <span class="literal">true</span> </span><br><span class="line"><span class="attr">window-save-state</span>              = always</span><br><span class="line"></span><br><span class="line"><span class="comment"># 透明效果</span></span><br><span class="line"><span class="attr">background-opacity</span>             = <span class="number">0.97</span></span><br><span class="line"><span class="attr">background-blur</span>                = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># macOS 集成</span></span><br><span class="line"><span class="attr">macos-titlebar-style</span>           = tabs</span><br><span class="line"><span class="attr">macos-option-as-alt</span>            = <span class="literal">true</span></span><br><span class="line"><span class="attr">macos-icon</span>                     = xray</span><br><span class="line"></span><br><span class="line"><span class="comment"># Shell 集成</span></span><br><span class="line"><span class="attr">shell-integration</span>              = zsh</span><br><span class="line"><span class="attr">shell-integration-features</span>     = cursor,sudo,title</span><br><span class="line"></span><br><span class="line"><span class="comment"># 性能优化</span></span><br><span class="line"><span class="attr">scrollback-limit</span>               = <span class="number">4200</span></span><br><span class="line"><span class="attr">window-vsync</span>                   = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><p><strong>关键配置说明</strong>：</p><ol><li><strong>字体选择</strong>：Maple Mono NF CN - 支持 Nerd Font 图标和中文</li><li><strong>透明度 0.97</strong>：微透明，既能看到背景又不影响阅读</li><li><strong>macos-titlebar-style = tabs</strong>：紧凑的标签栏样式</li><li><strong>shell-integration</strong>：启用 Ghostty 的 Shell 集成功能</li></ol><h3 id="ZSH-配置"><a href="#ZSH-配置" class="headerlink" title="ZSH 配置"></a>ZSH 配置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.zshrc - 极简配置</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 补全系统（无框架）</span></span><br><span class="line"><span class="keyword">if</span> <span class="built_in">type</span> brew &amp;&gt;/dev/null; <span class="keyword">then</span></span><br><span class="line">  FPATH=<span class="string">"<span class="subst">$(brew --prefix)</span>/share/zsh-completions:<span class="variable">$FPATH</span>"</span></span><br><span class="line"><span class="keyword">fi</span></span><br><span class="line"><span class="built_in">autoload</span> -Uz compinit &amp;&amp; compinit -C</span><br><span class="line"></span><br><span class="line"><span class="comment"># 环境变量</span></span><br><span class="line"><span class="built_in">export</span> LANG=en_US.UTF-8</span><br><span class="line"><span class="built_in">export</span> EDITOR=<span class="string">"code --wait"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># PATH 配置</span></span><br><span class="line"><span class="built_in">export</span> GOPATH=<span class="variable">$HOME</span>/go</span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$GOPATH</span>/bin:<span class="variable">$PATH</span></span><br><span class="line"><span class="built_in">export</span> PNPM_HOME=<span class="string">"<span class="variable">$HOME</span>/Library/pnpm"</span></span><br><span class="line"><span class="built_in">export</span> PATH=<span class="string">"<span class="variable">$PNPM_HOME</span>:<span class="variable">$PATH</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 工具初始化（按需加载）</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(zoxide init zsh)</span>"</span>          <span class="comment"># 智能目录跳转</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(fnm env --use-on-cd)</span>"</span>      <span class="comment"># Node.js 版本管理</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(starship init zsh)</span>"</span>        <span class="comment"># Starship prompt</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># FZF 配置</span></span><br><span class="line"><span class="built_in">export</span> FZF_DEFAULT_OPTS=<span class="string">'--height 40% --layout=reverse --border'</span></span><br><span class="line"><span class="built_in">export</span> FZF_DEFAULT_COMMAND=<span class="string">'fd --type f --hidden --follow --exclude .git'</span></span><br><span class="line"><span class="built_in">source</span> &lt;(fzf --zsh)</span><br><span class="line"></span><br><span class="line"><span class="comment"># 实用别名</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">cat</span>=<span class="string">'bat --paging=never'</span></span><br><span class="line"><span class="built_in">alias</span> l=<span class="string">'lsd -l'</span></span><br><span class="line"><span class="built_in">alias</span> la=<span class="string">'lsd -a'</span></span><br><span class="line"><span class="built_in">alias</span> lt=<span class="string">'lsd --tree'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Yazi 文件管理器（退出时 cd）</span></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">y</span></span>() {</span><br><span class="line">  <span class="built_in">local</span> tmp=<span class="string">"<span class="subst">$(mktemp -t <span class="string">"yazi-cwd.XXXXXX"</span>)</span>"</span> cwd</span><br><span class="line">  <span class="built_in">command</span> yazi <span class="string">"<span class="variable">$@</span>"</span> --cwd-file=<span class="string">"<span class="variable">$tmp</span>"</span></span><br><span class="line">  IFS= <span class="built_in">read</span> -r -d <span class="string">''</span> cwd &lt; <span class="string">"<span class="variable">$tmp</span>"</span></span><br><span class="line">  [ <span class="string">"<span class="variable">$cwd</span>"</span> != <span class="string">"<span class="variable">$PWD</span>"</span> ] &amp;&amp; [ -d <span class="string">"<span class="variable">$cwd</span>"</span> ] &amp;&amp; <span class="built_in">builtin</span> <span class="built_in">cd</span> -- <span class="string">"<span class="variable">$cwd</span>"</span></span><br><span class="line">  <span class="built_in">rm</span> -f -- <span class="string">"<span class="variable">$tmp</span>"</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p><strong>设计原则</strong>：</p><ol><li><strong>无框架</strong>：不用 Oh My Zsh、Prezto 等，保持轻量</li><li><strong>按需加载</strong>：只初始化真正需要的工具</li><li><strong>现代替代品</strong>：<ul><li><code>ls</code> → <code>lsd</code>（现代 ls，支持图标和颜色）</li><li><code>cat</code> → <code>bat</code>（语法高亮）</li><li><code>cd</code> → <code>zoxide</code>（智能跳转）</li><li><code>find</code> → <code>fd</code>（更快的查找）</li></ul></li></ol><h3 id="Starship-配置"><a href="#Starship-配置" class="headerlink" title="Starship 配置"></a>Starship 配置</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/starship.toml</span></span><br><span class="line"></span><br><span class="line"><span class="attr">format</span> = <span class="string">"""</span></span><br><span class="line"><span class="string">[ ](red)\</span></span><br><span class="line"><span class="string">$os\</span></span><br><span class="line"><span class="string">$username\</span></span><br><span class="line"><span class="string">[ ](bg:peach fg:red)\</span></span><br><span class="line"><span class="string">$directory\</span></span><br><span class="line"><span class="string">[ ](bg:yellow fg:peach)\</span></span><br><span class="line"><span class="string">$git_branch\</span></span><br><span class="line"><span class="string">$git_status\</span></span><br><span class="line"><span class="string">[ ](fg:yellow bg:green)\</span></span><br><span class="line"><span class="string">$c\</span></span><br><span class="line"><span class="string">$rust\</span></span><br><span class="line"><span class="string">$golang\</span></span><br><span class="line"><span class="string">$nodejs\</span></span><br><span class="line"><span class="string">$php\</span></span><br><span class="line"><span class="string">$python\</span></span><br><span class="line"><span class="string">[ ](fg:green bg:sapphire)\</span></span><br><span class="line"><span class="string">$conda\</span></span><br><span class="line"><span class="string">[ ](fg:sapphire bg:lavender)\</span></span><br><span class="line"><span class="string">$time\</span></span><br><span class="line"><span class="string">[ ](fg:lavender)\</span></span><br><span class="line"><span class="string">$cmd_duration\</span></span><br><span class="line"><span class="string">$line_break\</span></span><br><span class="line"><span class="string">$character"""</span></span><br><span class="line"></span><br><span class="line"><span class="attr">palette</span> = <span class="string">'catppuccin_mocha'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[os]</span></span><br><span class="line"><span class="attr">disabled</span> = <span class="literal">false</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:red fg:crust"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[os.symbols]</span></span><br><span class="line"><span class="attr">Macos</span> = <span class="string">" "</span></span><br><span class="line"></span><br><span class="line"><span class="section">[username]</span></span><br><span class="line"><span class="attr">show_always</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">style_user</span> = <span class="string">"bg:red fg:crust"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[ $user]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[directory]</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:peach fg:crust"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">"[ $path ]($style)"</span></span><br><span class="line"><span class="attr">truncation_length</span> = <span class="number">3</span></span><br><span class="line"></span><br><span class="line"><span class="section">[git_branch]</span></span><br><span class="line"><span class="attr">symbol</span> = <span class="string">" "</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:yellow"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[ $symbol $branch ](fg:crust bg:yellow)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[git_status]</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:yellow"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[($all_status$ahead_behind )](fg:crust bg:yellow)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[nodejs]</span></span><br><span class="line"><span class="attr">symbol</span> = <span class="string">" "</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:green"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[ $symbol( $version) ](fg:crust bg:green)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[golang]</span></span><br><span class="line"><span class="attr">symbol</span> = <span class="string">" "</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:green"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[ $symbol( $version) ](fg:crust bg:green)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[python]</span></span><br><span class="line"><span class="attr">symbol</span> = <span class="string">" "</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:green"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[ $symbol( $version)(\(#$virtualenv\)) ](fg:crust bg:green)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[time]</span></span><br><span class="line"><span class="attr">disabled</span> = <span class="literal">false</span></span><br><span class="line"><span class="attr">time_format</span> = <span class="string">"%R"</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:lavender"</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">'[[  $time ](fg:crust bg:lavender)]($style)'</span></span><br><span class="line"></span><br><span class="line"><span class="section">[cmd_duration]</span></span><br><span class="line"><span class="attr">show_milliseconds</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">format</span> = <span class="string">" in $duration "</span></span><br><span class="line"><span class="attr">style</span> = <span class="string">"bg:lavender"</span></span><br><span class="line"><span class="attr">show_notifications</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">min_time_to_notify</span> = <span class="number">45000</span></span><br><span class="line"></span><br><span class="line"><span class="section">[character]</span></span><br><span class="line"><span class="attr">success_symbol</span> = <span class="string">'[❯](bold fg:green)'</span></span><br><span class="line"><span class="attr">error_symbol</span> = <span class="string">'[❯](bold fg:red)'</span></span><br></pre></td></tr></tbody></table></figure><p><strong>效果展示</strong>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">󰀵 wangningkai   ~/Workplace/private/blog   main ≡   1.24   3.13  14:23 </span><br><span class="line">❯ </span><br></pre></td></tr></tbody></table></figure><p><strong>配置亮点</strong>：</p><ol><li><strong>Catppuccin Mocha 配色</strong>：统一美观的深色主题</li><li><strong>操作系统图标</strong>：一眼识别系统类型</li><li><strong>语言版本显示</strong>：自动检测当前目录使用的语言</li><li><strong>时间显示</strong>：方便追踪命令执行时间</li><li><strong>命令耗时通知</strong>：超过 45 秒自动弹出通知</li></ol><h2 id="迁移步骤"><a href="#迁移步骤" class="headerlink" title="迁移步骤"></a>迁移步骤</h2><p>如果你也想从 Oh My Zsh 迁移，这是我推荐的步骤：</p><h3 id="1-备份现有配置"><a href="#1-备份现有配置" class="headerlink" title="1. 备份现有配置"></a>1. 备份现有配置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">cp</span> ~/.zshrc ~/.zshrc.oh-my-zsh.backup</span><br><span class="line"><span class="built_in">cp</span> -r ~/.oh-my-zsh/custom ~/.oh-my-zsh-custom.backup</span><br></pre></td></tr></tbody></table></figure><h3 id="2-安装依赖工具"><a href="#2-安装依赖工具" class="headerlink" title="2. 安装依赖工具"></a>2. 安装依赖工具</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装 Starship</span></span><br><span class="line">brew install starship</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装现代工具替代品</span></span><br><span class="line">brew install zoxide lsd bat fd fzf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装 Nerd Font 字体</span></span><br><span class="line">brew install --cask font-maple-mono-nf-cn</span><br></pre></td></tr></tbody></table></figure><h3 id="3-创建新的-ZSH-配置"><a href="#3-创建新的-ZSH-配置" class="headerlink" title="3. 创建新的 ZSH 配置"></a>3. 创建新的 ZSH 配置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 备份旧配置</span></span><br><span class="line"><span class="built_in">mv</span> ~/.zshrc ~/.zshrc.backup</span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建新配置</span></span><br><span class="line"><span class="comment"># 将上面的配置保存到 ~/.zshrc</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建 Starship 配置目录</span></span><br><span class="line"><span class="built_in">mkdir</span> -p ~/.config</span><br><span class="line"><span class="comment"># 将 Starship 配置保存到 ~/.config/starship.toml</span></span><br></pre></td></tr></tbody></table></figure><h3 id="4-迁移自定义别名和函数"><a href="#4-迁移自定义别名和函数" class="headerlink" title="4. 迁移自定义别名和函数"></a>4. 迁移自定义别名和函数</h3><p>从备份中提取你常用的别名和函数，按需添加到新配置。</p><h3 id="5-测试并调整"><a href="#5-测试并调整" class="headerlink" title="5. 测试并调整"></a>5. 测试并调整</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 重新加载配置</span></span><br><span class="line"><span class="built_in">source</span> ~/.zshrc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试启动速度</span></span><br><span class="line"><span class="keyword">time</span> zsh -i -c <span class="built_in">exit</span></span><br></pre></td></tr></tbody></table></figure><h2 id="性能对比总结"><a href="#性能对比总结" class="headerlink" title="性能对比总结"></a>性能对比总结</h2><table><thead><tr><th>指标</th><th>Oh My Zsh</th><th>Starship</th><th>提升</th></tr></thead><tbody><tr><td>启动时间</td><td>~1.0s</td><td>~0.2s</td><td><strong>5x</strong></td></tr><tr><td>配置文件大小</td><td>200+ 行</td><td>~80 行</td><td><strong>2.5x</strong></td></tr><tr><td>内存占用</td><td>~50MB</td><td>~10MB</td><td><strong>5x</strong></td></tr><tr><td>输入延迟</td><td>可感知</td><td>无感知</td><td>✅</td></tr><tr><td>可维护性</td><td>中</td><td>高</td><td>✅</td></tr></tbody></table><h2 id="实用工具推荐"><a href="#实用工具推荐" class="headerlink" title="实用工具推荐"></a>实用工具推荐</h2><p>这套终端环境的其他实用工具：</p><table><thead><tr><th>工具</th><th>用途</th><th>替代</th></tr></thead><tbody><tr><td><strong>zoxide</strong></td><td>智能目录跳转</td><td><code>autojump</code></td></tr><tr><td><strong>lsd</strong></td><td>现代文件列表</td><td><code>ls</code></td></tr><tr><td><strong>bat</strong></td><td>语法高亮查看</td><td><code>cat</code></td></tr><tr><td><strong>fd</strong></td><td>快速文件查找</td><td><code>find</code></td></tr><tr><td><strong>fzf</strong></td><td>模糊搜索</td><td>-</td></tr><tr><td><strong>yazi</strong></td><td>终端文件管理器</td><td><code>ranger</code></td></tr><tr><td><strong>ripgrep</strong></td><td>快速文本搜索</td><td><code>grep</code></td></tr><tr><td><strong>dust</strong></td><td>磁盘占用分析</td><td><code>du</code></td></tr></tbody></table><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="Q-Oh-My-Zsh-的插件怎么办？"><a href="#Q-Oh-My-Zsh-的插件怎么办？" class="headerlink" title="Q: Oh My Zsh 的插件怎么办？"></a>Q: Oh My Zsh 的插件怎么办？</h3><p>大部分常用插件都有替代方案：</p><table><thead><tr><th>Oh My Zsh 插件</th><th>替代方案</th></tr></thead><tbody><tr><td><code>zsh-autosuggestions</code></td><td>原生支持不完善，可用 <code>fig</code> 或接受现实</td></tr><tr><td><code>zsh-syntax-highlighting</code></td><td>可单独安装：<code>brew install zsh-syntax-highlighting</code></td></tr><tr><td><code>z</code> / <code>autojump</code></td><td><code>zoxide</code>（更快更智能）</td></tr><tr><td><code>git</code></td><td>使用别名或 <code>git-extras</code></td></tr><tr><td><code>docker</code> / <code>kubectl</code></td><td>各工具自带补全</td></tr></tbody></table><h3 id="Q-Powerlevel10k-也很快，为什么不选它？"><a href="#Q-Powerlevel10k-也很快，为什么不选它？" class="headerlink" title="Q: Powerlevel10k 也很快，为什么不选它？"></a>Q: Powerlevel10k 也很快，为什么不选它？</h3><p>Powerlevel10k 确实很快，但：</p><ul><li>配置复杂，需要交互式向导</li><li>Zsh 专用，不跨平台</li><li>配置文件是大量条件判断，可读性差</li></ul><p>Starship 配置更直观，一个 TOML 文件搞定。</p><h3 id="Q-主题配色怎么统一？"><a href="#Q-主题配色怎么统一？" class="headerlink" title="Q: 主题配色怎么统一？"></a>Q: 主题配色怎么统一？</h3><p>我使用 <strong>Catppuccin</strong> 主题统一所有工具：</p><ul><li>Ghostty: <code>theme = Aura</code>（基于 Catppuccin）</li><li>Starship: <code>palette = 'catppuccin_mocha'</code></li><li>VSCode: Catppuccin 扩展</li><li>Browser: Catppuccin 主题</li></ul><p>一套配色，视觉一致。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这次终端环境重构的核心收获：</p><ol><li><strong>性能优先</strong>：终端是高频工具，启动速度和响应延迟直接影响体验</li><li><strong>极简主义</strong>：只保留必要的，去掉”可能用到”的</li><li><strong>现代工具</strong>：用 Rust/Go 写的现代工具替代老旧 Unix 工具</li><li><strong>配置即代码</strong>：所有配置都可以版本控制，随时恢复</li></ol><p>从 Oh My Zsh 到 Starship，从 iTerm2 到 Ghostty，不只是工具的更换，更是<strong>设计理念的转变</strong>：从”功能堆砌”到”性能优先”，从”开箱即用”到”按需配置”。</p><p>终端环境没有银弹，适合自己的才是最好的。希望我的经验能给你一些参考。</p><hr><blockquote><p>💡 <strong>相关文章</strong>：</p><ul><li><a href="/ghostty-config-guide/">Ghostty 终端配置完全指南</a></li><li><a href="/modern-cli-tools/">现代终端工具集 - bat, eza, fd, fzf, zoxide, yazi</a></li><li><a href="/grep-vs-ripgrep-vs-astgrep/">Grep vs Ripgrep vs AST-Grep - 代码搜索工具对比</a></li></ul></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/ghostty-zsh-starship-terminal-setup/</id>
    <link href="https://imwnk.cn/archives/ghostty-zsh-starship-terminal-setup/"/>
    <published>2026-04-04T02:00:00.000Z</published>
    <summary>从 Oh My Zsh 到 Starship，从 iTerm2 到 Ghostty，一次终端环境的彻底重构。分享我的配置经验和性能提升</summary>
    <title>Ghostty + ZSH + Starship - 我的终端开发环境进化之路</title>
    <updated>2026-04-04T01:39:49.970Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="ai" scheme="https://imwnk.cn/tags/ai/"/>
    <category term="agent" scheme="https://imwnk.cn/tags/agent/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="claude" scheme="https://imwnk.cn/tags/claude/"/>
    <category term="workflow" scheme="https://imwnk.cn/tags/workflow/"/>
    <content>
      <![CDATA[<blockquote><p><strong>Anthropic Hackathon 获奖项目</strong>，50K+ stars，让你的 Claude Code 从工具变成编程伙伴。</p></blockquote><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E4%BB%80%E4%B9%88%E6%98%AF-everything-claude-code">什么是 Everything Claude Code？</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7">核心特性</a></li><li><a href="#%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97">安装指南</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E7%BB%84%E4%BB%B6%E8%AF%A6%E8%A7%A3">核心组件详解</a></li><li><a href="#%E5%B8%B8%E7%94%A8%E5%B7%A5%E4%BD%9C%E6%B5%81">常用工作流</a></li><li><a href="#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5">最佳实践</a></li><li><a href="#%E7%94%9F%E6%80%81%E5%B7%A5%E5%85%B7">生态工具</a></li><li><a href="#%E6%80%BB%E7%BB%93">总结</a></li></ol><hr><h2 id="什么是-Everything-Claude-Code？"><a href="#什么是-Everything-Claude-Code？" class="headerlink" title="什么是 Everything Claude Code？"></a>什么是 Everything Claude Code？</h2><p>如果你正在使用 Claude Code 进行开发，可能遇到过这些问题：</p><ul><li>AI 跳过测试直接写代码，结果上线后出 bug</li><li>AI “修复”了一个问题，引入了两个新问题</li><li>AI 声称”完成”，实际上遗漏了很多需求</li><li>重复的工作流程没有标准化，每次都要重新沟通</li></ul><p><strong>Everything Claude Code (ECC)</strong> 就是为解决这些问题而生的。</p><p>它不是让 AI 变得更聪明，而是给 AI 一套<strong>标准化的工作流程</strong>——就像给一个聪明但没有纪律的工程师一本详细的操作手册。</p><h3 id="核心数据"><a href="#核心数据" class="headerlink" title="核心数据"></a>核心数据</h3><table><thead><tr><th>指标</th><th>数量</th></tr></thead><tbody><tr><td>GitHub Stars</td><td>50K+</td></tr><tr><td>Forks</td><td>6K+</td></tr><tr><td>贡献者</td><td>30+</td></tr><tr><td>专业代理</td><td>38 个</td></tr><tr><td>技能</td><td>156 个</td></tr><tr><td>命令</td><td>72 个</td></tr><tr><td>支持语言</td><td>7 种</td></tr></tbody></table><hr><h2 id="核心特性"><a href="#核心特性" class="headerlink" title="核心特性"></a>核心特性</h2><h3 id="1-专业代理（Agents）"><a href="#1-专业代理（Agents）" class="headerlink" title="1. 专业代理（Agents）"></a>1. 专业代理（Agents）</h3><p>38 个专业子代理，每个都有明确的职责：</p><table><thead><tr><th>代理</th><th>用途</th></tr></thead><tbody><tr><td><code>planner</code></td><td>功能实现规划</td></tr><tr><td><code>architect</code></td><td>系统设计决策</td></tr><tr><td><code>tdd-guide</code></td><td>测试驱动开发</td></tr><tr><td><code>code-reviewer</code></td><td>代码质量审查</td></tr><tr><td><code>security-reviewer</code></td><td>安全漏洞分析</td></tr><tr><td><code>build-error-resolver</code></td><td>构建错误修复</td></tr><tr><td><code>e2e-runner</code></td><td>E2E 测试执行</td></tr><tr><td><code>refactor-cleaner</code></td><td>死代码清理</td></tr><tr><td><code>doc-updater</code></td><td>文档同步更新</td></tr><tr><td><code>go-reviewer</code></td><td>Go 代码审查</td></tr><tr><td><code>python-reviewer</code></td><td>Python 代码审查</td></tr><tr><td><code>rust-reviewer</code></td><td>Rust 代码审查</td></tr><tr><td><code>typescript-reviewer</code></td><td>TypeScript 代码审查</td></tr></tbody></table><h3 id="2-技能（Skills）"><a href="#2-技能（Skills）" class="headerlink" title="2. 技能（Skills）"></a>2. 技能（Skills）</h3><p>156 个技能覆盖各种开发场景：</p><p><strong>开发流程类：</strong></p><ul><li><code>tdd-workflow</code> — 测试驱动开发</li><li><code>verification-loop</code> — 持续验证</li><li><code>continuous-learning</code> — 从会话中自动学习模式</li></ul><p><strong>语言框架类：</strong></p><ul><li><code>golang-patterns</code> — Go 惯用模式</li><li><code>python-patterns</code> — Python 最佳实践</li><li><code>django-patterns</code> — Django 开发模式</li><li><code>springboot-patterns</code> — Spring Boot 模式</li><li><code>laravel-patterns</code> — Laravel 架构模式</li></ul><p><strong>领域专项类：</strong></p><ul><li><code>security-review</code> — 安全检查清单</li><li><code>database-migrations</code> — 数据库迁移模式</li><li><code>api-design</code> — REST API 设计</li><li><code>docker-patterns</code> — Docker 最佳实践</li><li><code>e2e-testing</code> — Playwright E2E 测试</li></ul><h3 id="3-规则（Rules）"><a href="#3-规则（Rules）" class="headerlink" title="3. 规则（Rules）"></a>3. 规则（Rules）</h3><p>多语言支持的编码规范：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">rules/</span><br><span class="line">├── common/          # 通用原则（必须安装）</span><br><span class="line">│   ├── coding-style.md</span><br><span class="line">│   ├── git-workflow.md</span><br><span class="line">│   ├── testing.md</span><br><span class="line">│   ├── performance.md</span><br><span class="line">│   └── security.md</span><br><span class="line">├── typescript/      # TypeScript/JavaScript</span><br><span class="line">├── python/          # Python</span><br><span class="line">├── golang/          # Go</span><br><span class="line">├── swift/           # Swift</span><br><span class="line">├── php/             # PHP</span><br><span class="line">├── java/            # Java</span><br><span class="line">├── kotlin/          # Kotlin</span><br><span class="line">├── cpp/             # C++</span><br><span class="line">└── rust/            # Rust</span><br></pre></td></tr></tbody></table></figure><h3 id="4-钩子（Hooks）"><a href="#4-钩子（Hooks）" class="headerlink" title="4. 钩子（Hooks）"></a>4. 钩子（Hooks）</h3><p>自动化触发器，在关键时刻自动执行：</p><ul><li><strong>PreToolUse</strong> — 工具执行前验证</li><li><strong>PostToolUse</strong> — 工具执行后自动格式化</li><li><strong>Stop</strong> — 会话结束时保存状态</li></ul><hr><h2 id="安装指南"><a href="#安装指南" class="headerlink" title="安装指南"></a>安装指南</h2><h3 id="方式一：插件安装（推荐）"><a href="#方式一：插件安装（推荐）" class="headerlink" title="方式一：插件安装（推荐）"></a>方式一：插件安装（推荐）</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 添加市场</span></span><br><span class="line">/plugin marketplace add affaan-m/everything-claude-code</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 安装插件</span></span><br><span class="line">/plugin install everything-claude-code@everything-claude-code</span><br></pre></td></tr></tbody></table></figure><h3 id="方式二：手动安装"><a href="#方式二：手动安装" class="headerlink" title="方式二：手动安装"></a>方式二：手动安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 克隆仓库</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/affaan-m/everything-claude-code.git</span><br><span class="line"><span class="built_in">cd</span> everything-claude-code</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 安装依赖</span></span><br><span class="line">npm install</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 安装规则（必须手动安装）</span></span><br><span class="line"><span class="comment"># macOS/Linux</span></span><br><span class="line">./install.sh --profile full</span><br><span class="line"></span><br><span class="line"><span class="comment"># Windows PowerShell</span></span><br><span class="line">.\install.ps1 --profile full</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或只安装特定语言</span></span><br><span class="line">./install.sh typescript python golang</span><br></pre></td></tr></tbody></table></figure><h3 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看已安装的插件</span></span><br><span class="line">/plugin list everything-claude-code@everything-claude-code</span><br><span class="line"></span><br><span class="line"><span class="comment"># 测试命令</span></span><br><span class="line">/everything-claude-code:plan <span class="string">"测试功能"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="核心组件详解"><a href="#核心组件详解" class="headerlink" title="核心组件详解"></a>核心组件详解</h2><h3 id="Agents：专业分工"><a href="#Agents：专业分工" class="headerlink" title="Agents：专业分工"></a>Agents：专业分工</h3><p>代理是 ECC 的核心。每个代理都有：</p><ul><li>明确的职责范围</li><li>限制的工具集</li><li>专门的模型配置</li></ul><p><strong>示例：code-reviewer 代理</strong></p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">---</span><br><span class="line">name: code-reviewer</span><br><span class="line">description: 代码质量、安全性和可维护性审查</span><br><span class="line">tools: ["Read", "Grep", "Glob", "Bash"]</span><br><span class="line"><span class="section">model: opus</span></span><br><span class="line"><span class="section">---</span></span><br><span class="line"></span><br><span class="line">你是一名资深代码审查专家...</span><br></pre></td></tr></tbody></table></figure><h3 id="Skills：工作流程"><a href="#Skills：工作流程" class="headerlink" title="Skills：工作流程"></a>Skills：工作流程</h3><p>技能定义了完整的工作流程。以 TDD 为例：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1. 定义接口</span><br><span class="line">2. 写失败的测试（RED）</span><br><span class="line">3. 实现最小代码（GREEN）</span><br><span class="line">4. 重构优化（IMPROVE）</span><br><span class="line">5. 验证覆盖率 80%+</span><br></pre></td></tr></tbody></table></figure><h3 id="Rules：编码规范"><a href="#Rules：编码规范" class="headerlink" title="Rules：编码规范"></a>Rules：编码规范</h3><p>规则是必须遵守的准则：</p><p><strong>common/testing.md：</strong></p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># 测试要求</span></span><br><span class="line"></span><br><span class="line"><span class="section">## 最低覆盖率：80%</span></span><br><span class="line"></span><br><span class="line">测试类型（全部必需）：</span><br><span class="line"><span class="bullet">1.</span> 单元测试</span><br><span class="line"><span class="bullet">2.</span> 集成测试</span><br><span class="line"><span class="bullet">3.</span> E2E 测试</span><br></pre></td></tr></tbody></table></figure><p><strong>golang/coding-style.md：</strong></p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># Go 编码风格</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> 使用指针接收器进行结构体变更</span><br><span class="line"><span class="bullet">-</span> 错误处理不使用 panic</span><br><span class="line"><span class="bullet">-</span> 导出函数必须有文档注释</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="常用工作流"><a href="#常用工作流" class="headerlink" title="常用工作流"></a>常用工作流</h2><h3 id="开发新功能"><a href="#开发新功能" class="headerlink" title="开发新功能"></a>开发新功能</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 规划功能</span></span><br><span class="line">/everything-claude-code:plan <span class="string">"添加用户认证功能"</span></span><br><span class="line"><span class="comment"># → planner 代理创建实现蓝图</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. TDD 开发</span></span><br><span class="line">/tdd</span><br><span class="line"><span class="comment"># → tdd-guide 代理强制测试先行</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 代码审查</span></span><br><span class="line">/code-review</span><br><span class="line"><span class="comment"># → code-reviewer 代理检查代码质量</span></span><br></pre></td></tr></tbody></table></figure><h3 id="修复-Bug"><a href="#修复-Bug" class="headerlink" title="修复 Bug"></a>修复 Bug</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 系统化调试</span></span><br><span class="line">/debug</span><br><span class="line"><span class="comment"># → 自动收集证据、定位根因</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 编写回归测试</span></span><br><span class="line">/tdd</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 验证修复</span></span><br><span class="line">/verify</span><br></pre></td></tr></tbody></table></figure><h3 id="代码审查"><a href="#代码审查" class="headerlink" title="代码审查"></a>代码审查</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 通用审查</span></span><br><span class="line">/code-review</span><br><span class="line"></span><br><span class="line"><span class="comment"># 语言专项审查</span></span><br><span class="line">/go-review        <span class="comment"># Go 代码</span></span><br><span class="line">/python-review    <span class="comment"># Python 代码</span></span><br><span class="line">/rust-review      <span class="comment"># Rust 代码</span></span><br></pre></td></tr></tbody></table></figure><h3 id="构建修复"><a href="#构建修复" class="headerlink" title="构建修复"></a>构建修复</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/build-fix</span><br><span class="line"><span class="comment"># → build-error-resolver 代理分析错误、增量修复</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="最佳实践"><a href="#最佳实践" class="headerlink" title="最佳实践"></a>最佳实践</h2><h3 id="1-不要跳过流程"><a href="#1-不要跳过流程" class="headerlink" title="1. 不要跳过流程"></a>1. 不要跳过流程</h3><p>即使需求看起来很简单，也要走完完整流程。”简单”的需求往往隐藏着最容易被忽视的假设。</p><h3 id="2-信任流程"><a href="#2-信任流程" class="headerlink" title="2. 信任流程"></a>2. 信任流程</h3><p>当 AI 说”这个很简单，直接开始写吧”时，正是最容易出问题的时候。</p><h3 id="3-要求看到失败的测试"><a href="#3-要求看到失败的测试" class="headerlink" title="3. 要求看到失败的测试"></a>3. 要求看到失败的测试</h3><p>如果 AI 说”测试通过了”，但你没看到它运行测试失败的过程，要求它演示 Red-Green 循环。</p><h3 id="4-善用-Red-Flags"><a href="#4-善用-Red-Flags" class="headerlink" title="4. 善用 Red Flags"></a>4. 善用 Red Flags</h3><p>常见的危险信号：</p><ul><li>“只是简单问题”</li><li>“先试试这个改动能不能修复”</li><li>“应该可以了”</li><li>“我先实现再补测试”</li></ul><h3 id="5-选择合适的代理"><a href="#5-选择合适的代理" class="headerlink" title="5. 选择合适的代理"></a>5. 选择合适的代理</h3><table><thead><tr><th>场景</th><th>使用代理</th></tr></thead><tbody><tr><td>新功能规划</td><td>planner</td></tr><tr><td>架构决策</td><td>architect</td></tr><tr><td>代码实现</td><td>tdd-guide</td></tr><tr><td>质量检查</td><td>code-reviewer</td></tr><tr><td>安全审计</td><td>security-reviewer</td></tr><tr><td>构建问题</td><td>build-error-resolver</td></tr></tbody></table><hr><h2 id="生态工具"><a href="#生态工具" class="headerlink" title="生态工具"></a>生态工具</h2><h3 id="Skill-Creator"><a href="#Skill-Creator" class="headerlink" title="Skill Creator"></a>Skill Creator</h3><p>从你的仓库生成 Claude Code 技能：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 本地分析</span></span><br><span class="line">/skill-create                    <span class="comment"># 分析当前仓库</span></span><br><span class="line">/skill-create --instincts        <span class="comment"># 同时生成学习本能</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># GitHub App（高级功能）</span></span><br><span class="line"><span class="comment"># 在 issue 中评论：/skill-creator analyze</span></span><br></pre></td></tr></tbody></table></figure><h3 id="AgentShield-—-安全审计"><a href="#AgentShield-—-安全审计" class="headerlink" title="AgentShield — 安全审计"></a>AgentShield — 安全审计</h3><p>扫描 Claude Code 配置中的安全漏洞：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 快速扫描</span></span><br><span class="line">npx ecc-agentshield scan</span><br><span class="line"></span><br><span class="line"><span class="comment"># 自动修复</span></span><br><span class="line">npx ecc-agentshield scan --fix</span><br><span class="line"></span><br><span class="line"><span class="comment"># 深度分析（使用三个 Opus 4.6 代理）</span></span><br><span class="line">npx ecc-agentshield scan --opus --stream</span><br></pre></td></tr></tbody></table></figure><p><strong>扫描范围：</strong></p><ul><li>密钥检测（14 种模式）</li><li>权限审计</li><li>钩子注入分析</li><li>MCP 服务器风险分析</li><li>代理配置审查</li></ul><h3 id="Continuous-Learning-v2"><a href="#Continuous-Learning-v2" class="headerlink" title="Continuous Learning v2"></a>Continuous Learning v2</h3><p>自动学习你的编码模式：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">/instinct-status        <span class="comment"># 查看已学习的本能</span></span><br><span class="line">/instinct-import &lt;file&gt; <span class="comment"># 导入他人的本能</span></span><br><span class="line">/instinct-export        <span class="comment"># 导出你的本能</span></span><br><span class="line">/evolve                 <span class="comment"># 将相关本能聚类为技能</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Everything Claude Code 的核心价值不在于让 AI 变得更聪明，而在于<strong>给聪明但没有纪律的 AI 一套严格的工作流程</strong>。</p><h3 id="它的价值体现在："><a href="#它的价值体现在：" class="headerlink" title="它的价值体现在："></a>它的价值体现在：</h3><ol><li><strong>可预测性</strong> — 你知道 AI 会怎么做，不会跳过什么步骤</li><li><strong>可追溯性</strong> — 每个决策都有记录，每个实现都有测试</li><li><strong>可信赖性</strong> — 声称完成之前，必须有验证证据</li></ol><h3 id="推荐安装配置："><a href="#推荐安装配置：" class="headerlink" title="推荐安装配置："></a>推荐安装配置：</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 完整安装</span></span><br><span class="line">/plugin marketplace add affaan-m/everything-claude-code</span><br><span class="line">/plugin install everything-claude-code@everything-claude-code</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装规则</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/affaan-m/everything-claude-code.git</span><br><span class="line"><span class="built_in">cd</span> everything-claude-code</span><br><span class="line">./install.sh --profile full</span><br></pre></td></tr></tbody></table></figure><p>如果你在使用 Claude Code 时遇到过 AI 跳过测试、遗漏需求、声称完成但实际未完成的问题，Everything Claude Code 可能就是你需要的——不是更好的 AI，而是更有纪律的 AI。</p><hr><h2 id="延伸阅读"><a href="#延伸阅读" class="headerlink" title="延伸阅读"></a>延伸阅读</h2><ul><li><a href="https://github.com/affaan-m/everything-claude-code">Everything Claude Code GitHub</a></li><li><a href="https://docs.anthropic.com/claude-code">Claude Code 官方文档</a></li><li><a href="/posts/superpowers-guide/">Superpowers 入门指南</a></li><li><a href="https://github.com/affaan-m/agentshield">AgentShield 安全工具</a></li></ul><hr><blockquote><p>💡 <strong>提示</strong>: ECC 持续更新，建议定期 <code>git pull</code> 获取最新功能和修复。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/everything-claude-code-guide/</id>
    <link href="https://imwnk.cn/archives/everything-claude-code-guide/"/>
    <published>2026-04-03T04:00:00.000Z</published>
    <summary>Everything Claude Code 是一套完整的 AI 代理性能优化系统，包含 38 个专业代理、156 个技能、72 个命令，让 Claude Code 更强大、更专业</summary>
    <title>Everything Claude Code - 打造高效 AI 编程工作流</title>
    <updated>2026-04-03T02:56:29.678Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="cli" scheme="https://imwnk.cn/tags/cli/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="terminal" scheme="https://imwnk.cn/tags/terminal/"/>
    <category term="productivity" scheme="https://imwnk.cn/tags/productivity/"/>
    <content>
      <![CDATA[<blockquote><p><strong>工欲善其事，必先利其器。</strong> 用现代工具替代传统命令，让终端操作效率翻倍。</p></blockquote><p>终端是开发者的主场。但传统的 <code>ls</code>、<code>cd</code>、<code>cat</code>、<code>find</code> 这些命令，诞生于几十年前的 Unix时代，功能基础、体验原始。</p><p>2026 年，我们有了更好的选择：Rust 和 Go 编写的新一代工具，速度更快、体验更好、功能更强。本文介绍六款现代 CLI 工具，帮你打造高效的工作流。</p><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E5%B7%A5%E5%85%B7%E6%A6%82%E8%A7%88">工具概览</a></li><li><a href="#bat---%E5%B8%A6%E7%BF%85%E8%86%80%E7%9A%84-cat">bat - 带翅膀的 cat</a></li><li><a href="#eza---%E7%8E%B0%E4%BB%A3%E5%8C%96%E7%9A%84-ls">eza - 现代化的 ls</a></li><li><a href="#fd---%E6%9E%81%E9%80%9F%E6%96%87%E4%BB%B6%E6%9F%A5%E6%89%BE">fd - 极速文件查找</a></li><li><a href="#fzf---%E6%A8%A1%E7%B3%8A%E6%90%9C%E7%B4%A2%E7%A5%9E%E5%99%A8">fzf - 模糊搜索神器</a></li><li><a href="#zoxide---%E6%99%BA%E8%83%BD%E7%9B%AE%E5%BD%95%E8%B7%B3%E8%BD%AC">zoxide - 智能目录跳转</a></li><li><a href="#yazi---%E7%BB%88%E7%AB%AF%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86%E5%99%A8">yazi - 终端文件管理器</a></li><li><a href="#%E5%B7%A5%E5%85%B7%E5%AF%B9%E6%AF%94%E7%9F%A9%E9%98%B5">工具对比矩阵</a></li><li><a href="#%E7%BB%84%E5%90%88%E4%BD%BF%E7%94%A8%E7%A4%BA%E4%BE%8B">组合使用示例</a></li><li><a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">常见问题</a></li><li><a href="#%E6%80%BB%E7%BB%93">总结</a></li></ol><hr><h2 id="工具概览"><a href="#工具概览" class="headerlink" title="工具概览"></a>工具概览</h2><table><thead><tr><th>工具</th><th>替代命令</th><th>核心优势</th><th>语言</th></tr></thead><tbody><tr><td><strong>bat</strong></td><td>cat</td><td>语法高亮 + Git 集成</td><td>Rust</td></tr><tr><td><strong>eza</strong></td><td>ls</td><td>彩色输出 + Git 状态 + 图标</td><td>Rust</td></tr><tr><td><strong>fd</strong></td><td>find</td><td>极速 + 智能过滤</td><td>Rust</td></tr><tr><td><strong>fzf</strong></td><td>-</td><td>模糊搜索 + 交互式选择</td><td>Go</td></tr><tr><td><strong>zoxide</strong></td><td>cd/z</td><td>智能跳转 + 学习历史</td><td>Rust</td></tr><tr><td><strong>yazi</strong></td><td>ranger/lf</td><td>异步架构 + 图片预览</td><td>Rust</td></tr></tbody></table><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">传统工具                    现代替代</span><br><span class="line">cat file.txt         →     bat file.txt</span><br><span class="line">ls -la               →     eza -la</span><br><span class="line">find . -name "*.js"  →     fd .js</span><br><span class="line">cd ~/projects/app    →     z app</span><br><span class="line">ranger               →     yazi</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="bat-带翅膀的-cat"><a href="#bat-带翅膀的-cat" class="headerlink" title="bat - 带翅膀的 cat"></a>bat - 带翅膀的 cat</h2><p><strong>bat</strong> 是 <code>cat</code> 的现代替代品，由 sharkdp（ripgrep 作者）开发。项目名「bat」意为「带翅膀的 cat」。</p><h3 id="核心特性"><a href="#核心特性" class="headerlink" title="核心特性"></a>核心特性</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># bat vs cat 对比</span></span><br><span class="line"><span class="built_in">cat</span> main.rs          <span class="comment"># 原始文本输出</span></span><br><span class="line">bat main.rs          <span class="comment"># 语法高亮 + 行号 + Git 标记</span></span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>语法高亮</strong></td><td>支持 150+ 语言，内置 syntect引擎</td></tr><tr><td><strong>Git 集成</strong></td><td>显示文件修改标记（左侧边栏）</td></tr><tr><td><strong>行号显示</strong></td><td>自动显示，可配置样式</td></tr><tr><td><strong>自动分页</strong></td><td>输出过长时自动调用 pager</td></tr><tr><td><strong>非打印字符</strong></td><td><code>-A</code> 选项显示特殊字符</td></tr></tbody></table><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># Fedora</span></span><br><span class="line">dnf install bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># Windows (winget)</span></span><br><span class="line">winget install sharkdp.bat</span><br></pre></td></tr></tbody></table></figure><blockquote><p>⚠️ <strong>注意</strong>: Ubuntu/Debian 上可能安装为 <code>batcat</code>，需创建别名：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">mkdir</span> -p ~/.local/bin</span><br><span class="line"><span class="built_in">ln</span> -s /usr/bin/batcat ~/.local/bin/bat</span><br></pre></td></tr></tbody></table></figure></blockquote><h3 id="实用示例"><a href="#实用示例" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看代码文件（自动高亮）</span></span><br><span class="line">bat src/main.rs</span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示 Git 修改标记</span></span><br><span class="line">bat --style=changes,numbers config.py</span><br><span class="line"></span><br><span class="line"><span class="comment"># 只显示行号（无高亮）</span></span><br><span class="line">bat -n plain.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看非打印字符</span></span><br><span class="line">bat -A binary.log</span><br><span class="line"></span><br><span class="line"><span class="comment"># 从 stdin 读取（指定语言）</span></span><br><span class="line">curl -s https://example.com/api.json | bat -l json</span><br><span class="line"></span><br><span class="line"><span class="comment"># 合并多个文件</span></span><br><span class="line">bat header.md content.md footer.md &gt; document.md</span><br><span class="line"></span><br><span class="line"><span class="comment"># 作为 man pager（彩色手册页）</span></span><br><span class="line"><span class="built_in">export</span> MANPAGER=<span class="string">"bat -plman"</span></span><br><span class="line">man 2 <span class="keyword">select</span></span><br></pre></td></tr></tbody></table></figure><h3 id="集成其他工具"><a href="#集成其他工具" class="headerlink" title="集成其他工具"></a>集成其他工具</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># fzf 预览</span></span><br><span class="line">fzf --preview <span class="string">"bat --color=always --style=numbers --line-range=:500 {}"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fd 批量查看</span></span><br><span class="line">fd -e rs -X bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># git show 查看历史版本</span></span><br><span class="line">git show v1.0:main.rs | bat -l rs</span><br><span class="line"></span><br><span class="line"><span class="comment"># tail -f 实时监控</span></span><br><span class="line"><span class="built_in">tail</span> -f /var/log/app.log | bat --paging=never -l <span class="built_in">log</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 高亮 help 输出</span></span><br><span class="line"><span class="built_in">alias</span> bathelp=<span class="string">'bat --plain --language=help'</span></span><br><span class="line"><span class="function"><span class="title">help</span></span>() {</span><br><span class="line">    <span class="string">"<span class="variable">$@</span>"</span> --<span class="built_in">help</span> 2&gt;&amp;1 | bathelp</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="配置文件"><a href="#配置文件" class="headerlink" title="配置文件"></a>配置文件</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 配置文件位置</span></span><br><span class="line">~/.config/bat/config</span><br><span class="line"></span><br><span class="line"><span class="comment"># 示例配置</span></span><br><span class="line">--theme=<span class="string">"TwoDark"</span></span><br><span class="line">--style=<span class="string">"numbers,changes,grid"</span></span><br><span class="line">--italic-text=always</span><br><span class="line">--pager=<span class="string">"less -RF"</span></span><br><span class="line">--map-syntax <span class="string">"*.conf:json"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="主题选择"><a href="#主题选择" class="headerlink" title="主题选择"></a>主题选择</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看所有主题</span></span><br><span class="line">bat --list-themes</span><br><span class="line"></span><br><span class="line"><span class="comment"># 实时预览主题</span></span><br><span class="line">bat --list-themes | fzf --preview=<span class="string">"bat --theme={} --color=always main.rs"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 设置主题</span></span><br><span class="line"><span class="built_in">export</span> BAT_THEME=<span class="string">"TwoDark"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自动适应深/浅色模式</span></span><br><span class="line"><span class="built_in">export</span> BAT_THEME_DARK=<span class="string">"Monokai Extended"</span></span><br><span class="line"><span class="built_in">export</span> BAT_THEME_LIGHT=<span class="string">"Monokai Extended Light"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="eza-现代化的-ls"><a href="#eza-现代化的-ls" class="headerlink" title="eza - 现代化的 ls"></a>eza - 现代化的 ls</h2><p><strong>eza</strong> 是 <code>exa</code> 的继任者（exa 已停止维护），用 Rust 编写，提供彩色输出、Git 状态、文件图标等现代特性。</p><h3 id="核心特性-1"><a href="#核心特性-1" class="headerlink" title="核心特性"></a>核心特性</h3><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>彩色输出</strong></td><td>文件类型自动配色</td></tr><tr><td><strong>Git 状态</strong></td><td>显示修改、新增、删除标记</td></tr><tr><td><strong>文件图标</strong></td><td>Unicode 图标区分文件类型</td></tr><tr><td><strong>树形视图</strong></td><td><code>--tree</code> 递归显示目录结构</td></tr><tr><td><strong>Hyperlink</strong></td><td>终端可点击链接</td></tr></tbody></table><h3 id="安装-1"><a href="#安装-1" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install eza</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S eza</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install eza</span><br><span class="line"></span><br><span class="line"><span class="comment"># Fedora</span></span><br><span class="line">dnf install eza</span><br><span class="line"></span><br><span class="line"><span class="comment"># Nix</span></span><br><span class="line">nix-env -iA nixpkgs.eza</span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例-1"><a href="#实用示例-1" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本用法（替代 ls）</span></span><br><span class="line">eza                    <span class="comment"># 简洁列表</span></span><br><span class="line">eza -la                <span class="comment"># 详细列表 + 隐藏文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示 Git 状态</span></span><br><span class="line">eza --git              <span class="comment"># Git 状态标记</span></span><br><span class="line">eza --git-status       <span class="comment"># 详细 Git 信息</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 文件图标</span></span><br><span class="line">eza --icons            <span class="comment"># Unicode图标</span></span><br><span class="line">eza --icons=auto       <span class="comment"># 自动判断是否显示</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 树形视图</span></span><br><span class="line">eza --tree             <span class="comment"># 递归显示</span></span><br><span class="line">eza --tree --level=2   <span class="comment"># 限制层级</span></span><br><span class="line">eza -T --git           <span class="comment"># 树形 + Git</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 按时间排序</span></span><br><span class="line">eza -la --<span class="built_in">sort</span>=modified    <span class="comment"># 按修改时间</span></span><br><span class="line">eza -la --<span class="built_in">sort</span>=created     <span class="comment"># 按创建时间</span></span><br><span class="line">eza -la --<span class="built_in">sort</span>=size        <span class="comment"># 按大小</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 组合使用</span></span><br><span class="line">eza -la --git --icons --<span class="built_in">sort</span>=modified</span><br></pre></td></tr></tbody></table></figure><h3 id="Git-状态标记"><a href="#Git-状态标记" class="headerlink" title="Git 状态标记"></a>Git 状态标记</h3><table><thead><tr><th>标记</th><th>说明</th></tr></thead><tbody><tr><td><code>-</code></td><td>已修改，未暂存</td></tr><tr><td><code>M</code></td><td>已暂存，未提交</td></tr><tr><td><code>+</code></td><td>新文件，未跟踪</td></tr><tr><td><code>!</code></td><td>已删除</td></tr></tbody></table><h3 id="配置别名"><a href="#配置别名" class="headerlink" title="配置别名"></a>配置别名</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.zshrc 或 ~/.bashrc</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">ls</span>=<span class="string">'eza'</span></span><br><span class="line"><span class="built_in">alias</span> ll=<span class="string">'eza -la --icons --git'</span></span><br><span class="line"><span class="built_in">alias</span> lt=<span class="string">'eza --tree --level=2 --icons'</span></span><br><span class="line"><span class="built_in">alias</span> l=<span class="string">'eza -la --icons --git --group-directories-first'</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="fd-极速文件查找"><a href="#fd-极速文件查找" class="headerlink" title="fd - 极速文件查找"></a>fd - 极速文件查找</h2><p><strong>fd</strong> 是 <code>find</code> 的现代替代品，速度更快、语法更简单、智能过滤。</p><h3 id="核心特性-2"><a href="#核心特性-2" class="headerlink" title="核心特性"></a>核心特性</h3><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>极速搜索</strong></td><td>多线程并行，比 find 快10x+</td></tr><tr><td><strong>智能过滤</strong></td><td>自动跳过 .git、node_modules</td></tr><tr><td><strong>彩色输出</strong></td><td>不同文件类型自动配色</td></tr><tr><td><strong>正则支持</strong></td><td>支持正则表达式模式</td></tr><tr><td><strong>并行执行</strong></td><td><code>-x</code> 并行执行命令</td></tr></tbody></table><h3 id="安装-2"><a href="#安装-2" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install fd</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S fd</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install fd-find</span><br><span class="line"><span class="comment"># 注意：可能需要 alias fd=fdfind</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Fedora</span></span><br><span class="line">dnf install fd-find</span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例-2"><a href="#实用示例-2" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本搜索</span></span><br><span class="line">fd pattern            <span class="comment"># 搜索文件名包含 pattern</span></span><br><span class="line">fd .js                <span class="comment"># 搜索所有 .js 文件</span></span><br><span class="line">fd -e rs main         <span class="comment"># 搜索 rs 文件中包含 main</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 按类型搜索</span></span><br><span class="line">fd -t f               <span class="comment"># 只搜索文件</span></span><br><span class="line">fd -t d               <span class="comment"># 只搜索目录</span></span><br><span class="line">fd -t x               <span class="comment"># 只搜索可执行文件</span></span><br><span class="line">fd -t l               <span class="comment"># 只搜索符号链接</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 按扩展名</span></span><br><span class="line">fd -e py              <span class="comment"># Python 文件</span></span><br><span class="line">fd -e js -e ts        <span class="comment"># JS 和 TS 文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 按大小/时间</span></span><br><span class="line">fd -S +10M            <span class="comment"># 大于 10MB</span></span><br><span class="line">fd --changed-within 1d    <span class="comment"># 1天内修改</span></span><br><span class="line">fd --changed-before 1w    <span class="comment"># 1周前修改</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 隐藏文件</span></span><br><span class="line">fd -H pattern         <span class="comment"># 包含隐藏文件</span></span><br><span class="line">fd -I pattern         <span class="comment"># 忽略 .gitignore</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 正则模式</span></span><br><span class="line">fd -x <span class="string">'test_.*\.py'</span>   <span class="comment"># 正则匹配</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 并行执行命令</span></span><br><span class="line">fd -e jpg -x <span class="built_in">rm</span>       <span class="comment"># 删除所有 jpg</span></span><br><span class="line">fd -e rs -x bat       <span class="comment"># 用 bat 查看所有 rs 文件</span></span><br><span class="line">fd -t f -X <span class="built_in">chmod</span> 644  <span class="comment"># 批量修改权限</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 排除特定目录</span></span><br><span class="line">fd -E node_modules pattern</span><br><span class="line">fd --exclude .git pattern</span><br></pre></td></tr></tbody></table></figure><h3 id="fd-vs-find对比"><a href="#fd-vs-find对比" class="headerlink" title="fd vs find对比"></a>fd vs find对比</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># find 语法（复杂）</span></span><br><span class="line">find . -name <span class="string">"*.js"</span> -<span class="built_in">type</span> f -not -path <span class="string">"./node_modules/*"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fd 语法（简洁）</span></span><br><span class="line">fd -e js -E node_modules</span><br></pre></td></tr></tbody></table></figure><table><thead><tr><th>维度</th><th>find</th><th>fd</th></tr></thead><tbody><tr><td>语法复杂度</td><td>高</td><td>低</td></tr><tr><td>默认过滤</td><td>无</td><td>智能</td></tr><tr><td>速度</td><td>慢</td><td>快 10x+</td></tr><tr><td>彩色输出</td><td>需配置</td><td>默认</td></tr><tr><td>并行执行</td><td>-exec</td><td>-x</td></tr></tbody></table><hr><h2 id="fzf-模糊搜索神器"><a href="#fzf-模糊搜索神器" class="headerlink" title="fzf - 模糊搜索神器"></a>fzf - 模糊搜索神器</h2><p><strong>fzf</strong> 是通用的模糊搜索工具，可与任何命令集成，提供交互式选择界面。</p><h3 id="核心特性-3"><a href="#核心特性-3" class="headerlink" title="核心特性"></a>核心特性</h3><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>模糊匹配</strong></td><td>智能匹配，无需精确输入</td></tr><tr><td><strong>交互式选择</strong></td><td>可用键盘实时筛选</td></tr><tr><td><strong>高度可定制</strong></td><td>布局、颜色、键绑定全可配置</td></tr><tr><td><strong>广泛集成</strong></td><td>shell、vim、tmux等</td></tr><tr><td><strong>预览窗口</strong></td><td>实时预览选中内容</td></tr></tbody></table><h3 id="安装-3"><a href="#安装-3" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install fzf</span><br><span class="line"><span class="comment"># 安装 shell 集成</span></span><br><span class="line">$(brew --prefix)/opt/fzf/install</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S fzf</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install fzf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 手动安装</span></span><br><span class="line">git <span class="built_in">clone</span> --depth 1 https://github.com/junegunn/fzf.git ~/.fzf</span><br><span class="line">~/.fzf/install</span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例-3"><a href="#实用示例-3" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本用法</span></span><br><span class="line">fzf                   <span class="comment"># 从 stdin 选择</span></span><br><span class="line">fzf -f pattern        <span class="comment"># 直接过滤</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索文件</span></span><br><span class="line">fd | fzf              <span class="comment"># 用 fd 提供文件列表</span></span><br><span class="line">fd -t f | fzf         <span class="comment"># 只搜索文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 带预览窗口</span></span><br><span class="line">fzf --preview <span class="string">'bat --color=always {}'</span></span><br><span class="line">fzf --preview-window=right:50%    <span class="comment"># 右侧50%宽度</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索命令历史</span></span><br><span class="line"><span class="built_in">history</span> | fzf         <span class="comment"># 搜索历史命令</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索环境变量</span></span><br><span class="line"><span class="built_in">printenv</span> | fzf        <span class="comment"># 搜索环境变量</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索进程</span></span><br><span class="line">ps aux | fzf          <span class="comment"># 交互式选择进程</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索 Git 分支</span></span><br><span class="line">git branch | fzf      <span class="comment"># 选择分支</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 组合 fd + bat</span></span><br><span class="line">fd -e rs | fzf --preview <span class="string">'bat --color=always --style=numbers {}'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 Ctrl-T/Ctrl-R/Ctrl-Alt-J（shell 集成）</span></span><br><span class="line"><span class="comment"># Ctrl-T    搜索文件</span></span><br><span class="line"><span class="comment"># Ctrl-R    搜索历史</span></span><br><span class="line"><span class="comment"># Alt-C     搜索目录（zoxide集成）</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Shell-集成"><a href="#Shell-集成" class="headerlink" title="Shell 集成"></a>Shell 集成</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装后自动生成以下快捷键：</span></span><br><span class="line"><span class="comment"># Ctrl-T    文件搜索</span></span><br><span class="line"><span class="comment"># Ctrl-R    命令历史搜索</span></span><br><span class="line"><span class="comment"># Alt-C     目录跳转</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义快捷键绑定</span></span><br><span class="line"><span class="built_in">export</span> FZF_CTRL_T_OPTS=<span class="string">"--preview 'bat --color=always {}'"</span></span><br><span class="line"><span class="built_in">export</span> FZF_CTRL_R_OPTS=<span class="string">"--sort"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 布局配置</span></span><br><span class="line"><span class="built_in">export</span> FZF_DEFAULT_OPTS=<span class="string">"--height 40% --layout=reverse --border"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="高级用法"><a href="#高级用法" class="headerlink" title="高级用法"></a>高级用法</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 多选模式</span></span><br><span class="line">fzf -m                <span class="comment"># 可选多个文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 分屏布局</span></span><br><span class="line">fzf --height 50% --layout=reverse</span><br><span class="line"></span><br><span class="line"><span class="comment"># 边框样式</span></span><br><span class="line">fzf --border --border-rounded</span><br><span class="line"></span><br><span class="line"><span class="comment"># 颜色主题</span></span><br><span class="line">fzf --color=<span class="built_in">bg</span>+:#3b4252,<span class="built_in">bg</span>:#1e1e2e</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用 fd 作为默认输入</span></span><br><span class="line"><span class="built_in">export</span> FZF_DEFAULT_COMMAND=<span class="string">"fd --type f"</span></span><br><span class="line"><span class="built_in">export</span> FZF_CTRL_T_COMMAND=<span class="string">"<span class="variable">$FZF_DEFAULT_COMMAND</span>"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="zoxide-智能目录跳转"><a href="#zoxide-智能目录跳转" class="headerlink" title="zoxide - 智能目录跳转"></a>zoxide - 智能目录跳转</h2><p><strong>zoxide</strong> 是 <code>cd</code> 和 <code>z</code> 的智能替代品，基于 frecency（频率 + 近期）算法，自动学习你的目录习惯。</p><h3 id="核心特性-4"><a href="#核心特性-4" class="headerlink" title="核心特性"></a>核心特性</h3><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>智能跳转</strong></td><td>输入部分名称即可跳转</td></tr><tr><td><strong>自动学习</strong></td><td>记录访问历史，权重自动调整</td></tr><tr><td><strong>frecency算法</strong></td><td>频率 + 时间双重权重</td></tr><tr><td><strong>多目录匹配</strong></td><td>模糊匹配多个候选</td></tr><tr><td><strong>跨平台</strong></td><td>Linux/macOS/Windows</td></tr></tbody></table><h3 id="安装-4"><a href="#安装-4" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Fedora</span></span><br><span class="line">dnf install zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Windows (winget)</span></span><br><span class="line">winget install ajeetdsouza.zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Nix</span></span><br><span class="line">nix-env -iA nixpkgs.zoxide</span><br></pre></td></tr></tbody></table></figure><h3 id="Shell-初始化"><a href="#Shell-初始化" class="headerlink" title="Shell 初始化"></a>Shell 初始化</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Bash (~/.bashrc)</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(zoxide init bash)</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Zsh (~/.zshrc)</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(zoxide init zsh)</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Fish (~/.config/fish/config.fish)</span></span><br><span class="line">zoxide init fish | <span class="built_in">source</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># PowerShell</span></span><br><span class="line">Invoke-Expression (&amp; { (zoxide init powershell | Out-String) })</span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例-4"><a href="#实用示例-4" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 记录目录（访问时自动记录）</span></span><br><span class="line">z ~/projects/myapp</span><br><span class="line">z /var/log</span><br><span class="line"></span><br><span class="line"><span class="comment"># 智能跳转</span></span><br><span class="line">z myapp              <span class="comment"># 跳转到包含 "myapp" 的目录</span></span><br><span class="line">z pro                <span class="comment"># 跳转到 projects</span></span><br><span class="line">z <span class="built_in">log</span>                <span class="comment"># 跳转到 /var/log</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示候选列表</span></span><br><span class="line">zi                   <span class="comment"># 交互式选择（fzf 集成）</span></span><br><span class="line">z -l                 <span class="comment"># 列出历史目录</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加目录（不跳转）</span></span><br><span class="line">zoxide add ~/new-project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 删除记录</span></span><br><span class="line">zoxide remove ~/old-project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查询分数</span></span><br><span class="line">zoxide query myapp</span><br><span class="line"></span><br><span class="line"><span class="comment"># 交互式选择（需要 fzf）</span></span><br><span class="line">zi                   <span class="comment"># 用 fzf 选择目录</span></span><br></pre></td></tr></tbody></table></figure><h3 id="frecency-算法"><a href="#frecency-算法" class="headerlink" title="frecency 算法"></a>frecency 算法</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">frecency = frequency × recency</span><br><span class="line"></span><br><span class="line">frequency: 访问次数</span><br><span class="line">recency:   最近访问时间权重</span><br><span class="line"></span><br><span class="line">访问 100 次，最后一次是昨天 → 高权重</span><br><span class="line">访问 1 次，最后一次是去年 → 低权重</span><br></pre></td></tr></tbody></table></figure><h3 id="配置选项"><a href="#配置选项" class="headerlink" title="配置选项"></a>配置选项</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 初始化选项</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(zoxide init zsh --cmd cd)</span>"</span>   <span class="comment"># 用 cd 作为命令名</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义别名</span></span><br><span class="line"><span class="built_in">alias</span> z=<span class="string">'zoxide'</span></span><br><span class="line"><span class="built_in">alias</span> zi=<span class="string">'zoxide -i'</span></span><br><span class="line"><span class="built_in">alias</span> za=<span class="string">'zoxide add'</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="yazi-终端文件管理器"><a href="#yazi-终端文件管理器" class="headerlink" title="yazi - 终端文件管理器"></a>yazi - 终端文件管理器</h2><p><strong>Yazi</strong>（鸭子）是用 Rust 编写的终端文件管理器，全异步架构，速度极快。已有详细指南，此处简要介绍。</p><h3 id="核心特性-5"><a href="#核心特性-5" class="headerlink" title="核心特性"></a>核心特性</h3><table><thead><tr><th>特性</th><th>说明</th></tr></thead><tbody><tr><td><strong>全异步架构</strong></td><td>所有 I/O 操作异步执行</td></tr><tr><td><strong>图片预览</strong></td><td>支持 Kitty、iTerm2、Sixel协议</td></tr><tr><td><strong>代码高亮</strong></td><td>内置语法高亮，无需 bat</td></tr><tr><td><strong>插件系统</strong></td><td>Lua 插件扩展</td></tr><tr><td><strong>任务管理</strong></td><td>复制/移动进度显示</td></tr></tbody></table><h3 id="安装-5"><a href="#安装-5" class="headerlink" title="安装"></a>安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install yazi ffmpeg 7zip jq poppler fd ripgrep fzf zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S yazi ffmpeg 7zip jq poppler fd ripgrep fzf zoxide</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动</span></span><br><span class="line">yazi</span><br></pre></td></tr></tbody></table></figure><h3 id="与其他工具集成"><a href="#与其他工具集成" class="headerlink" title="与其他工具集成"></a>与其他工具集成</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Yazi 内置集成：</span></span><br><span class="line"><span class="comment"># / → fd 文件搜索</span></span><br><span class="line"><span class="comment"># s → rg 内容搜索</span></span><br><span class="line"><span class="comment"># f → fzf 快速跳转</span></span><br><span class="line"><span class="comment"># z → zoxide 目录跳转</span></span><br></pre></td></tr></tbody></table></figure><p>完整指南见：<a href="/posts/yazi-file-manager-guide/">Yazi 终端文件管理器使用指南</a></p><hr><h2 id="工具对比矩阵"><a href="#工具对比矩阵" class="headerlink" title="工具对比矩阵"></a>工具对比矩阵</h2><h3 id="传统-vs-现代"><a href="#传统-vs-现代" class="headerlink" title="传统 vs 现代"></a>传统 vs 现代</h3><table><thead><tr><th>传统命令</th><th>现代替代</th><th align="center">速度提升</th><th>主要优势</th></tr></thead><tbody><tr><td><code>cat</code></td><td><code>bat</code></td><td align="center">-</td><td>高亮 + Git + 分页</td></tr><tr><td><code>ls</code></td><td><code>eza</code></td><td align="center">2x</td><td>彩色 + Git + 图标</td></tr><tr><td><code>find</code></td><td><code>fd</code></td><td align="center">10x+</td><td>智能过滤 + 简洁语法</td></tr><tr><td><code>cd</code></td><td><code>zoxide</code></td><td align="center">-</td><td>智能跳转 + 学习历史</td></tr><tr><td>-</td><td><code>fzf</code></td><td align="center">-</td><td>模糊搜索 + 交互选择</td></tr><tr><td><code>ranger</code></td><td><code>yazi</code></td><td align="center">5x</td><td>异步 + 图片预览</td></tr></tbody></table><h3 id="功能对比"><a href="#功能对比" class="headerlink" title="功能对比"></a>功能对比</h3><table><thead><tr><th>工具</th><th align="center">Git 集成</th><th align="center">彩色输出</th><th align="center">智能过滤</th><th align="center">可定制</th><th align="center">学习曲线</th></tr></thead><tbody><tr><td><strong>bat</strong></td><td align="center">✅</td><td align="center">✅</td><td align="center">-</td><td align="center">✅</td><td align="center">低</td></tr><tr><td><strong>eza</strong></td><td align="center">✅</td><td align="center">✅</td><td align="center">-</td><td align="center">✅</td><td align="center">低</td></tr><tr><td><strong>fd</strong></td><td align="center">-</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td><td align="center">低</td></tr><tr><td><strong>fzf</strong></td><td align="center">-</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td><td align="center">中</td></tr><tr><td><strong>zoxide</strong></td><td align="center">-</td><td align="center">-</td><td align="center">✅</td><td align="center">✅</td><td align="center">低</td></tr><tr><td><strong>yazi</strong></td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td><td align="center">中</td></tr></tbody></table><hr><h2 id="组合使用示例"><a href="#组合使用示例" class="headerlink" title="组合使用示例"></a>组合使用示例</h2><h3 id="1-文件查找-查看流程"><a href="#1-文件查找-查看流程" class="headerlink" title="1. 文件查找 + 查看流程"></a>1. 文件查找 + 查看流程</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># fd 找文件 → fzf 选择 → bat 查看</span></span><br><span class="line">fd -e rs | fzf --preview <span class="string">'bat --color=always {}'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 直接用 fzf 预览</span></span><br><span class="line">fzf --preview <span class="string">'bat --color=always --style=numbers --line-range=:500 {}'</span></span><br></pre></td></tr></tbody></table></figure><h3 id="2-目录跳转-文件管理"><a href="#2-目录跳转-文件管理" class="headerlink" title="2. 目录跳转 + 文件管理"></a>2. 目录跳转 + 文件管理</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># zoxide 跳转 → yazi 管理</span></span><br><span class="line">z myapp &amp;&amp; yazi</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或在 yazi 内用 zoxide</span></span><br><span class="line"><span class="comment"># 按 z 键，输入 myapp，跳转</span></span><br></pre></td></tr></tbody></table></figure><h3 id="3-搜索-执行"><a href="#3-搜索-执行" class="headerlink" title="3. 搜索 + 执行"></a>3. 搜索 + 执行</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># fd 找文件 → fzf 选择 → 执行</span></span><br><span class="line">fd -t f | fzf | xargs bat</span><br><span class="line"></span><br><span class="line"><span class="comment"># 并行执行</span></span><br><span class="line">fd -e jpg -x <span class="built_in">rm</span></span><br><span class="line">fd -e py -x pytest</span><br></pre></td></tr></tbody></table></figure><h3 id="4-Git-工作流"><a href="#4-Git-工作流" class="headerlink" title="4. Git 工作流"></a>4. Git 工作流</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看 Git 状态文件</span></span><br><span class="line">eza --git --icons</span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索修改文件</span></span><br><span class="line">fd --changed-within 1d --<span class="built_in">type</span> f</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看修改内容</span></span><br><span class="line">git show HEAD:main.rs | bat -l rs</span><br><span class="line">git diff | batdiff</span><br></pre></td></tr></tbody></table></figure><h3 id="5-Shell-配置推荐"><a href="#5-Shell-配置推荐" class="headerlink" title="5. Shell 配置推荐"></a>5. Shell 配置推荐</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.zshrc 或 ~/.bashrc</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># bat</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">cat</span>=<span class="string">'bat'</span></span><br><span class="line"><span class="built_in">export</span> MANPAGER=<span class="string">"bat -plman"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># eza</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">ls</span>=<span class="string">'eza --icons'</span></span><br><span class="line"><span class="built_in">alias</span> ll=<span class="string">'eza -la --icons --git'</span></span><br><span class="line"><span class="built_in">alias</span> lt=<span class="string">'eza --tree --level=2 --icons'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fd（替代 find）</span></span><br><span class="line"><span class="built_in">alias</span> find=<span class="string">'fd'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># zoxide</span></span><br><span class="line"><span class="built_in">eval</span> <span class="string">"<span class="subst">$(zoxide init zsh)</span>"</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">cd</span>=<span class="string">'z'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fzf 集成</span></span><br><span class="line"><span class="built_in">export</span> FZF_DEFAULT_COMMAND=<span class="string">"fd --type f"</span></span><br><span class="line"><span class="built_in">export</span> FZF_CTRL_T_OPTS=<span class="string">"--preview 'bat --color=always {}'"</span></span><br><span class="line"><span class="built_in">export</span> FZF_ALT_C_OPTS=<span class="string">"--preview 'eza --tree --level=1 {}'"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="Q-这些工具都需要安装，会不会太麻烦？"><a href="#Q-这些工具都需要安装，会不会太麻烦？" class="headerlink" title="Q: 这些工具都需要安装，会不会太麻烦？"></a>Q: 这些工具都需要安装，会不会太麻烦？</h3><p><strong>A</strong>: 一次安装，长期受益。推荐用包管理器批量安装：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install bat eza fd fzf zoxide yazi ripgrep</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S bat eza fd fzf zoxide yazi ripgrep</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-传统命令在某些场景仍需要，怎么办？"><a href="#Q-传统命令在某些场景仍需要，怎么办？" class="headerlink" title="Q: 传统命令在某些场景仍需要，怎么办？"></a>Q: 传统命令在某些场景仍需要，怎么办？</h3><p><strong>A</strong>: 可以共存。关键场景（如SSH服务器）可用传统命令：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 本地用现代工具</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">cat</span>=<span class="string">'bat'</span></span><br><span class="line"><span class="built_in">alias</span> <span class="built_in">ls</span>=<span class="string">'eza'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 服务器用原命令（别名只在本地生效）</span></span><br><span class="line">ssh server <span class="string">'cat /var/log/app.log'</span>  <span class="comment"># 使用原 cat</span></span><br></pre></td></tr></tbody></table></figure><p>或用 <code>command</code> 跳过别名：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">command</span> <span class="built_in">cat</span> file.txt  <span class="comment"># 使用原 cat</span></span><br><span class="line"><span class="built_in">command</span> <span class="built_in">ls</span> -la        <span class="comment"># 使用原 ls</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-bat-的输出会被管道影响吗？"><a href="#Q-bat-的输出会被管道影响吗？" class="headerlink" title="Q: bat 的输出会被管道影响吗？"></a>Q: bat 的输出会被管道影响吗？</h3><p><strong>A</strong>: 会自动调整。管道输出时，bat 自动切换为纯文本模式：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 交互模式：高亮输出</span></span><br><span class="line">bat main.rs</span><br><span class="line"></span><br><span class="line"><span class="comment"># 管道模式：纯文本输出</span></span><br><span class="line">bat main.rs | grep <span class="string">"fn main"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 强制高亮（用于 fzf 预览）</span></span><br><span class="line">bat --color=always main.rs | fzf</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-fd-如何处理中文文件名？"><a href="#Q-fd-如何处理中文文件名？" class="headerlink" title="Q: fd 如何处理中文文件名？"></a>Q: fd 如何处理中文文件名？</h3><p><strong>A</strong>: 完美支持。fd 和其他 Rust 工具对 Unicode 支持完善：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">fd <span class="string">"文档"</span>            <span class="comment"># 搜索中文文件名</span></span><br><span class="line">fd -e py <span class="string">"测试"</span>      <span class="comment"># 搜索测试相关文件</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-zoxide-会记录所有目录吗？"><a href="#Q-zoxide-会记录所有目录吗？" class="headerlink" title="Q: zoxide 会记录所有目录吗？"></a>Q: zoxide 会记录所有目录吗？</h3><p><strong>A</strong>: 只记录你访问的目录。敏感目录不会被记录：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 删除特定记录</span></span><br><span class="line">zoxide remove ~/secrets</span><br><span class="line"></span><br><span class="line"><span class="comment"># 清空所有记录</span></span><br><span class="line">zoxide query --clear</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-fzf-预览窗口加载慢？"><a href="#Q-fzf-预览窗口加载慢？" class="headerlink" title="Q: fzf 预览窗口加载慢？"></a>Q: fzf 预览窗口加载慢？</h3><p><strong>A</strong>: 限制预览行数：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 只预览前 500 行</span></span><br><span class="line">fzf --preview <span class="string">'bat --color=always --line-range=:500 {}'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 限制窗口大小</span></span><br><span class="line">fzf --preview-window=right:40%:wrap</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>六款现代 CLI 工具，各司其职：</p><table><thead><tr><th>工具</th><th>一句话总结</th><th align="center">推荐指数</th></tr></thead><tbody><tr><td><strong>bat</strong></td><td>带翅膀的 cat，高亮 + Git</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>eza</strong></td><td>彩色 ls，图标 + Git</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>fd</strong></td><td>极速 find，智能过滤</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>fzf</strong></td><td>模糊搜索神器，交互式选择</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>zoxide</strong></td><td>智能跳转，学习你的习惯</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>yazi</strong></td><td>终端文件管理器，异步架构</td><td align="center">⭐⭐⭐⭐</td></tr></tbody></table><h3 id="最终建议"><a href="#最终建议" class="headerlink" title="最终建议"></a>最终建议</h3><ol><li><strong>全部安装</strong> — 包管理器一键安装，无依赖冲突</li><li><strong>配置别名</strong> — 替代传统命令，潜移默化提升效率</li><li><strong>组合使用</strong> — fd + fzf + bat 形成搜索-选择-查看流</li><li><strong>Yazi 集成</strong> — 内置所有工具，统一入口</li></ol><hr><h2 id="延伸阅读"><a href="#延伸阅读" class="headerlink" title="延伸阅读"></a>延伸阅读</h2><ul><li><a href="https://github.com/sharkdp/bat">bat GitHub</a></li><li><a href="https://github.com/eza-community/eza">eza GitHub</a></li><li><a href="https://github.com/sharkdp/fd">fd GitHub</a></li><li><a href="https://github.com/junegunn/fzf">fzf GitHub</a></li><li><a href="https://github.com/ajeetdsouza/zoxide">zoxide GitHub</a></li><li><a href="https://github.com/sxyazi/yazi">yazi GitHub</a></li><li><a href="/posts/yazi-file-manager-guide/">Yazi 终端文件管理器使用指南</a></li><li><a href="/posts/grep-vs-ripgrep-vs-astgrep/">Grep vs Ripgrep vs AST-Grep对比</a></li></ul><hr><blockquote><p>💡 <strong>提示</strong>: 这些工具都是 Rust 或 Go 编写，性能强悍。全部安装后，配置别名替代传统命令，效率提升立竿见影。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/modern-cli-tools-guide/</id>
    <link href="https://imwnk.cn/archives/modern-cli-tools-guide/"/>
    <published>2026-03-30T02:00:00.000Z</published>
    <summary>介绍 FZF、FD、Yazi、eza、zoxide、bat 六款现代命令行工具，替代传统工具，提升终端操作效率</summary>
    <title>现代终端工具集 - 打造高效 CLI 工作流</title>
    <updated>2026-03-30T11:49:07.816Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="terminal" scheme="https://imwnk.cn/tags/terminal/"/>
    <category term="yazi" scheme="https://imwnk.cn/tags/yazi/"/>
    <category term="rust" scheme="https://imwnk.cn/tags/rust/"/>
    <content>
      <![CDATA[<blockquote><p><strong>版本</strong>: 基于 Yazi 26.1.x 官方文档整理<br><strong>更新时间</strong>: 2026年3月</p></blockquote><p>终端里敲 <code>ls</code>、<code>cd</code>、<code>rm</code>，文件多了眼花缭乱。想用鼠标？对不起，这是 CLI 世界。</p><p>有没有一个工具，能在终端里像 GUI 文件管理器那样操作，还能保持键盘流的高效？</p><p>Yazi 就是答案。</p><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E4%BB%80%E4%B9%88%E6%98%AF-yazi">什么是 Yazi</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7%E4%B8%80%E8%A7%88">核心特性一览</a></li><li><a href="#%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97">安装指南</a></li><li><a href="#%E9%85%8D%E7%BD%AE%E5%9F%BA%E7%A1%80">配置基础</a></li><li><a href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7">基本使用技巧</a></li><li><a href="#%E5%BF%AB%E6%8D%B7%E9%94%AE%E8%AF%A6%E8%A7%A3">快捷键详解</a></li><li><a href="#%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F">插件系统</a></li><li><a href="#%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%8E%9F%E7%90%86">性能优化原理</a></li><li><a href="#%E5%AE%9E%E7%94%A8%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B">实用配置示例</a></li><li><a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">常见问题</a></li></ol><hr><h2 id="什么是-Yazi"><a href="#什么是-Yazi" class="headerlink" title="什么是 Yazi"></a>什么是 Yazi</h2><p><strong>Yazi</strong>（意为「鸭子」）是一个用 Rust 编写的终端文件管理器，基于非阻塞异步 I/O 设计。定位类似 ranger 和 lf，但性能更强、功能更现代：</p><ul><li><strong>全异步架构</strong>：所有 I/O 操作异步执行，CPU 任务多线程分散</li><li><strong>内置图片预览</strong>：支持 Kitty、iTerm2、Sixel 等多种协议</li><li><strong>代码高亮</strong>：内置语法高亮，无需依赖外部工具</li><li><strong>插件系统</strong>：Lua 插件扩展，UI、预览器、功能插件都能自定义</li><li><strong>包管理器</strong>：一键安装/更新插件和主题</li></ul><p>项目地址：<a href="https://github.com/sxyazi/yazi">https://github.com/sxyazi/yazi</a></p><hr><h2 id="核心特性一览"><a href="#核心特性一览" class="headerlink" title="核心特性一览"></a>核心特性一览</h2><h3 id="滚动预览"><a href="#滚动预览" class="headerlink" title="滚动预览"></a>滚动预览</h3><p>预览各种类型文件，还能在预览区滚动内容：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 支持预览的文件类型：</span></span><br><span class="line"><span class="comment"># - 图片（PNG、JPEG、GIF、SVG 等）</span></span><br><span class="line"><span class="comment"># - 视频（通过 ffmpeg 生成缩略图）</span></span><br><span class="line"><span class="comment"># - PDF（通过 poppler）</span></span><br><span class="line"><span class="comment"># - 代码文件（内置语法高亮）</span></span><br><span class="line"><span class="comment"># - JSON（通过 jq 格式化）</span></span><br><span class="line"><span class="comment"># - 目录（显示目录内容）</span></span><br><span class="line"><span class="comment"># - 压缩包（通过 7-Zip）</span></span><br></pre></td></tr></tbody></table></figure><p>用 <code>J</code>/<code>K</code> 滚动预览内容，无需打开文件。</p><h3 id="可视模式与批量重命名"><a href="#可视模式与批量重命名" class="headerlink" title="可视模式与批量重命名"></a>可视模式与批量重命名</h3><p>Vim 风格的可视模式，批量选择文件：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 按 v 进入可视模式</span></span><br><span class="line"><span class="comment"># 然后用 j/k 选择文件</span></span><br><span class="line"><span class="comment"># 可对选中文件执行：复制、移动、删除、批量重命名</span></span><br></pre></td></tr></tbody></table></figure><p>批量重命名时，Yazi 会打开编辑器让你批量修改文件名。</p><h3 id="多标签页"><a href="#多标签页" class="headerlink" title="多标签页"></a>多标签页</h3><p>类似浏览器，多标签页并行工作：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 标签页操作：</span></span><br><span class="line"><span class="comment"># 1-9    快速切换到标签页 1-9</span></span><br><span class="line"><span class="comment"># t      新建标签页</span></span><br><span class="line"><span class="comment"># [ / ]  切换上一个/下一个标签页</span></span><br><span class="line"><span class="comment"># q      关闭当前标签页（最后一个标签页则退出）</span></span><br></pre></td></tr></tbody></table></figure><h3 id="搜索集成"><a href="#搜索集成" class="headerlink" title="搜索集成"></a>搜索集成</h3><p>集成 fd、rg、fzf、zoxide：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 文件名搜索（使用 fd）</span></span><br><span class="line"><span class="comment"># 按 / 进入搜索模式</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 内容搜索（使用 rg）</span></span><br><span class="line"><span class="comment"># 按 s 进入内容搜索</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fzf 快速跳转</span></span><br><span class="line"><span class="comment"># 按 f 使用 fzf 选择文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># zoxide 历史目录跳转</span></span><br><span class="line"><span class="comment"># 按 z 使用 zoxide 快速导航</span></span><br></pre></td></tr></tbody></table></figure><h3 id="任务管理系统"><a href="#任务管理系统" class="headerlink" title="任务管理系统"></a>任务管理系统</h3><p>复制、移动等操作由任务系统调度：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 任务特性：</span></span><br><span class="line"><span class="comment"># - 实时进度显示</span></span><br><span class="line"><span class="comment"># - 任务可取消</span></span><br><span class="line"><span class="comment"># - 内部优先级分配</span></span><br><span class="line"><span class="comment"># - 异步非阻塞执行</span></span><br></pre></td></tr></tbody></table></figure><p>按 <code>w</code> 打开任务管理器查看进度。</p><h3 id="增量查找"><a href="#增量查找" class="headerlink" title="增量查找"></a>增量查找</h3><p>实时增量查找，显示当前位置和匹配数量：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 按 f 进入增量查找</span></span><br><span class="line"><span class="comment"># 输入字符实时过滤文件</span></span><br><span class="line"><span class="comment"># 显示匹配数量和当前位置</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="安装指南"><a href="#安装指南" class="headerlink" title="安装指南"></a>安装指南</h2><h3 id="依赖项"><a href="#依赖项" class="headerlink" title="依赖项"></a>依赖项</h3><p><strong>必需依赖</strong>：</p><ul><li><code>file</code> - 文件类型检测</li></ul><p><strong>可选依赖</strong>（推荐安装）：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install ffmpeg 7zip jq poppler fd ripgrep fzf zoxide resvg imagemagick</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line"><span class="built_in">sudo</span> pacman -S yazi ffmpeg 7zip jq poppler fd ripgrep fzf zoxide resvg imagemagick</span><br><span class="line"></span><br><span class="line"><span class="comment"># Ubuntu/Debian</span></span><br><span class="line"><span class="built_in">sudo</span> apt install yazi ffmpeg 7zip jq poppler-utils fd-find ripgrep fzf zoxide</span><br></pre></td></tr></tbody></table></figure><h3 id="包管理器安装"><a href="#包管理器安装" class="headerlink" title="包管理器安装"></a>包管理器安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install yazi</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line"><span class="built_in">sudo</span> pacman -S yazi</span><br><span class="line"></span><br><span class="line"><span class="comment"># Nix</span></span><br><span class="line">nix-env -iA nixpkgs.yazi</span><br><span class="line"></span><br><span class="line"><span class="comment"># Cargo（需要 Rust 环境）</span></span><br><span class="line">cargo install --locked yazi</span><br></pre></td></tr></tbody></table></figure><h3 id="手动下载"><a href="#手动下载" class="headerlink" title="手动下载"></a>手动下载</h3><p>从 <a href="https://github.com/sxyazi/yazi/releases">Release 页面</a> 下载预编译二进制：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Linux / macOS</span></span><br><span class="line">tar -xvf yazi*.tar.gz</span><br><span class="line"><span class="built_in">chmod</span> +x yazi</span><br><span class="line"><span class="built_in">mv</span> yazi ~/.local/bin/</span><br></pre></td></tr></tbody></table></figure><h3 id="启动方式"><a href="#启动方式" class="headerlink" title="启动方式"></a>启动方式</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 直接启动</span></span><br><span class="line">yazi</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动并退出时输出当前目录（适合 shell 集成）</span></span><br><span class="line">yazi --cwd-file=/tmp/yazi-cwd</span><br><span class="line"></span><br><span class="line"><span class="comment"># Shell 集成（添加到 shell 配置）</span></span><br><span class="line"><span class="comment"># Bash (~/.bashrc)</span></span><br><span class="line"><span class="keyword">function</span> <span class="function"><span class="title">y</span></span>() {</span><br><span class="line">    tmp=<span class="string">"<span class="subst">$(mktemp -t <span class="string">"yazi-cwd.XXXXXX"</span>)</span>"</span></span><br><span class="line">    yazi --cwd-file=<span class="string">"<span class="variable">$tmp</span>"</span></span><br><span class="line">    cwd=<span class="string">"<span class="subst">$(cat <span class="string">"<span class="variable">$tmp</span>"</span>)</span>"</span></span><br><span class="line">    <span class="keyword">if</span> [ -n <span class="string">"<span class="variable">$cwd</span>"</span> ] &amp;&amp; [ <span class="string">"<span class="variable">$cwd</span>"</span> != <span class="string">"<span class="variable">$PWD</span>"</span> ]; <span class="keyword">then</span></span><br><span class="line">        <span class="built_in">cd</span> <span class="string">"<span class="variable">$cwd</span>"</span></span><br><span class="line">    <span class="keyword">fi</span></span><br><span class="line">    <span class="built_in">rm</span> -f <span class="string">"<span class="variable">$tmp</span>"</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment"># Fish (~/.config/fish/functions/y.fish)</span></span><br><span class="line"><span class="keyword">function</span> y</span><br><span class="line">    <span class="built_in">set</span> tmp (<span class="built_in">mktemp</span> -t <span class="string">"yazi-cwd.XXXXXX"</span>)</span><br><span class="line">    yazi --cwd-file=<span class="variable">$tmp</span></span><br><span class="line">    <span class="built_in">set</span> cwd (<span class="built_in">cat</span> <span class="variable">$tmp</span>)</span><br><span class="line">    <span class="keyword">if</span> [ -n <span class="string">"<span class="variable">$cwd</span>"</span> ] &amp;&amp; [ <span class="string">"<span class="variable">$cwd</span>"</span> != <span class="string">"<span class="variable">$PWD</span>"</span> ]</span><br><span class="line">        <span class="built_in">cd</span> <span class="variable">$cwd</span></span><br><span class="line">    end</span><br><span class="line">    <span class="built_in">rm</span> -f <span class="variable">$tmp</span></span><br><span class="line">end</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="配置基础"><a href="#配置基础" class="headerlink" title="配置基础"></a>配置基础</h2><h3 id="配置文件位置"><a href="#配置文件位置" class="headerlink" title="配置文件位置"></a>配置文件位置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Unix-like 系统</span></span><br><span class="line">~/.config/yazi/</span><br><span class="line">├── yazi.toml      <span class="comment"># 主配置</span></span><br><span class="line">├── keymap.toml    <span class="comment"># 快捷键配置</span></span><br><span class="line">├── theme.toml     <span class="comment"># 主题配置</span></span><br><span class="line">├── init.lua       <span class="comment"># Lua 初始化脚本</span></span><br><span class="line">└── plugins/       <span class="comment"># 插件目录</span></span><br><span class="line">    └── foo.yazi/</span><br><span class="line">        ├── main.lua</span><br><span class="line">        └── README.md</span><br></pre></td></tr></tbody></table></figure><h3 id="生成默认配置"><a href="#生成默认配置" class="headerlink" title="生成默认配置"></a>生成默认配置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Yazi 会自动使用默认配置</span></span><br><span class="line"><span class="comment"># 如需自定义，创建配置文件即可</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 示例：创建 yazi.toml</span></span><br><span class="line"><span class="built_in">mkdir</span> -p ~/.config/yazi</span><br></pre></td></tr></tbody></table></figure><h3 id="主配置-yazi-toml"><a href="#主配置-yazi-toml" class="headerlink" title="主配置 yazi.toml"></a>主配置 yazi.toml</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/yazi.toml</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mgr]</span></span><br><span class="line"><span class="comment"># 布局比例：[父目录, 当前目录, 预览]</span></span><br><span class="line"><span class="attr">ratio</span> = [<span class="number">1</span>, <span class="number">4</span>, <span class="number">3</span>]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 排序方式</span></span><br><span class="line"><span class="attr">sort_by</span> = <span class="string">"natural"</span>        <span class="comment"># none, mtime, btime, extension, alphabetical, natural, size, random</span></span><br><span class="line"><span class="attr">sort_sensitive</span> = <span class="literal">false</span>     <span class="comment"># 是否区分大小写</span></span><br><span class="line"><span class="attr">sort_reverse</span> = <span class="literal">false</span>       <span class="comment"># 反向排序</span></span><br><span class="line"><span class="attr">sort_dir_first</span> = <span class="literal">true</span>      <span class="comment"># 目录优先</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示隐藏文件</span></span><br><span class="line"><span class="attr">show_hidden</span> = <span class="literal">false</span></span><br><span class="line"><span class="attr">show_symlink</span> = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 滚动偏移（光标上下保留的文件数）</span></span><br><span class="line"><span class="attr">scrolloff</span> = <span class="number">5</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 行模式（右侧显示的信息）</span></span><br><span class="line"><span class="attr">linemode</span> = <span class="string">"none"</span>          <span class="comment"># none, size, btime, mtime, permissions, owner</span></span><br><span class="line"></span><br><span class="line"><span class="section">[preview]</span></span><br><span class="line"><span class="comment"># 预览设置</span></span><br><span class="line"><span class="attr">wrap</span> = <span class="string">"no"</span>                <span class="comment"># 代码预览换行</span></span><br><span class="line"><span class="attr">tab_size</span> = <span class="number">4</span>               <span class="comment"># Tab 宽度</span></span><br><span class="line"><span class="attr">max_width</span> = <span class="number">600</span>            <span class="comment"># 图片预览最大宽度</span></span><br><span class="line"><span class="attr">max_height</span> = <span class="number">900</span>           <span class="comment"># 图片预览最大高度</span></span><br><span class="line"></span><br><span class="line"><span class="section">[opener]</span></span><br><span class="line"><span class="comment"># 文件打开器配置</span></span><br><span class="line"><span class="attr">edit</span> = [</span><br><span class="line">    { run = <span class="string">'nvim "$@"'</span>, block = <span class="literal">true</span>, desc = <span class="string">"nvim"</span> },</span><br><span class="line">]</span><br><span class="line"><span class="attr">open</span> = [</span><br><span class="line">    { run = <span class="string">'open "$@"'</span>, desc = <span class="string">"macOS open"</span> },</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="section">[open]</span></span><br><span class="line"><span class="comment"># 文件类型与打开器映射</span></span><br><span class="line"><span class="attr">rules</span> = [</span><br><span class="line">    { mime = <span class="string">"text/*"</span>, use = <span class="string">"edit"</span> },</span><br><span class="line">    { mime = <span class="string">"image/*"</span>, use = <span class="string">"open"</span> },</span><br><span class="line">    { name = <span class="string">"*.md"</span>, use = <span class="string">"edit"</span> },</span><br><span class="line">]</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="基本使用技巧"><a href="#基本使用技巧" class="headerlink" title="基本使用技巧"></a>基本使用技巧</h2><h3 id="首次启动"><a href="#首次启动" class="headerlink" title="首次启动"></a>首次启动</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">yazi      <span class="comment"># 启动</span></span><br><span class="line">yy        <span class="comment"># 如果配置了 shell 函数 y</span></span><br></pre></td></tr></tbody></table></figure><p>启动后看到三栏布局：</p><ul><li><strong>左栏</strong>：父目录</li><li><strong>中栏</strong>：当前目录（主操作区）</li><li><strong>右栏</strong>：文件预览</li></ul><h3 id="基本导航"><a href="#基本导航" class="headerlink" title="基本导航"></a>基本导航</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Vim 风格导航</span></span><br><span class="line">j / k      <span class="comment"># 下/上移动光标</span></span><br><span class="line">h / l      <span class="comment"># 进入父目录/进入子目录</span></span><br><span class="line">gg / G     <span class="comment"># 顶部/底部</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 快速跳转</span></span><br><span class="line">数字 + G   <span class="comment"># 跳转到指定行（如 5G 跳到第 5 行）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 翻页</span></span><br><span class="line">Ctrl+d / Ctrl+u  <span class="comment"># 下翻半页/上翻半页</span></span><br><span class="line">Ctrl+f / Ctrl+b  <span class="comment"># 下翻一页/上翻一页</span></span><br></pre></td></tr></tbody></table></figure><h3 id="文件操作"><a href="#文件操作" class="headerlink" title="文件操作"></a>文件操作</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 选择文件</span></span><br><span class="line">Space      <span class="comment"># 选择/取消当前文件</span></span><br><span class="line">v          <span class="comment"># 进入可视模式（批量选择）</span></span><br><span class="line">V          <span class="comment"># 退出可视模式</span></span><br><span class="line">Ctrl+a     <span class="comment"># 选择所有文件</span></span><br><span class="line">Ctrl+r     <span class="comment"># 反选</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 复制/移动/删除</span></span><br><span class="line">y          <span class="comment"># 复制（yank）</span></span><br><span class="line">x          <span class="comment"># 剪切</span></span><br><span class="line">p          <span class="comment"># 粘贴</span></span><br><span class="line">d          <span class="comment"># 删除到回收站</span></span><br><span class="line">D          <span class="comment"># 永久删除</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建/重命名</span></span><br><span class="line">a          <span class="comment"># 新建文件</span></span><br><span class="line">r          <span class="comment"># 重命名</span></span><br><span class="line">;          <span class="comment"># 新建目录</span></span><br></pre></td></tr></tbody></table></figure><h3 id="搜索与跳转"><a href="#搜索与跳转" class="headerlink" title="搜索与跳转"></a>搜索与跳转</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 增量查找</span></span><br><span class="line">f          <span class="comment"># 进入查找模式，输入字符实时过滤</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 文件搜索（使用 fd）</span></span><br><span class="line">/          <span class="comment"># 搜索文件名</span></span><br><span class="line">s          <span class="comment"># 搜索文件内容（使用 rg）</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># fzf/zoxide 集成</span></span><br><span class="line">f          <span class="comment"># fzf 快速跳转（按两次）</span></span><br><span class="line">z          <span class="comment"># zoxide 历史目录跳转</span></span><br><span class="line">Z          <span class="comment"># zoxide 子目录跳转</span></span><br></pre></td></tr></tbody></table></figure><h3 id="打开文件"><a href="#打开文件" class="headerlink" title="打开文件"></a>打开文件</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">Enter      <span class="comment"># 用默认程序打开</span></span><br><span class="line">o          <span class="comment"># 打开方式选择器</span></span><br><span class="line">O          <span class="comment"># 用指定打开器打开</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 编辑器</span></span><br><span class="line">e          <span class="comment"># 用 $EDITOR 打开</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="快捷键详解"><a href="#快捷键详解" class="headerlink" title="快捷键详解"></a>快捷键详解</h2><h3 id="快捷键配置-keymap-toml"><a href="#快捷键配置-keymap-toml" class="headerlink" title="快捷键配置 keymap.toml"></a>快捷键配置 keymap.toml</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/keymap.toml</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mgr]</span></span><br><span class="line"><span class="attr">prepend_keymap</span> = [</span><br><span class="line">    <span class="comment"># 添加自定义快捷键（优先级高于默认）</span></span><br><span class="line">    { <span class="literal">on</span> = <span class="string">"&lt;C-a&gt;"</span>, run = <span class="string">"select_all"</span>, desc = <span class="string">"选择所有文件"</span> },</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="attr">append_keymap</span> = [</span><br><span class="line">    <span class="comment"># 添加快捷键（优先级低于默认）</span></span><br><span class="line">    { <span class="literal">on</span> = [<span class="string">"g"</span>, <span class="string">"h"</span>], run = <span class="string">"cd ~"</span>, desc = <span class="string">"跳转到 Home"</span> },</span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 完全自定义（覆盖默认）</span></span><br><span class="line"><span class="attr">keymap</span> = [</span><br><span class="line">    { <span class="literal">on</span> = <span class="string">"j"</span>, run = <span class="string">"arrow 1"</span>, desc = <span class="string">"向下移动"</span> },</span><br><span class="line">    { <span class="literal">on</span> = <span class="string">"k"</span>, run = <span class="string">"arrow -1"</span>, desc = <span class="string">"向上移动"</span> },</span><br><span class="line">]</span><br></pre></td></tr></tbody></table></figure><h3 id="快捷键语法"><a href="#快捷键语法" class="headerlink" title="快捷键语法"></a>快捷键语法</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"># 单键</span><br><span class="line">{ on = "j", run = "arrow 1" }</span><br><span class="line"></span><br><span class="line"># 组合键</span><br><span class="line">{ on = "&lt;C-a&gt;", run = "select_all" }     # Ctrl + a</span><br><span class="line">{ on = "&lt;S-a&gt;", run = "action" }         # Shift + a</span><br><span class="line">{ on = "&lt;A-a&gt;", run = "action" }         # Alt + a</span><br><span class="line"></span><br><span class="line"># 序列键</span><br><span class="line">{ on = ["g", "h"], run = "cd ~" }        # 先 g 后 h</span><br><span class="line"></span><br><span class="line"># 多动作</span><br><span class="line">{ on = "x", run = ["yank", "remove"], desc = "剪切" }</span><br></pre></td></tr></tbody></table></figure><h3 id="常用快捷键表"><a href="#常用快捷键表" class="headerlink" title="常用快捷键表"></a>常用快捷键表</h3><table><thead><tr><th>快捷键</th><th>动作</th><th>说明</th></tr></thead><tbody><tr><td><code>j/k</code></td><td>arrow</td><td>下/上移动</td></tr><tr><td><code>h/l</code></td><td>leave/enter</td><td>父目录/子目录</td></tr><tr><td><code>gg/G</code></td><td>顶部/底部</td><td></td></tr><tr><td><code>Space</code></td><td>select</td><td>选择文件</td></tr><tr><td><code>v</code></td><td>visual</td><td>可视模式</td></tr><tr><td><code>y/x/p</code></td><td>yank/cut/paste</td><td>复制/剪切/粘贴</td></tr><tr><td><code>d/D</code></td><td>remove</td><td>删除到回收站/永久删除</td></tr><tr><td><code>a/r</code></td><td>create/rename</td><td>新建/重命名</td></tr><tr><td><code>Enter</code></td><td>open</td><td>打开文件</td></tr><tr><td><code>o</code></td><td>open –chooser</td><td>选择打开方式</td></tr><tr><td><code>/</code></td><td>search fd</td><td>搜索文件名</td></tr><tr><td><code>s</code></td><td>search rg</td><td>搜索内容</td></tr><tr><td><code>f</code></td><td>find</td><td>增量查找</td></tr><tr><td><code>z/Z</code></td><td>zoxide</td><td>历史目录跳转</td></tr><tr><td><code>t</code></td><td>tab_create</td><td>新建标签页</td></tr><tr><td><code>1-9</code></td><td>tab_switch</td><td>切换标签页</td></tr><tr><td><code>q</code></td><td>quit</td><td>退出</td></tr><tr><td><code>w</code></td><td>tasks_show</td><td>任务管理器</td></tr><tr><td><code>?</code></td><td>help</td><td>帮助菜单</td></tr><tr><td><code>.</code></td><td>toggle_hidden</td><td>显示隐藏文件</td></tr><tr><td><code>Ctrl+s</code></td><td>shell</td><td>执行 shell 命令</td></tr></tbody></table><hr><h2 id="插件系统"><a href="#插件系统" class="headerlink" title="插件系统"></a>插件系统</h2><h3 id="插件结构"><a href="#插件结构" class="headerlink" title="插件结构"></a>插件结构</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">~/.config/yazi/plugins/</span><br><span class="line">└── my-plugin.yazi/</span><br><span class="line">    ├── main.lua      # 入口文件</span><br><span class="line">    ├── README.md     # 文档</span><br><span class="line">    └── LICENSE       # 许可证</span><br></pre></td></tr></tbody></table></figure><h3 id="使用插件"><a href="#使用插件" class="headerlink" title="使用插件"></a>使用插件</h3><p><strong>功能插件</strong>（绑定快捷键）：</p><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/keymap.toml</span></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = <span class="string">"T"</span></span><br><span class="line"><span class="attr">run</span> = <span class="string">"plugin toggle-pane max-preview"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"最大化预览面板"</span></span><br></pre></td></tr></tbody></table></figure><p><strong>预览器插件</strong>：</p><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/yazi.toml</span></span><br><span class="line"><span class="section">[plugin]</span></span><br><span class="line"><span class="attr">prepend_previewers</span> = [</span><br><span class="line">    { name = <span class="string">"*.md"</span>, run = <span class="string">"glow"</span> },  <span class="comment"># Markdown 渲染</span></span><br><span class="line">]</span><br></pre></td></tr></tbody></table></figure><h3 id="官方插件"><a href="#官方插件" class="headerlink" title="官方插件"></a>官方插件</h3><p>Yazi 提供官方插件仓库：<a href="https://github.com/yazi-rs/plugins">yazi-rs/plugins</a></p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 使用包管理器安装</span></span><br><span class="line">ya pack -a yazi-rs/plugins:git         <span class="comment"># Git 集成</span></span><br><span class="line">ya pack -a yazi-rs/plugins:mount       <span class="comment"># 挂载管理</span></span><br><span class="line">ya pack -a yazi-rs/plugins:<span class="built_in">chmod</span>       <span class="comment"># 权限修改</span></span><br><span class="line">ya pack -a yazi-rs/plugins:full-border <span class="comment"># 边框美化</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 或手动克隆</span></span><br><span class="line">git <span class="built_in">clone</span> https://github.com/yazi-rs/plugins ~/.config/yazi/plugins</span><br></pre></td></tr></tbody></table></figure><h3 id="插件示例"><a href="#插件示例" class="headerlink" title="插件示例"></a>插件示例</h3><figure class="highlight lua"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- ~/.config/yazi/plugins/test.yazi/main.lua</span></span><br><span class="line"><span class="keyword">return</span> {</span><br><span class="line">    entry = <span class="function"><span class="keyword">function</span><span class="params">(self, job)</span></span></span><br><span class="line">        <span class="comment">-- job.args 获取参数</span></span><br><span class="line">        ya.dbg(job.args[<span class="number">1</span>])</span><br><span class="line">        </span><br><span class="line">        <span class="comment">-- 获取当前文件</span></span><br><span class="line">        <span class="keyword">local</span> hovered = cx.active.current.hovered</span><br><span class="line">        <span class="keyword">if</span> hovered <span class="keyword">then</span></span><br><span class="line">            ya.dbg(<span class="string">"当前文件: "</span> .. hovered.url)</span><br><span class="line">        <span class="keyword">end</span></span><br><span class="line">    <span class="keyword">end</span>,</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="初始化脚本-init-lua"><a href="#初始化脚本-init-lua" class="headerlink" title="初始化脚本 init.lua"></a>初始化脚本 init.lua</h3><figure class="highlight lua"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- ~/.config/yazi/init.lua</span></span><br><span class="line"></span><br><span class="line"><span class="comment">-- 设置插件配置</span></span><br><span class="line"><span class="built_in">require</span>(<span class="string">"full-border"</span>):setup {</span><br><span class="line">    <span class="built_in">type</span> = <span class="string">"rounded"</span>,  <span class="comment">-- 边框样式</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">-- 自定义 linemode</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Linemode:size_and_mtime</span><span class="params">()</span></span></span><br><span class="line">    <span class="keyword">local</span> <span class="built_in">time</span> = <span class="built_in">math</span>.<span class="built_in">floor</span>(<span class="built_in">self</span>._file.cha.mtime <span class="keyword">or</span> <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">local</span> size = <span class="built_in">self</span>._file:size()</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">string</span>.<span class="built_in">format</span>(<span class="string">"%s %s"</span>, </span><br><span class="line">        size <span class="keyword">and</span> ya.readable_size(size) <span class="keyword">or</span> <span class="string">"-"</span>,</span><br><span class="line">        <span class="built_in">time</span> &gt; <span class="number">0</span> <span class="keyword">and</span> <span class="built_in">os</span>.<span class="built_in">date</span>(<span class="string">"%b %d %H:%M"</span>, <span class="built_in">time</span>) <span class="keyword">or</span> <span class="string">""</span></span><br><span class="line">    )</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="性能优化原理"><a href="#性能优化原理" class="headerlink" title="性能优化原理"></a>性能优化原理</h2><p>Yazi 为什么快？几个关键设计：</p><h3 id="全异步架构"><a href="#全异步架构" class="headerlink" title="全异步架构"></a>全异步架构</h3><p>所有 I/O 操作都是异步的：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 异步任务类型：</span><br><span class="line"># - 目录加载</span><br><span class="line"># - 文件预览</span><br><span class="line"># - 图片处理</span><br><span class="line"># - 代码高亮</span><br><span class="line"># - 任务调度</span><br></pre></td></tr></tbody></table></figure><p>使用 Tokio 作为异步运行时，CPU 任务多线程分散。</p><h3 id="分块加载"><a href="#分块加载" class="headerlink" title="分块加载"></a>分块加载</h3><p>大目录（如 10 万文件）不会一次性加载：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 分块加载策略：</span></span><br><span class="line"><span class="comment"># - 只加载当前页面的文件</span></span><br><span class="line"><span class="comment"># - 后台预加载后续页面</span></span><br><span class="line"><span class="comment"># - 滚动时动态加载</span></span><br></pre></td></tr></tbody></table></figure><p>对比 <code>ls</code> 和 <code>eza</code> 必须加载全部文件，Yazi 响应更快。</p><h3 id="预加载机制"><a href="#预加载机制" class="headerlink" title="预加载机制"></a>预加载机制</h3><p>预加载器异步处理耗时任务：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"># 内置预加载器：</span><br><span class="line"># - Mimetype: 批量计算文件类型</span><br><span class="line"># - Image: 两阶段处理（预处理 + 实时缩放）</span><br><span class="line"># - Video: ffmpeg 提取缩略图</span><br><span class="line"># - PDF: poppler 渲染</span><br><span class="line"># - Directory size: 懒计算（仅按大小排序时）</span><br></pre></td></tr></tbody></table></figure><p>预加载只处理当前页面的文件，节省资源。</p><h3 id="可丢弃任务"><a href="#可丢弃任务" class="headerlink" title="可丢弃任务"></a>可丢弃任务</h3><p>切换文件时，未完成的预览任务直接丢弃：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 任务丢弃策略：</span><br><span class="line"># - I/O 任务：Tokio abort</span><br><span class="line"># - CPU 任务：Atomic ticket 检查</span><br><span class="line"># - Lua 任务：定期检查取消标志</span><br></pre></td></tr></tbody></table></figure><p>避免资源浪费在不再需要的任务上。</p><h3 id="内置代码高亮"><a href="#内置代码高亮" class="headerlink" title="内置代码高亮"></a>内置代码高亮</h3><p>不需要外部工具如 <code>bat</code>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"># 代码高亮优化：</span><br><span class="line"># - 只高亮可见行数</span><br><span class="line"># - 多线程分散处理</span><br><span class="line"># - 外部工具（如 jq）读取后立即终止</span><br></pre></td></tr></tbody></table></figure><p>其他依赖 <code>bat</code> 的工具需要等待整个文件高亮完成。</p><hr><h2 id="实用配置示例"><a href="#实用配置示例" class="headerlink" title="实用配置示例"></a>实用配置示例</h2><h3 id="🚀-开发者推荐配置"><a href="#🚀-开发者推荐配置" class="headerlink" title="🚀 开发者推荐配置"></a>🚀 开发者推荐配置</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/yazi.toml</span></span><br><span class="line"></span><br><span class="line"><span class="section">[mgr]</span></span><br><span class="line"><span class="attr">ratio</span> = [<span class="number">1</span>, <span class="number">4</span>, <span class="number">4</span>]</span><br><span class="line"><span class="attr">sort_by</span> = <span class="string">"natural"</span></span><br><span class="line"><span class="attr">sort_dir_first</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">show_hidden</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">linemode</span> = <span class="string">"size_and_mtime"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[preview]</span></span><br><span class="line"><span class="attr">max_width</span> = <span class="number">1000</span></span><br><span class="line"><span class="attr">max_height</span> = <span class="number">1000</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[plugin.prepend_previewers]]</span></span><br><span class="line"><span class="attr">name</span> = <span class="string">"*.md"</span></span><br><span class="line"><span class="attr">run</span> = <span class="string">"glow"</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight lua"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">-- ~/.config/yazi/init.lua</span></span><br><span class="line"><span class="built_in">require</span>(<span class="string">"full-border"</span>):setup()</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Linemode:size_and_mtime</span><span class="params">()</span></span></span><br><span class="line">    <span class="keyword">local</span> <span class="built_in">time</span> = <span class="built_in">math</span>.<span class="built_in">floor</span>(<span class="built_in">self</span>._file.cha.mtime <span class="keyword">or</span> <span class="number">0</span>)</span><br><span class="line">    <span class="keyword">local</span> size = <span class="built_in">self</span>._file:size()</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">string</span>.<span class="built_in">format</span>(<span class="string">"%s %s"</span>,</span><br><span class="line">        size <span class="keyword">and</span> ya.readable_size(size) <span class="keyword">or</span> <span class="string">"-"</span>,</span><br><span class="line">        <span class="built_in">time</span> &gt; <span class="number">0</span> <span class="keyword">and</span> <span class="built_in">os</span>.<span class="built_in">date</span>(<span class="string">"%m/%d %H:%M"</span>, <span class="built_in">time</span>) <span class="keyword">or</span> <span class="string">""</span></span><br><span class="line">    )</span><br><span class="line"><span class="keyword">end</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/keymap.toml</span></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"h"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd ~"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到 Home"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"c"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd ~/.config"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到配置目录"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"d"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd ~/Downloads"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到下载目录"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="🎨-主题配置"><a href="#🎨-主题配置" class="headerlink" title="🎨 主题配置"></a>🎨 主题配置</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/theme.toml</span></span><br><span class="line"></span><br><span class="line"><span class="section">[flavor]</span></span><br><span class="line"><span class="attr">use</span> = <span class="string">"catppuccin-mocha"</span>  <span class="comment"># 使用内置主题</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 或自定义颜色</span></span><br><span class="line"><span class="section">[mgr]</span></span><br><span class="line"><span class="attr">active</span> = { fg = <span class="string">"#cdd6f4"</span>, bg = <span class="string">"#1e1e2e"</span> }</span><br><span class="line"><span class="attr">hovered</span> = { fg = <span class="string">"#f38ba8"</span>, bg = <span class="string">"#313244"</span> }</span><br></pre></td></tr></tbody></table></figure><h3 id="🔧-快速跳转配置"><a href="#🔧-快速跳转配置" class="headerlink" title="🔧 快速跳转配置"></a>🔧 快速跳转配置</h3><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/keymap.toml</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"r"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd /"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到根目录"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"w"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd ~/Work"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到工作目录"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = [<span class="string">"g"</span>, <span class="string">"p"</span>]</span><br><span class="line"><span class="attr">run</span> = <span class="string">"cd ~/Projects"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"跳转到项目目录"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="Q-图片预览不显示？"><a href="#Q-图片预览不显示？" class="headerlink" title="Q: 图片预览不显示？"></a>Q: 图片预览不显示？</h3><p><strong>A</strong>: 检查终端是否支持图片协议：</p><table><thead><tr><th>终端</th><th>协议</th><th>支持状态</th></tr></thead><tbody><tr><td>Kitty</td><td>Kitty Unicode</td><td>✅ 内置</td></tr><tr><td>iTerm2</td><td>Inline Images</td><td>✅ 内置</td></tr><tr><td>WezTerm</td><td>Inline Images</td><td>✅ 内置</td></tr><tr><td>Ghostty</td><td>Kitty Unicode</td><td>✅ 内置</td></tr><tr><td>Konsole</td><td>Kitty Old</td><td>✅ 内置</td></tr><tr><td>foot</td><td>Sixel</td><td>✅ 内置</td></tr><tr><td>Windows Terminal</td><td>Sixel</td><td>✅ 内置（&gt;= v1.22）</td></tr></tbody></table><p>确保安装了 <code>ffmpeg</code>（视频预览）和 <code>imagemagick</code>（某些图片格式）。</p><h3 id="Q-如何自定义文件打开方式？"><a href="#Q-如何自定义文件打开方式？" class="headerlink" title="Q: 如何自定义文件打开方式？"></a>Q: 如何自定义文件打开方式？</h3><p><strong>A</strong>: 配置 <code>yazi.toml</code> 的 <code>[opener]</code> 和 <code>[open]</code>：</p><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[opener]</span></span><br><span class="line"><span class="attr">edit</span> = [</span><br><span class="line">    { run = <span class="string">'nvim "$@"'</span>, block = <span class="literal">true</span> },</span><br><span class="line">]</span><br><span class="line"><span class="attr">image</span> = [</span><br><span class="line">    { run = <span class="string">'open "$@"'</span>, orphan = <span class="literal">true</span> },  <span class="comment"># macOS</span></span><br><span class="line">]</span><br><span class="line"></span><br><span class="line"><span class="section">[[open.rules]]</span></span><br><span class="line"><span class="attr">mime</span> = <span class="string">"image/*"</span></span><br><span class="line"><span class="attr">use</span> = <span class="string">"image"</span></span><br><span class="line"></span><br><span class="line"><span class="section">[[open.rules]]</span></span><br><span class="line"><span class="attr">name</span> = <span class="string">"*.json"</span></span><br><span class="line"><span class="attr">use</span> = <span class="string">"edit"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-快捷键和-Vim-冲突？"><a href="#Q-快捷键和-Vim-冲突？" class="headerlink" title="Q: 快捷键和 Vim 冲突？"></a>Q: 快捷键和 Vim 冲突？</h3><p><strong>A</strong>: Yazi 默认使用 Vim 风格，不冲突。如需自定义：</p><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ~/.config/yazi/keymap.toml</span></span><br><span class="line"><span class="section">[[mgr.prepend_keymap]]</span></span><br><span class="line"><span class="attr">on</span> = <span class="string">"&lt;C-j&gt;"</span></span><br><span class="line"><span class="attr">run</span> = <span class="string">"arrow 1"</span></span><br><span class="line"><span class="attr">desc</span> = <span class="string">"向下移动（Ctrl+j）"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-如何显示隐藏文件？"><a href="#Q-如何显示隐藏文件？" class="headerlink" title="Q: 如何显示隐藏文件？"></a>Q: 如何显示隐藏文件？</h3><p><strong>A</strong>: 按 <code>.</code> 切换，或在配置中设置：</p><figure class="highlight toml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">[mgr]</span></span><br><span class="line"><span class="attr">show_hidden</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-退出后如何跳转到当前目录？"><a href="#Q-退出后如何跳转到当前目录？" class="headerlink" title="Q: 退出后如何跳转到当前目录？"></a>Q: 退出后如何跳转到当前目录？</h3><p><strong>A</strong>: 使用 shell 集成（见安装指南的 Shell 集成部分）。</p><h3 id="Q-如何批量重命名？"><a href="#Q-如何批量重命名？" class="headerlink" title="Q: 如何批量重命名？"></a>Q: 如何批量重命名？</h3><p><strong>A</strong>: </p><ol><li><code>v</code> 进入可视模式</li><li><code>j/k</code> 选择多个文件</li><li><code>r</code> 批量重命名</li><li>编辑器中修改文件名</li><li>保存退出</li></ol><hr><h2 id="与其他文件管理器对比"><a href="#与其他文件管理器对比" class="headerlink" title="与其他文件管理器对比"></a>与其他文件管理器对比</h2><table><thead><tr><th>维度</th><th>Yazi</th><th>ranger</th><th>lf</th></tr></thead><tbody><tr><td><strong>语言</strong></td><td>Rust</td><td>Python</td><td>Go</td></tr><tr><td><strong>异步架构</strong></td><td>✅ 全异步</td><td>❌</td><td>部分</td></tr><tr><td><strong>图片预览</strong></td><td>✅ 内置多协议</td><td>需配置</td><td>需配置</td></tr><tr><td><strong>代码高亮</strong></td><td>✅ 内置</td><td>需要 bat</td><td>需要 bat</td></tr><tr><td><strong>插件系统</strong></td><td>✅ Lua</td><td>Python</td><td>外部命令</td></tr><tr><td><strong>包管理器</strong></td><td>✅ 内置</td><td>❌</td><td>❌</td></tr><tr><td><strong>性能</strong></td><td>极快</td><td>较慢</td><td>快</td></tr><tr><td><strong>配置复杂度</strong></td><td>TOML（简单）</td><td>Python（复杂）</td><td>简单</td></tr></tbody></table><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Yazi 是现代终端文件管理器，核心优势：</p><table><thead><tr><th>优势</th><th>说明</th></tr></thead><tbody><tr><td><strong>性能强悍</strong></td><td>全异步 + 分块加载 + 预加载</td></tr><tr><td><strong>功能丰富</strong></td><td>图片预览、代码高亮、多标签页</td></tr><tr><td><strong>扩展灵活</strong></td><td>Lua 插件系统 + 包管理器</td></tr><tr><td><strong>上手简单</strong></td><td>Vim 风格快捷键 + 清晰配置</td></tr></tbody></table><p><strong>推荐场景</strong>：</p><ol><li><strong>日常文件管理</strong>：替代 <code>ls</code>/<code>cd</code>/<code>rm</code> 组合</li><li><strong>远程服务器</strong>：SSH 下高效操作文件</li><li><strong>开发工作流</strong>：快速浏览项目文件</li><li><strong>批量操作</strong>：可视模式批量处理</li></ol><hr><h2 id="延伸阅读"><a href="#延伸阅读" class="headerlink" title="延伸阅读"></a>延伸阅读</h2><ul><li><a href="https://yazi-rs.github.io/docs/installation">Yazi 官方文档</a></li><li><a href="https://github.com/sxyazi/yazi">Yazi GitHub</a></li><li><a href="https://yazi-rs.github.io/blog/why-is-yazi-fast">为什么 Yazi 快</a></li><li><a href="https://github.com/yazi-rs/plugins">插件仓库</a></li><li><a href="https://github.com/yazi-rs/flavors">主题仓库</a></li><li><a href="https://t.me/yazi_rs">Telegram 中文群</a></li><li><a href="https://discord.gg/qfADduSdJu">Discord 社区</a></li></ul><hr><blockquote><p>💡 <strong>提示</strong>: 如果你是 ranger 用户，迁移很简单。Yazi 的快捷键风格类似，配置更直观。可以先从默认配置体验，再逐步自定义。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/yazi-file-manager-guide/</id>
    <link href="https://imwnk.cn/archives/yazi-file-manager-guide/"/>
    <published>2026-03-28T08:00:00.000Z</published>
    <summary>Yazi 终端文件管理器的完整使用指南，涵盖核心特性、安装配置、快捷键、插件系统、性能优化等高级功能</summary>
    <title>Yazi - 终端文件管理器使用指南</title>
    <updated>2026-03-28T10:09:02.499Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="terminal" scheme="https://imwnk.cn/tags/terminal/"/>
    <category term="productivity" scheme="https://imwnk.cn/tags/productivity/"/>
    <category term="zellij" scheme="https://imwnk.cn/tags/zellij/"/>
    <content>
      <![CDATA[<blockquote><p><strong>版本</strong>: 基于 Zellij 0.41.x 官方文档整理<br><strong>更新时间</strong>: 2026年3月</p></blockquote><p>SSH 断开，正在跑的构建进程没了。三个终端窗口，每个都要手动切换。tmux 配置文件写了三年，还是记不住那些快捷键。</p><p>有没有一个工具，开箱即用，不需要花时间学，就能搞定这些？</p><p>Zellij 就是答案。</p><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E4%BB%80%E4%B9%88%E6%98%AF-zellij">什么是 Zellij</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E7%89%B9%E6%80%A7%E4%B8%80%E8%A7%88">核心特性一览</a></li><li><a href="#%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97">安装指南</a></li><li><a href="#%E9%85%8D%E7%BD%AE%E5%9F%BA%E7%A1%80">配置基础</a></li><li><a href="#%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8%E6%8A%80%E5%B7%A7">基本使用技巧</a></li><li><a href="#%E5%B8%83%E5%B1%80%E4%B8%8E%E8%87%AA%E5%8A%A8%E5%8C%96">布局与自动化</a></li><li><a href="#%E4%BC%9A%E8%AF%9D%E7%AE%A1%E7%90%86">会话管理</a></li><li><a href="#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD%E8%AF%A6%E8%A7%A3">高级功能详解</a></li><li><a href="#%E4%B8%8E-tmux-%E5%AF%B9%E6%AF%94">与 tmux 对比</a></li><li><a href="#%E5%AE%9E%E7%94%A8%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B">实用配置示例</a></li><li><a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98">常见问题</a></li></ol><hr><h2 id="什么是-Zellij"><a href="#什么是-Zellij" class="headerlink" title="什么是 Zellij"></a>什么是 Zellij</h2><p><strong>Zellij</strong> 是一个用 Rust 编写的终端工作空间，定位为现代版终端复用器（Terminal Multiplexer）。类似 tmux 和 screen，但设计理念不同：</p><ul><li><strong>开箱即用</strong>：不写配置文件也能高效工作</li><li><strong>现代 UI</strong>：浮动窗格、堆叠窗格、可视化界面</li><li><strong>可扩展</strong>：WebAssembly 插件系统，任何语言都能写插件</li><li><strong>协作友好</strong>：内置 Web 客户端，多人实时协作</li></ul><p>名字源自阿拉伯语”زليج”，一种精美的马赛克瓷砖工艺——把多个窗格拼接成精美的整体工作空间。</p><hr><h2 id="核心特性一览"><a href="#核心特性一览" class="headerlink" title="核心特性一览"></a>核心特性一览</h2><h3 id="浮动窗格"><a href="#浮动窗格" class="headerlink" title="浮动窗格"></a>浮动窗格</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 按 Alt+f 切换浮动窗格模式</span></span><br><span class="line"><span class="comment"># 浮动窗格可以：</span></span><br><span class="line"><span class="comment"># - 用鼠标或键盘移动位置</span></span><br><span class="line"><span class="comment"># - 自由调整大小</span></span><br><span class="line"><span class="comment"># - 固定在最上层（适合监控命令）</span></span><br><span class="line"><span class="comment"># - 平铺窗格 ⇄ 浮动窗格 相互转换</span></span><br></pre></td></tr></tbody></table></figure><p>浮动窗格是”一等公民”。在里面跑一个命令，隐藏后重新打开，命令还在后台运行。</p><h3 id="堆叠窗格"><a href="#堆叠窗格" class="headerlink" title="堆叠窗格"></a>堆叠窗格</h3><p>把多个窗格堆叠在一起：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 适合场景：</span></span><br><span class="line"><span class="comment"># - 编辑器多个 buffer 同时可见</span></span><br><span class="line"><span class="comment"># - 监控多个命令不占用水平空间</span></span><br><span class="line"><span class="comment"># - 按任务/上下文组织工作区</span></span><br></pre></td></tr></tbody></table></figure><p>用方向键在堆叠窗格间导航，动态调整大小。</p><h3 id="命令窗格"><a href="#命令窗格" class="headerlink" title="命令窗格"></a>命令窗格</h3><p>命令不只是输出，而是”一等公民”：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 命令窗格特性：</span></span><br><span class="line"><span class="comment"># - 查看命令退出码</span></span><br><span class="line"><span class="comment"># - 单按 Enter 重新运行</span></span><br><span class="line"><span class="comment"># - 可暂停启动，按需触发</span></span><br><span class="line"><span class="comment"># - 适合构建命令、测试、开发服务器</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Session-复活"><a href="#Session-复活" class="headerlink" title="Session 复活"></a>Session 复活</h3><p>关闭的会话可以完整恢复，包括窗格结构和运行的命令。即使重启系统后也能找回之前的工作状态。</p><hr><h2 id="安装指南"><a href="#安装指南" class="headerlink" title="安装指南"></a>安装指南</h2><h3 id="一键试用（不安装）"><a href="#一键试用（不安装）" class="headerlink" title="一键试用（不安装）"></a>一键试用（不安装）</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># bash / zsh</span></span><br><span class="line">bash &lt;(curl -L https://zellij.dev/launch)</span><br><span class="line"></span><br><span class="line"><span class="comment"># fish</span></span><br><span class="line">bash (curl -L https://zellij.dev/launch | psub)</span><br><span class="line"></span><br><span class="line"><span class="comment"># PowerShell</span></span><br><span class="line">irm https://zellij.dev/launch.ps1 | iex</span><br></pre></td></tr></tbody></table></figure><h3 id="Cargo-安装"><a href="#Cargo-安装" class="headerlink" title="Cargo 安装"></a>Cargo 安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 编译安装（需要 Rust 环境）</span></span><br><span class="line">cargo install --locked zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># 预编译二进制（更快）</span></span><br><span class="line">cargo binstall zellij</span><br></pre></td></tr></tbody></table></figure><h3 id="包管理器"><a href="#包管理器" class="headerlink" title="包管理器"></a>包管理器</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># macOS</span></span><br><span class="line">brew install zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># Arch Linux</span></span><br><span class="line">pacman -S zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># Debian/Ubuntu</span></span><br><span class="line"><span class="built_in">sudo</span> apt install zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># Fedora</span></span><br><span class="line"><span class="built_in">sudo</span> dnf install zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># Nix</span></span><br><span class="line">nix-env -iA nixpkgs.zellij</span><br></pre></td></tr></tbody></table></figure><h3 id="手动下载"><a href="#手动下载" class="headerlink" title="手动下载"></a>手动下载</h3><p>从 <a href="https://github.com/zellij-org/zellij/releases">Release 页面</a> 下载预编译二进制：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Linux / macOS</span></span><br><span class="line">tar -xvf zellij*.tar.gz</span><br><span class="line"><span class="built_in">chmod</span> +x zellij</span><br><span class="line">./zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加到 PATH</span></span><br><span class="line"><span class="built_in">mv</span> zellij ~/.local/bin/</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="配置基础"><a href="#配置基础" class="headerlink" title="配置基础"></a>配置基础</h2><h3 id="配置文件位置"><a href="#配置文件位置" class="headerlink" title="配置文件位置"></a>配置文件位置</h3><p>Zellij 使用 <strong>KDL</strong> (KDL Document Language) 作为配置语言：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 默认位置</span></span><br><span class="line"><span class="built_in">mkdir</span> ~/.config/zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成默认配置</span></span><br><span class="line">zellij setup --dump-config &gt; ~/.config/zellij/config.kdl</span><br></pre></td></tr></tbody></table></figure><p><strong>查找优先级</strong>：</p><ol><li><code>--config-dir</code> 命令行参数</li><li><code>ZELLIJ_CONFIG_DIR</code> 环境变量</li><li><code>$HOME/.config/zellij</code></li><li>系统默认位置：<ul><li>Linux: <code>/home/alice/.config/zellij</code></li><li>macOS: <code>/Users/Alice/Library/Application Support/org.Zellij-Contributors.Zellij</code></li></ul></li><li><code>/etc/zellij</code> (系统级)</li></ol><h3 id="绕过配置文件"><a href="#绕过配置文件" class="headerlink" title="绕过配置文件"></a>绕过配置文件</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定配置文件</span></span><br><span class="line">zellij --config /path/to/config.kdl</span><br><span class="line"></span><br><span class="line"><span class="comment"># 环境变量</span></span><br><span class="line"><span class="built_in">export</span> ZELLIJ_CONFIG_FILE=/path/to/config.kdl</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动时不加载配置</span></span><br><span class="line">zellij options --clean</span><br></pre></td></tr></tbody></table></figure><h3 id="配置热更新"><a href="#配置热更新" class="headerlink" title="配置热更新"></a>配置热更新</h3><p>Zellij 会监听配置文件变化，大部分设置立即生效，无需重启。</p><hr><h2 id="基本使用技巧"><a href="#基本使用技巧" class="headerlink" title="基本使用技巧"></a>基本使用技巧</h2><h3 id="首次启动"><a href="#首次启动" class="headerlink" title="首次启动"></a>首次启动</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 直接启动</span></span><br><span class="line">zellij</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动并附加到已有会话</span></span><br><span class="line">zellij attach</span><br><span class="line"></span><br><span class="line"><span class="comment"># 启动欢迎界面（会话选择器）</span></span><br><span class="line">zellij -l welcome</span><br></pre></td></tr></tbody></table></figure><h3 id="快捷键基础"><a href="#快捷键基础" class="headerlink" title="快捷键基础"></a>快捷键基础</h3><p>Zellij 使用 <strong>Lock Mode</strong> 设计（类似 Vim 模式）：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">默认状态: 直接输入命令（无拦截）</span><br><span class="line">Ctrl+o:   进入操作模式（所有快捷键生效）</span><br><span class="line">Esc:      退出操作模式</span><br></pre></td></tr></tbody></table></figure><p><strong>常用操作</strong>（在操作模式下，即先按 Ctrl+o）：</p><table><thead><tr><th>快捷键</th><th>动作</th></tr></thead><tbody><tr><td><code>n</code></td><td>新建窗格（右）</td></tr><tr><td><code>d</code></td><td>新建窗格（下）</td></tr><tr><td><code>f</code></td><td>切换浮动窗格</td></tr><tr><td><code>x</code></td><td>关闭当前窗格</td></tr><tr><td><code>q</code></td><td>退出 Zellij</td></tr><tr><td><code>h/j/k/l</code></td><td>切换窗格（左/下/上/右）</td></tr><tr><td><code>+</code> / <code>-</code></td><td>调整窗格大小</td></tr><tr><td><code>t</code></td><td>新建标签页</td></tr><tr><td><code>w</code></td><td>打开会话管理器</td></tr><tr><td><code>s</code></td><td>进入选择模式</td></tr></tbody></table><h3 id="分屏操作"><a href="#分屏操作" class="headerlink" title="分屏操作"></a>分屏操作</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Ctrl+o 然后按:</span></span><br><span class="line">n      <span class="comment"># 右侧分屏</span></span><br><span class="line">d      <span class="comment"># 下方分屏</span></span><br><span class="line">+/-    <span class="comment"># 调整大小</span></span><br><span class="line">hjkl   <span class="comment"># 切换窗格</span></span><br></pre></td></tr></tbody></table></figure><h3 id="标签页管理"><a href="#标签页管理" class="headerlink" title="标签页管理"></a>标签页管理</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Ctrl+o 然后按:</span></span><br><span class="line">t      <span class="comment"># 新建标签页</span></span><br><span class="line">w      <span class="comment"># 会话管理器（可切换标签）</span></span><br><span class="line">1-9    <span class="comment"># 快速切换到标签页 1-9</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="布局与自动化"><a href="#布局与自动化" class="headerlink" title="布局与自动化"></a>布局与自动化</h2><h3 id="布局文件"><a href="#布局文件" class="headerlink" title="布局文件"></a>布局文件</h3><p>布局是预定义的窗格/标签/命令/插件组合，用 KDL 文件描述：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">// ~/.config/zellij/layouts/dev.kdl</span><br><span class="line"></span><br><span class="line">layout {</span><br><span class="line">    tab name="editor" {</span><br><span class="line">        pane size=1 borderless=true {</span><br><span class="line">            plugin location="zellij:tab-bar"</span><br><span class="line">        }</span><br><span class="line">        pane split_direction="vertical" {</span><br><span class="line">            pane size="70%" command="nvim"</span><br><span class="line">            pane size="30%" split_direction="horizontal" {</span><br><span class="line">                pane command="git" { args "status" }</span><br><span class="line">                pane</span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">        pane size=2 borderless=true {</span><br><span class="line">            plugin location="zellij:status-bar"</span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="启动布局"><a href="#启动布局" class="headerlink" title="启动布局"></a>启动布局</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 使用布局文件</span></span><br><span class="line">zellij --layout dev</span><br><span class="line"></span><br><span class="line"><span class="comment"># 或在配置中设置默认布局</span></span><br><span class="line">default_layout <span class="string">"dev"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="命令窗格布局"><a href="#命令窗格布局" class="headerlink" title="命令窗格布局"></a>命令窗格布局</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">// 布局中预定义命令</span><br><span class="line">pane {</span><br><span class="line">    name "tests"</span><br><span class="line">    command "make"</span><br><span class="line">    args "test"</span><br><span class="line">    start_suspended true  # 启动时暂停，按需触发</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">pane {</span><br><span class="line">    name "build"</span><br><span class="line">    command "cargo"</span><br><span class="line">    args "build"</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="窗格模板"><a href="#窗格模板" class="headerlink" title="窗格模板"></a>窗格模板</h3><p>避免重复定义：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">// 定义模板</span><br><span class="line">pane_template name="monitor-pane" {</span><br><span class="line">    size "20%"</span><br><span class="line">    borderless true</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// 使用模板</span><br><span class="line">pane name="logs" use="monitor-pane" {</span><br><span class="line">    command "tail"</span><br><span class="line">    args "-f" "logs/app.log"</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="会话管理"><a href="#会话管理" class="headerlink" title="会话管理"></a>会话管理</h2><h3 id="会话管理器"><a href="#会话管理器" class="headerlink" title="会话管理器"></a>会话管理器</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Ctrl+o + w 打开会话管理器</span></span><br><span class="line"><span class="comment"># 功能:</span></span><br><span class="line"><span class="comment"># - 快速切换运行中的会话</span></span><br><span class="line"><span class="comment"># - 创建命名会话</span></span><br><span class="line"><span class="comment"># - 管理后台会话</span></span><br><span class="line"><span class="comment"># - 切换时保留上下文</span></span><br></pre></td></tr></tbody></table></figure><h3 id="会话操作"><a href="#会话操作" class="headerlink" title="会话操作"></a>会话操作</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建命名会话</span></span><br><span class="line">zellij -s my-project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 附加到会话</span></span><br><span class="line">zellij attach my-project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 附加或创建</span></span><br><span class="line">zellij attach -c new-session</span><br><span class="line"></span><br><span class="line"><span class="comment"># 列出所有会话</span></span><br><span class="line">zellij list-sessions</span><br><span class="line"></span><br><span class="line"><span class="comment"># 杀死会话</span></span><br><span class="line">zellij kill-session my-project</span><br><span class="line"></span><br><span class="line"><span class="comment"># 杀死所有会话</span></span><br><span class="line">zellij kill-all-sessions</span><br></pre></td></tr></tbody></table></figure><h3 id="会话复活"><a href="#会话复活" class="headerlink" title="会话复活"></a>会话复活</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 启动欢迎界面选择已退出的会话</span></span><br><span class="line">zellij -l welcome</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可以恢复:</span></span><br><span class="line"><span class="comment"># - 窗格结构</span></span><br><span class="line"><span class="comment"># - 运行的命令</span></span><br><span class="line"><span class="comment"># - 工作目录</span></span><br><span class="line"><span class="comment"># - 窗格内容（可配置）</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="高级功能详解"><a href="#高级功能详解" class="headerlink" title="高级功能详解"></a>高级功能详解</h2><h3 id="Web-客户端"><a href="#Web-客户端" class="headerlink" title="Web 客户端"></a>Web 客户端</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 启动 Web 服务</span></span><br><span class="line">zellij options --web-server <span class="literal">true</span> --web-server-port 8082</span><br><span class="line"></span><br><span class="line"><span class="comment"># 浏览器访问</span></span><br><span class="line">http://localhost:8082/my-session</span><br><span class="line"></span><br><span class="line"><span class="comment"># 特性:</span></span><br><span class="line"><span class="comment"># - 不需要终端模拟器</span></span><br><span class="line"><span class="comment"># - 内置认证</span></span><br><span class="line"><span class="comment"># - 持久会话 URL</span></span><br><span class="line"><span class="comment"># - 远程共享会话</span></span><br></pre></td></tr></tbody></table></figure><h3 id="远程会话访问"><a href="#远程会话访问" class="headerlink" title="远程会话访问"></a>远程会话访问</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 从另一台机器附加到远程会话</span></span><br><span class="line">zellij attach https://my-server:8082/my-session</span><br><span class="line"></span><br><span class="line"><span class="comment"># 只读共享</span></span><br><span class="line">zellij options --read-only-user-permissions <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><h3 id="插件系统"><a href="#插件系统" class="headerlink" title="插件系统"></a>插件系统</h3><p>Zellij 界面本身就是插件组成：</p><ul><li><strong>Tab Bar</strong>: 标签栏</li><li><strong>Status Bar</strong>: 状态栏</li><li><strong>Session Manager</strong>: 会话管理界面</li><li><strong>Welcome Screen</strong>: 启动选择器</li><li><strong>Filepicker</strong>: 文件选择器（Strider）</li></ul><p><strong>开发插件</strong>：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Rust 插件开发（首选）</span></span><br><span class="line">// 使用 zellij-plugin crate</span><br><span class="line">use zellij_tile::prelude::*;</span><br><span class="line"></span><br><span class="line">// 输出到 pane</span><br><span class="line"><span class="built_in">print</span>!(<span class="string">"Hello from plugin!"</span>);</span><br><span class="line"></span><br><span class="line">// 注册事件监听</span><br><span class="line">subscribe_to_events(&amp;[</span><br><span class="line">    EventType::KeyPress,</span><br><span class="line">    EventType::Mouse,</span><br><span class="line">]);</span><br><span class="line"></span><br><span class="line">// WebAssembly 单文件分发</span><br><span class="line">cargo build --target wasm32-wasi --release</span><br></pre></td></tr></tbody></table></figure><h3 id="多窗格批量操作"><a href="#多窗格批量操作" class="headerlink" title="多窗格批量操作"></a>多窗格批量操作</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Alt + 左键选择多个窗格（拖拽选择）</span></span><br><span class="line"><span class="comment"># 批量操作:</span></span><br><span class="line"><span class="comment"># - 关闭多个窗格</span></span><br><span class="line"><span class="comment"># - 移动到新标签页</span></span><br><span class="line"><span class="comment"># - 堆叠在一起</span></span><br><span class="line"><span class="comment"># - 切换焦点</span></span><br></pre></td></tr></tbody></table></figure><h3 id="编辑-Scrollback"><a href="#编辑-Scrollback" class="headerlink" title="编辑 Scrollback"></a>编辑 Scrollback</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Ctrl+s + e 编辑当前窗格的输出历史</span></span><br><span class="line"><span class="comment"># 用 $EDITOR (vim/nvim/emacs) 打开</span></span><br><span class="line"><span class="comment"># 适合:</span></span><br><span class="line"><span class="comment"># - 复制长输出</span></span><br><span class="line"><span class="comment"># - 搜索历史记录</span></span><br><span class="line"><span class="comment"># - 保存输出到文件</span></span><br></pre></td></tr></tbody></table></figure><h3 id="CLI-脚本化"><a href="#CLI-脚本化" class="headerlink" title="CLI 脚本化"></a>CLI 脚本化</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 条件阻塞（脚本友好）</span></span><br><span class="line">zellij action new-pane \</span><br><span class="line">    --block-until-exit-success \</span><br><span class="line">    --name <span class="string">"tests"</span> \</span><br><span class="line">    -- make <span class="built_in">test</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 实时输出流</span></span><br><span class="line">zellij subscribe --pane-id 123</span><br><span class="line"></span><br><span class="line"><span class="comment"># 状态查询</span></span><br><span class="line">zellij list-panes --json</span><br><span class="line">zellij list-tabs --json</span><br><span class="line">zellij current-tab-info --json</span><br><span class="line"></span><br><span class="line"><span class="comment"># 后台会话</span></span><br><span class="line">zellij attach --create-background my-session</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="与-tmux-对比"><a href="#与-tmux-对比" class="headerlink" title="与 tmux 对比"></a>与 tmux 对比</h2><table><thead><tr><th>维度</th><th>tmux</th><th>Zellij</th></tr></thead><tbody><tr><td><strong>开箱即用</strong></td><td>❌ 需配置</td><td>✅ 默认好用</td></tr><tr><td><strong>学习曲线</strong></td><td>陡峭</td><td>平缓（模式切换更直观）</td></tr><tr><td><strong>UI 风格</strong></td><td>传统终端风格</td><td>现代 UI（浮动/堆叠）</td></tr><tr><td><strong>配置格式</strong></td><td><code>.tmux.conf</code></td><td>KDL（结构更清晰）</td></tr><tr><td><strong>插件扩展</strong></td><td>有限（脚本）</td><td>WebAssembly（全语言）</td></tr><tr><td><strong>协作功能</strong></td><td>基础共享</td><td>Web 客户端 + 实时协作</td></tr><tr><td><strong>会话复活</strong></td><td>❌</td><td>✅ 完整恢复</td></tr><tr><td><strong>快捷键冲突</strong></td><td>常见（需要改键）</td><td>模式切换（默认不冲突）</td></tr><tr><td><strong>性能</strong></td><td>极快</td><td>快（Rust）</td></tr><tr><td><strong>社区生态</strong></td><td>成熟</td><td>发展中</td></tr></tbody></table><p><strong>迁移建议</strong>：</p><ul><li>新手：直接用 Zellij</li><li>tmux 老用户：可以共存，逐步迁移功能</li><li>团队协作：Zellij 的 Web 客户端更方便</li></ul><hr><h2 id="实用配置示例"><a href="#实用配置示例" class="headerlink" title="实用配置示例"></a>实用配置示例</h2><h3 id="开发环境布局"><a href="#开发环境布局" class="headerlink" title="开发环境布局"></a>开发环境布局</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">// ~/.config/zellij/layouts/dev.kdl</span><br><span class="line">layout {</span><br><span class="line">    tab name="main" {</span><br><span class="line">        pane split_direction="vertical" {</span><br><span class="line">            pane size="70%" edit="src/main.rs"</span><br><span class="line">            pane size="30%" split_direction="horizontal" {</span><br><span class="line">                pane name="git" command="git" { args "status" "-sb" }</span><br><span class="line">                pane name="tests" command="cargo" { args "test" "--watch" }</span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">    tab name="logs" {</span><br><span class="line">        pane command="tail" { args "-f" "logs/*.log" }</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="Vim-风格快捷键"><a href="#Vim-风格快捷键" class="headerlink" title="Vim 风格快捷键"></a>Vim 风格快捷键</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">// ~/.config/zellij/config.kdl</span><br><span class="line">keybinds {</span><br><span class="line">    normal {</span><br><span class="line">        // 解绑默认的 hjkl，避免与 Vim 冲突</span><br><span class="line">        unbind "Ctrl+h" "Ctrl+j" "Ctrl+k" "Ctrl+l"</span><br><span class="line">    }</span><br><span class="line">    locked {</span><br><span class="line">        // Leader 风格（类似 tmux prefix）</span><br><span class="line">        bind "Ctrl+a" {</span><br><span class="line">            bind "n" { NewPane Right; }</span><br><span class="line">            bind "d" { NewPane Down; }</span><br><span class="line">            bind "x" { CloseFocus; }</span><br><span class="line">            bind "h" { MoveFocus Left; }</span><br><span class="line">            bind "j" { MoveFocus Down; }</span><br><span class="line">            bind "k" { MoveFocus Up; }</span><br><span class="line">            bind "l" { MoveFocus Right; }</span><br><span class="line">        }</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="CI-管道布局"><a href="#CI-管道布局" class="headerlink" title="CI 管道布局"></a>CI 管道布局</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line">// ci-layout.kdl</span><br><span class="line">layout {</span><br><span class="line">    pane {</span><br><span class="line">        name "tests"</span><br><span class="line">        command "make"</span><br><span class="line">        args "test"</span><br><span class="line">        start_suspended true</span><br><span class="line">    }</span><br><span class="line">    pane {</span><br><span class="line">        name "build"</span><br><span class="line">        command "make"</span><br><span class="line">        args "build"</span><br><span class="line">        start_suspended true</span><br><span class="line">    }</span><br><span class="line">    pane {</span><br><span class="line">        name "deploy"</span><br><span class="line">        command "./deploy.sh"</span><br><span class="line">        start_suspended true</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// 脚本触发</span><br><span class="line">// zellij attach ci-session</span><br><span class="line">// 然后手动按 Enter 依次运行</span><br></pre></td></tr></tbody></table></figure><h3 id="远程开发配置"><a href="#远程开发配置" class="headerlink" title="远程开发配置"></a>远程开发配置</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">// 远程服务器配置</span><br><span class="line">// ~/.config/zellij/config.kdl</span><br><span class="line">session_serialization true</span><br><span class="line">pane_viewport_serialization true</span><br><span class="line">scrollback_lines_to_serialize 10000</span><br><span class="line"></span><br><span class="line">// Web 服务</span><br><span class="line">web_server true</span><br><span class="line">web_server_port 8082</span><br><span class="line">web_server_ssl true</span><br><span class="line">web_server_ssl_certificate "/path/to/cert.pem"</span><br><span class="line">web_server_ssl_key "/path/to/key.pem"</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h2><h3 id="Q-快捷键和-Vim-x2F-Nvim-冲突？"><a href="#Q-快捷键和-Vim-x2F-Nvim-冲突？" class="headerlink" title="Q: 快捷键和 Vim/Nvim 冲突？"></a>Q: 快捷键和 Vim/Nvim 冲突？</h3><p><strong>A</strong>: 使用 Lock Mode（先按 Ctrl+o），默认不拦截任何键。或者配置 Leader 风格：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 类似 tmux 的 prefix key</span><br><span class="line">bind "Ctrl+a" {</span><br><span class="line">    bind "n" { NewPane; }</span><br><span class="line">    // ...</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-如何退出-Zellij？"><a href="#Q-如何退出-Zellij？" class="headerlink" title="Q: 如何退出 Zellij？"></a>Q: 如何退出 Zellij？</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Ctrl+o 然后按:</span></span><br><span class="line">q      <span class="comment"># 退出当前会话（会话保存）</span></span><br><span class="line">Q      <span class="comment"># 退出并杀死会话</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 或直接</span></span><br><span class="line">zellij kill-session my-session</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-如何在启动时自动运行命令？"><a href="#Q-如何在启动时自动运行命令？" class="headerlink" title="Q: 如何在启动时自动运行命令？"></a>Q: 如何在启动时自动运行命令？</h3><p><strong>A</strong>: 使用布局文件定义 <code>command</code> 和 <code>args</code>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">pane {</span><br><span class="line">    command "nvim"</span><br><span class="line">    args "README.md"</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-如何查看所有可用快捷键？"><a href="#Q-如何查看所有可用快捷键？" class="headerlink" title="Q: 如何查看所有可用快捷键？"></a>Q: 如何查看所有可用快捷键？</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 在 Zellij 内按 Ctrl+o 然后 ?</span></span><br><span class="line"><span class="comment"># 会显示快捷键帮助面板</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Q-配置文件格式报错？"><a href="#Q-配置文件格式报错？" class="headerlink" title="Q: 配置文件格式报错？"></a>Q: 配置文件格式报错？</h3><p><strong>A</strong>: KDL 格式检查：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 验证配置</span></span><br><span class="line">zellij setup --check</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看解析错误</span></span><br><span class="line">zellij options --config ~/.config/zellij/config.kdl</span><br></pre></td></tr></tbody></table></figure><h3 id="Q-如何自定义主题？"><a href="#Q-如何自定义主题？" class="headerlink" title="Q: 如何自定义主题？"></a>Q: 如何自定义主题？</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">// ~/.config/zellij/themes/my-theme.kdl</span><br><span class="line">themes {</span><br><span class="line">    my-theme {</span><br><span class="line">        fg "#cdd6f4"</span><br><span class="line">        bg "#1e1e2e"</span><br><span class="line">        black "#45475a"</span><br><span class="line">        red "#f38ba8"</span><br><span class="line">        green "#a6e3a1"</span><br><span class="line">        yellow "#f9e2af"</span><br><span class="line">        blue "#89b4fa"</span><br><span class="line">        magenta "#f5c2e7"</span><br><span class="line">        cyan "#94e2d5"</span><br><span class="line">        white "#a6adc8"</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">// config.kdl 中引用</span><br><span class="line">theme "my-theme"</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Zellij 是 tmux 的现代替代品，核心优势：</p><table><thead><tr><th>优势</th><th>说明</th></tr></thead><tbody><tr><td><strong>零配置上手</strong></td><td>不写配置文件也能高效工作</td></tr><tr><td><strong>现代 UI</strong></td><td>浮动窗格、堆叠窗格、可视化界面</td></tr><tr><td><strong>会话持久</strong></td><td>复活功能让工作状态可恢复</td></tr><tr><td><strong>协作友好</strong></td><td>Web 客户端、远程访问、多人实时</td></tr><tr><td><strong>可扩展</strong></td><td>WebAssembly 插件，全语言支持</td></tr></tbody></table><p><strong>推荐场景</strong>：</p><ol><li><strong>日常开发</strong>：替代 tmux，更快上手</li><li><strong>远程协作</strong>：Web 客户端共享会话</li><li><strong>自动化布局</strong>：开发环境一键启动</li><li><strong>CI/CD 集成</strong>：脚本化终端流程</li></ol><hr><h2 id="延伸阅读"><a href="#延伸阅读" class="headerlink" title="延伸阅读"></a>延伸阅读</h2><ul><li><a href="https://zellij.dev/documentation/">Zellij 官方文档</a></li><li><a href="https://zellij.dev/tutorials/layouts">布局系统教程</a></li><li><a href="https://zellij.dev/tutorials/developing-a-rust-plugin">插件开发指南</a></li><li><a href="https://zellij.dev/tutorials/session-management">会话管理教程</a></li><li><a href="https://github.com/zellij-org/zellij">GitHub 仓库</a></li><li><a href="https://discord.gg/CrUAFH3">Discord 社区</a></li></ul><hr><blockquote><p>💡 <strong>提示</strong>: 如果你是 tmux 用户，可以把 Zellij 作为补充工具。先从 Web 客户端和布局自动化尝试，逐步迁移核心工作流。不喜欢？随时退回 tmux，两者可以共存。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/zellij-guide/</id>
    <link href="https://imwnk.cn/archives/zellij-guide/"/>
    <published>2026-03-28T07:00:00.000Z</published>
    <summary>Zellij 终端复用器的完整使用指南，涵盖核心特性、安装配置、布局自动化、会话管理、插件开发等高级功能</summary>
    <title>Zellij - 现代终端复用器完全指南</title>
    <updated>2026-03-28T09:51:41.711Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="cli" scheme="https://imwnk.cn/tags/cli/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="productivity" scheme="https://imwnk.cn/tags/productivity/"/>
    <category term="devtools" scheme="https://imwnk.cn/tags/devtools/"/>
    <content>
      <![CDATA[<blockquote><p><strong>工欲善其事，必先利其器。</strong> 选择正确的搜索工具，让代码探索效率翻倍。</p></blockquote><p>在开发工作中，代码搜索是最频繁的操作之一。无论是查找函数定义、追踪调用链，还是排查错误日志，一款高效的搜索工具能极大提升开发效率。本文将深入对比三款主流搜索工具：<strong>grep</strong>、<strong>ripgrep (rg)</strong> 和 **ast-grep (sg)**。</p><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E5%B7%A5%E5%85%B7%E6%A6%82%E8%A7%88">工具概览</a></li><li><a href="#grep%E7%BB%8F%E5%85%B8%E6%B0%B8%E6%81%92%E7%9A%84%E6%90%9C%E7%B4%A2%E9%BC%BB%E7%A5%96">Grep：经典永恒的搜索鼻祖</a></li><li><a href="#ripgrep%E9%80%9F%E5%BA%A6%E4%B8%8E%E6%99%BA%E8%83%BD%E7%9A%84%E7%8E%B0%E4%BB%A3%E7%8E%8B%E8%80%85">Ripgrep：速度与智能的现代王者</a></li><li><a href="#ast-grep%E8%AF%AD%E6%B3%95%E6%84%9F%E7%9F%A5%E7%9A%84%E7%BB%93%E6%9E%84%E5%8C%96%E6%90%9C%E7%B4%A2">AST-Grep：语法感知的结构化搜索</a></li><li><a href="#%E6%80%A7%E8%83%BD%E5%9F%BA%E5%87%86%E6%B5%8B%E8%AF%95">性能基准测试</a></li><li><a href="#%E5%8A%9F%E8%83%BD%E5%AF%B9%E6%AF%94%E7%9F%A9%E9%98%B5">功能对比矩阵</a></li><li><a href="#%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF%E6%8C%87%E5%8D%97">使用场景指南</a></li><li><a href="#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5%E4%B8%8E%E6%8A%80%E5%B7%A7">最佳实践与技巧</a></li><li><a href="#%E5%A6%82%E4%BD%95%E9%80%89%E6%8B%A9">如何选择</a></li></ol><hr><h2 id="工具概览"><a href="#工具概览" class="headerlink" title="工具概览"></a>工具概览</h2><table><thead><tr><th>工具</th><th>定位</th><th>核心优势</th><th>适用场景</th></tr></thead><tbody><tr><td><strong>grep</strong></td><td>文本搜索鼻祖</td><td>通用性、跨平台、预装</td><td>简单文本搜索、服务器环境</td></tr><tr><td><strong>ripgrep (rg)</strong></td><td>现代搜索工具</td><td>极致速度、智能过滤、Unicode</td><td>代码库搜索、日常开发</td></tr><tr><td><strong>ast-grep (sg)</strong></td><td>结构化搜索</td><td>AST 感知、语法匹配、代码重构</td><td>代码重构、模式匹配、代码审查</td></tr></tbody></table><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">搜索精度层级：</span><br><span class="line"></span><br><span class="line">grep        → 文本级（字符匹配）</span><br><span class="line">ripgrep     → 文本级 + 智能过滤（优化字符匹配）</span><br><span class="line">ast-grep    → 语法级（AST 结构匹配）</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="Grep：经典永恒的搜索鼻祖"><a href="#Grep：经典永恒的搜索鼻祖" class="headerlink" title="Grep：经典永恒的搜索鼻祖"></a>Grep：经典永恒的搜索鼻祖</h2><h3 id="历史与地位"><a href="#历史与地位" class="headerlink" title="历史与地位"></a>历史与地位</h3><p><strong>grep</strong> (Global Regular Expression Print) 诞生于 1973 年的 Unix 时代，是 Ken Thompson 用一晚上的时间写出来的传奇工具。近 50 年来，它一直是 Unix/Linux 系统的标准组件。</p><h3 id="核心特性"><a href="#核心特性" class="headerlink" title="核心特性"></a>核心特性</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本语法</span></span><br><span class="line">grep [options] pattern [files]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 常用选项</span></span><br><span class="line">-i, --ignore-case      <span class="comment"># 忽略大小写</span></span><br><span class="line">-v, --invert-match     <span class="comment"># 反向匹配</span></span><br><span class="line">-r, --recursive        <span class="comment"># 递归搜索目录</span></span><br><span class="line">-n, --line-number      <span class="comment"># 显示行号</span></span><br><span class="line">-l, --files-with-matches  <span class="comment"># 只显示文件名</span></span><br><span class="line">-c, --count            <span class="comment"># 统计匹配行数</span></span><br><span class="line">-E, --extended-regexp  <span class="comment"># 扩展正则表达式</span></span><br><span class="line">-F, --fixed-strings    <span class="comment"># 固定字符串（不解释正则）</span></span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例"><a href="#实用示例" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查找包含 "error" 的文件</span></span><br><span class="line">grep -r <span class="string">"error"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有 TODO 注释</span></span><br><span class="line">grep -rn <span class="string">"TODO"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 统计每个文件的匹配行数</span></span><br><span class="line">grep -rc <span class="string">"function"</span> ./src/ | <span class="built_in">sort</span> -t: -k2 -nr</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找不以 # 开头的行（排除注释）</span></span><br><span class="line">grep -v <span class="string">"^#"</span> ./config.conf</span><br><span class="line"></span><br><span class="line"><span class="comment"># 使用扩展正则匹配邮箱</span></span><br><span class="line">grep -E <span class="string">"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"</span> ./data.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 多文件搜索，显示文件名</span></span><br><span class="line">grep -l <span class="string">"import React"</span> ./src/*.tsx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 上下文搜索（显示匹配前后 2 行）</span></span><br><span class="line">grep -C 2 <span class="string">"def main"</span> ./app.py</span><br></pre></td></tr></tbody></table></figure><h3 id="优势"><a href="#优势" class="headerlink" title="优势"></a>优势</h3><ul><li>✅ <strong>预装优势</strong>：几乎所有 Unix/Linux 系统自带</li><li>✅ <strong>通用性强</strong>：搜索任何文本，不限于代码</li><li>✅ <strong>稳定可靠</strong>：50 年历史，极其稳定</li><li>✅ <strong>丰富文档</strong>：海量的教程和社区资源</li><li>✅ <strong>管道友好</strong>：与其他 Unix 命令完美配合</li></ul><h3 id="局限"><a href="#局限" class="headerlink" title="局限"></a>局限</h3><ul><li>❌ <strong>速度较慢</strong>：大文件/大目录性能不佳</li><li>❌ <strong>无智能过滤</strong>：会搜索 .git、node_modules 等</li><li>❌ <strong>输出格式简单</strong>：不支持高亮、上下文理解</li><li>❌ <strong>Unicode 支持弱</strong>：多字节字符处理不完善</li></ul><hr><h2 id="Ripgrep：速度与智能的现代王者"><a href="#Ripgrep：速度与智能的现代王者" class="headerlink" title="Ripgrep：速度与智能的现代王者"></a>Ripgrep：速度与智能的现代王者</h2><h3 id="诞生背景"><a href="#诞生背景" class="headerlink" title="诞生背景"></a>诞生背景</h3><p><strong>ripgrep (rg)</strong> 由 BurntSushi (Andrew Gallant) 开发，使用 Rust 编写。它被设计为 grep 的现代替代品，在保持兼容性的同时大幅提升性能和用户体验。</p><h3 id="核心特性-1"><a href="#核心特性-1" class="headerlink" title="核心特性"></a>核心特性</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本语法</span></span><br><span class="line">rg [options] pattern [path]</span><br><span class="line"></span><br><span class="line"><span class="comment"># 特色选项</span></span><br><span class="line">--smart-case          <span class="comment"># 智能大小写（全小写时忽略大小写）</span></span><br><span class="line">--hidden              <span class="comment"># 搜索隐藏文件</span></span><br><span class="line">--no-ignore           <span class="comment"># 忽略 .gitignore 规则</span></span><br><span class="line">--<span class="built_in">type</span> &lt;<span class="built_in">type</span>&gt;         <span class="comment"># 按文件类型搜索（js, py, rust...）</span></span><br><span class="line">--type-list           <span class="comment"># 列出所有支持的文件类型</span></span><br><span class="line">-C, --context &lt;num&gt;   <span class="comment"># 显示上下文行</span></span><br><span class="line">-A, --after &lt;num&gt;     <span class="comment"># 显示匹配后 N 行</span></span><br><span class="line">-B, --before &lt;num&gt;    <span class="comment"># 显示匹配前 N 行</span></span><br><span class="line">--json                <span class="comment"># JSON 格式输出</span></span><br><span class="line">--replace &lt;text&gt;      <span class="comment"># 替换匹配内容（预览）</span></span><br></pre></td></tr></tbody></table></figure><h3 id="速度的秘密"><a href="#速度的秘密" class="headerlink" title="速度的秘密"></a>速度的秘密</h3><p>ripgrep 的速度优势来自多个方面的优化：</p><table><thead><tr><th>优化策略</th><th>说明</th></tr></thead><tbody><tr><td><strong>多线程</strong></td><td>利用所有 CPU 核心并行搜索</td></tr><tr><td><strong>内存映射</strong></td><td>大文件使用 mmap 读取</td></tr><tr><td><strong>智能过滤</strong></td><td>自动跳过 .git、node_modules、target 等</td></tr><tr><td><strong>SIMD 加速</strong></td><td>使用 AVX/SSE 指令集加速匹配</td></tr><tr><td><strong>PCRE2 引擎</strong></td><td>更快的正则引擎实现</td></tr></tbody></table><h3 id="实用示例-1"><a href="#实用示例-1" class="headerlink" title="实用示例"></a>实用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 智能搜索（自动忽略 git 忽略的文件）</span></span><br><span class="line">rg <span class="string">"function"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 按文件类型搜索</span></span><br><span class="line">rg <span class="string">"useState"</span> --<span class="built_in">type</span> js</span><br><span class="line">rg <span class="string">"import"</span> --<span class="built_in">type</span> python</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看支持的文件类型</span></span><br><span class="line">rg --type-list</span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索隐藏文件</span></span><br><span class="line">rg --hidden <span class="string">"config"</span> ./</span><br><span class="line"></span><br><span class="line"><span class="comment"># 忽略 .gitignore，搜索所有文件</span></span><br><span class="line">rg --no-ignore <span class="string">"password"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示匹配上下文</span></span><br><span class="line">rg -C 3 <span class="string">"def main"</span> ./app.py</span><br><span class="line"></span><br><span class="line"><span class="comment"># 只显示文件名</span></span><br><span class="line">rg -l <span class="string">"TODO"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 统计匹配数</span></span><br><span class="line">rg -c <span class="string">"error"</span> ./logs/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 替换预览（不修改文件）</span></span><br><span class="line">rg <span class="string">"oldName"</span> -r <span class="string">"newName"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># JSON 输出（便于脚本处理）</span></span><br><span class="line">rg --json <span class="string">"pattern"</span> ./src/ | jq <span class="string">'.matches[].line.text'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 正则搜索</span></span><br><span class="line">rg -E <span class="string">"fn\s+\w+\s*\("</span> --<span class="built_in">type</span> rust</span><br><span class="line"></span><br><span class="line"><span class="comment"># 搜索特定文件名模式</span></span><br><span class="line">rg <span class="string">"pattern"</span> -g <span class="string">"*.tsx"</span> -g <span class="string">"!*.test.tsx"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 统计每种文件类型的匹配数</span></span><br><span class="line">rg --stats <span class="string">"import"</span> ./src/</span><br></pre></td></tr></tbody></table></figure><h3 id="智能过滤示例"><a href="#智能过滤示例" class="headerlink" title="智能过滤示例"></a>智能过滤示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 自动忽略的目录（默认）</span></span><br><span class="line">.git/</span><br><span class="line">node_modules/</span><br><span class="line">target/</span><br><span class="line">__pycache__/</span><br><span class="line">.<span class="built_in">env</span>/</span><br><span class="line">*.min.js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 自动识别的二进制文件</span></span><br><span class="line">*.png, *.jpg, *.gif</span><br><span class="line">*.pdf, *.zip</span><br><span class="line">*.exe, *.dll</span><br></pre></td></tr></tbody></table></figure><h3 id="优势-1"><a href="#优势-1" class="headerlink" title="优势"></a>优势</h3><ul><li>✅ <strong>极致速度</strong>：比 grep 快 10-100 倍</li><li>✅ <strong>智能过滤</strong>：自动跳过无用文件</li><li>✅ <strong>开箱即用</strong>：无需配置即可高效工作</li><li>✅ <strong>Unicode 完美支持</strong>：中文、日文、emoji 无障碍</li><li>✅ <strong>丰富输出</strong>：彩色高亮、多格式支持</li><li>✅ <strong>类型感知</strong>：按文件类型自动过滤</li></ul><h3 id="局限-1"><a href="#局限-1" class="headerlink" title="局限"></a>局限</h3><ul><li>❌ <strong>需要安装</strong>：不像 grep 预装</li><li>❌ <strong>正则语法差异</strong>：与 grep 的 PCRE 有细微差别</li><li>❌ <strong>仍是文本级匹配</strong>：不理解代码语法</li></ul><hr><h2 id="AST-Grep：语法感知的结构化搜索"><a href="#AST-Grep：语法感知的结构化搜索" class="headerlink" title="AST-Grep：语法感知的结构化搜索"></a>AST-Grep：语法感知的结构化搜索</h2><h3 id="核心理念"><a href="#核心理念" class="headerlink" title="核心理念"></a>核心理念</h3><p><strong>ast-grep (sg)</strong> 是一种革命性的代码搜索工具，它不匹配文本，而是匹配**抽象语法树 (AST)**。这意味着你可以用代码的模式来搜索代码，而不是用正则表达式。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">传统搜索：匹配字符 → "function foo"</span><br><span class="line">AST 搜索：匹配语法 → function $NAME($$$) { $$$ }</span><br></pre></td></tr></tbody></table></figure><h3 id="核心特性-2"><a href="#核心特性-2" class="headerlink" title="核心特性"></a>核心特性</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 基本语法</span></span><br><span class="line">sg -p <span class="string">'pattern'</span> -l language</span><br><span class="line"></span><br><span class="line"><span class="comment"># 核心选项</span></span><br><span class="line">-p, --pattern &lt;pattern&gt;   <span class="comment"># AST 模式</span></span><br><span class="line">-l, --lang &lt;language&gt;     <span class="comment"># 语言类型</span></span><br><span class="line">-r, --rewrite &lt;rewrite&gt;   <span class="comment"># 替换模式</span></span><br><span class="line">--json                    <span class="comment"># JSON 输出</span></span><br><span class="line">-C, --context &lt;num&gt;       <span class="comment"># 上下文行数</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 元变量语法</span></span><br><span class="line"><span class="variable">$VAR</span>      <span class="comment"># 单个 AST 节点（变量名、表达式等）</span></span><br><span class="line">$$$       <span class="comment"># 任意数量的 AST 节点（通配符）</span></span><br></pre></td></tr></tbody></table></figure><h3 id="支持的语言"><a href="#支持的语言" class="headerlink" title="支持的语言"></a>支持的语言</h3><table><thead><tr><th>语言</th><th>标识符</th></tr></thead><tbody><tr><td>JavaScript</td><td>js, javascript</td></tr><tr><td>TypeScript</td><td>ts, typescript</td></tr><tr><td>TSX</td><td>tsx</td></tr><tr><td>Python</td><td>py, python</td></tr><tr><td>Rust</td><td>rs, rust</td></tr><tr><td>Go</td><td>go, golang</td></tr><tr><td>Java</td><td>java</td></tr><tr><td>C/C++</td><td>c, cpp</td></tr><tr><td>Ruby</td><td>rb, ruby</td></tr><tr><td>Swift</td><td>swift</td></tr><tr><td>Kotlin</td><td>kt, kotlin</td></tr><tr><td>HTML/CSS</td><td>html, css</td></tr><tr><td>JSON/YAML</td><td>json, yaml</td></tr></tbody></table><h3 id="元变量详解"><a href="#元变量详解" class="headerlink" title="元变量详解"></a>元变量详解</h3><figure class="highlight javascript"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// $VAR - 匹配单个 AST 节点</span></span><br><span class="line"><span class="attr">pattern</span>: <span class="string">"const $VAR = $VALUE"</span></span><br><span class="line"><span class="comment">// 匹配: const name = "John"</span></span><br><span class="line"><span class="comment">// 匹配: const count = 42</span></span><br><span class="line"><span class="comment">// 匹配: const items = [1, 2, 3]</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// $$$ - 匹配任意数量的节点（类似正则的 .*）</span></span><br><span class="line"><span class="attr">pattern</span>: <span class="string">"function $NAME($$$) { $$$ }"</span></span><br><span class="line"><span class="comment">// 匹配: function foo() {}</span></span><br><span class="line"><span class="comment">// 匹配: function bar(a, b) { return a + b; }</span></span><br><span class="line"><span class="comment">// 匹配: function baz(x, y, z) { console.log(x); return y; }</span></span><br></pre></td></tr></tbody></table></figure><h3 id="实用示例-2"><a href="#实用示例-2" class="headerlink" title="实用示例"></a>实用示例</h3><h4 id="JavaScript-x2F-TypeScript"><a href="#JavaScript-x2F-TypeScript" class="headerlink" title="JavaScript/TypeScript"></a>JavaScript/TypeScript</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查找所有 console.log</span></span><br><span class="line">sg -p <span class="string">'console.log($A)'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有函数声明</span></span><br><span class="line">sg -p <span class="string">'function $NAME($$$) { $$$ }'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有 async 函数</span></span><br><span class="line">sg -p <span class="string">'async function $NAME($$$) { $$$ }'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有箭头函数</span></span><br><span class="line">sg -p <span class="string">'const $NAME = ($$$) =&gt; { $$$ }'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找特定的 React Hook 使用</span></span><br><span class="line">sg -p <span class="string">'useState($INIT)'</span> -l tsx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找 useEffect 清理函数</span></span><br><span class="line">sg -p <span class="string">'useEffect(() =&gt; { $$$ return $FUNC })'</span> -l tsx</span><br></pre></td></tr></tbody></table></figure><h4 id="批量替换"><a href="#批量替换" class="headerlink" title="批量替换"></a>批量替换</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 将 var 替换为 let</span></span><br><span class="line">sg -p <span class="string">'var $VAR = $VALUE'</span> -r <span class="string">'let $VAR = $VALUE'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># 将 console.log 替换为 logger.info</span></span><br><span class="line">sg -p <span class="string">'console.log($MSG)'</span> -r <span class="string">'logger.info($MSG)'</span> -l js</span><br><span class="line"></span><br><span class="line"><span class="comment"># React 类组件转函数组件（简化示例）</span></span><br><span class="line">sg -p <span class="string">'class $NAME extends React.Component { render() { return $JSX } }'</span> \</span><br><span class="line">   -r <span class="string">'function $NAME() { return $JSX }'</span> -l tsx</span><br></pre></td></tr></tbody></table></figure><h4 id="Python"><a href="#Python" class="headerlink" title="Python"></a>Python</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查找所有函数定义</span></span><br><span class="line">sg -p <span class="string">'def $NAME($$$): $$$'</span> -l py</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有装饰器</span></span><br><span class="line">sg -p <span class="string">'@$DECORATOR\ndef $NAME($$$): $$$'</span> -l py</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找 try-except 块</span></span><br><span class="line">sg -p <span class="string">'try: $$$ except $ERR: $$$'</span> -l py</span><br></pre></td></tr></tbody></table></figure><h4 id="Rust"><a href="#Rust" class="headerlink" title="Rust"></a>Rust</h4><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查找所有 unsafe 块</span></span><br><span class="line">sg -p <span class="string">'unsafe { $$$ }'</span> -l rs</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找所有 impl 块</span></span><br><span class="line">sg -p <span class="string">'impl $TYPE { $$$ }'</span> -l rs</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查找 Result 处理</span></span><br><span class="line">sg -p <span class="string">'match $EXPR { Ok($VAR) =&gt; $$$, Err($ERR) =&gt; $$$ }'</span> -l rs</span><br></pre></td></tr></tbody></table></figure><h3 id="配置化规则"><a href="#配置化规则" class="headerlink" title="配置化规则"></a>配置化规则</h3><figure class="highlight yaml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># sgconfig.yml</span></span><br><span class="line"><span class="attr">rules:</span></span><br><span class="line">  <span class="bullet">-</span> <span class="attr">id:</span> <span class="literal">no</span><span class="string">-console-log</span></span><br><span class="line">    <span class="attr">pattern:</span> <span class="string">console.log($MSG)</span></span><br><span class="line">    <span class="attr">language:</span> <span class="string">js</span></span><br><span class="line">    <span class="attr">severity:</span> <span class="string">warning</span></span><br><span class="line">    <span class="attr">message:</span> <span class="string">"Avoid using console.log in production"</span></span><br><span class="line">    </span><br><span class="line">  <span class="bullet">-</span> <span class="attr">id:</span> <span class="string">prefer-const</span></span><br><span class="line">    <span class="attr">pattern:</span> <span class="string">let</span> <span class="string">$VAR</span> <span class="string">=</span> <span class="string">$VALUE</span></span><br><span class="line">    <span class="attr">fix:</span> <span class="string">const</span> <span class="string">$VAR</span> <span class="string">=</span> <span class="string">$VALUE</span></span><br><span class="line">    <span class="attr">language:</span> <span class="string">js</span></span><br><span class="line">    <span class="attr">message:</span> <span class="string">"Use const for variables that are never reassigned"</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 运行规则检查</span></span><br><span class="line">sg scan --config sgconfig.yml ./src/</span><br></pre></td></tr></tbody></table></figure><h3 id="优势-2"><a href="#优势-2" class="headerlink" title="优势"></a>优势</h3><ul><li>✅ <strong>语法感知</strong>：理解代码结构，非纯文本匹配</li><li>✅ <strong>精确匹配</strong>：不会匹配字符串、注释中的内容</li><li>✅ <strong>重构友好</strong>：安全地进行大规模代码修改</li><li>✅ <strong>多语言支持</strong>：25+ 语言</li><li>✅ <strong>规则配置</strong>：可定义自定义 lint 规则</li></ul><h3 id="局限-2"><a href="#局限-2" class="headerlink" title="局限"></a>局限</h3><ul><li>❌ <strong>学习曲线</strong>：需要理解 AST 概念和元变量语法</li><li>❌ <strong>需要指定语言</strong>：不能像 grep 那样跨语言搜索</li><li>❌ <strong>速度相对较慢</strong>：需要解析 AST，比纯文本搜索慢</li><li>❌ <strong>不支持所有语言</strong>：新语言支持需要开发</li></ul><hr><h2 id="性能基准测试"><a href="#性能基准测试" class="headerlink" title="性能基准测试"></a>性能基准测试</h2><h3 id="测试环境"><a href="#测试环境" class="headerlink" title="测试环境"></a>测试环境</h3><ul><li><strong>硬件</strong>：MacBook Pro M3 Pro, 32GB RAM</li><li><strong>代码库</strong>：Linux Kernel 源码 (~70k 文件, ~800MB)</li><li><strong>搜索模式</strong>：<code>"struct file_operations"</code></li></ul><h3 id="测试结果"><a href="#测试结果" class="headerlink" title="测试结果"></a>测试结果</h3><table><thead><tr><th>工具</th><th>执行时间</th><th>相对速度</th></tr></thead><tbody><tr><td><strong>grep -r</strong></td><td>2.34s</td><td>1x (基准)</td></tr><tr><td><strong>grep -r –exclude-dir=.git</strong></td><td>2.12s</td><td>1.1x</td></tr><tr><td><strong>ripgrep</strong></td><td>0.18s</td><td><strong>13x</strong></td></tr><tr><td><strong>ast-grep</strong></td><td>1.56s</td><td>1.5x</td></tr></tbody></table><h3 id="大型代码库测试-Chromium-300k-文件"><a href="#大型代码库测试-Chromium-300k-文件" class="headerlink" title="大型代码库测试 (Chromium ~300k 文件)"></a>大型代码库测试 (Chromium ~300k 文件)</h3><table><thead><tr><th>工具</th><th>执行时间</th><th>内存占用</th></tr></thead><tbody><tr><td><strong>grep -r</strong></td><td>45.2s</td><td>~50MB</td></tr><tr><td><strong>ripgrep</strong></td><td>2.8s</td><td>~120MB</td></tr><tr><td><strong>ast-grep</strong></td><td>18.4s</td><td>~500MB</td></tr></tbody></table><h3 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">速度排序（文本搜索）：ripgrep &gt;&gt; grep &gt; ast-grep</span><br><span class="line"></span><br><span class="line">资源占用：ast-grep &gt; ripgrep &gt; grep</span><br><span class="line"></span><br><span class="line">精度排序：ast-grep &gt;&gt; ripgrep ≈ grep</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="功能对比矩阵"><a href="#功能对比矩阵" class="headerlink" title="功能对比矩阵"></a>功能对比矩阵</h2><h3 id="核心功能"><a href="#核心功能" class="headerlink" title="核心功能"></a>核心功能</h3><table><thead><tr><th>功能</th><th align="center">grep</th><th align="center">ripgrep</th><th align="center">ast-grep</th></tr></thead><tbody><tr><td>文本搜索</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>正则表达式</td><td align="center">✅</td><td align="center">✅</td><td align="center">❌ (使用模式)</td></tr><tr><td>AST 语法匹配</td><td align="center">❌</td><td align="center">❌</td><td align="center">✅</td></tr><tr><td>多线程并行</td><td align="center">❌</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>智能过滤</td><td align="center">❌</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>Unicode 支持</td><td align="center">⚠️ 部分</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>替换功能</td><td align="center">❌</td><td align="center">✅ 预览</td><td align="center">✅ 执行</td></tr><tr><td>彩色输出</td><td align="center">⚠️ 需配置</td><td align="center">✅</td><td align="center">✅</td></tr></tbody></table><h3 id="高级功能"><a href="#高级功能" class="headerlink" title="高级功能"></a>高级功能</h3><table><thead><tr><th>功能</th><th align="center">grep</th><th align="center">ripgrep</th><th align="center">ast-grep</th></tr></thead><tbody><tr><td>文件类型过滤</td><td align="center">⚠️ 手动</td><td align="center">✅ 内置</td><td align="center">✅ 必须</td></tr><tr><td>隐藏文件处理</td><td align="center">⚠️ 默认搜索</td><td align="center">✅ 智能跳过</td><td align="center">✅ 智能跳过</td></tr><tr><td>.gitignore 支持</td><td align="center">❌</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>JSON 输出</td><td align="center">❌</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>上下文显示</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>自定义规则</td><td align="center">❌</td><td align="center">❌</td><td align="center">✅ YAML</td></tr><tr><td>CI/CD 集成</td><td align="center">⚠️ 手动</td><td align="center">⚠️ 手动</td><td align="center">✅ scan</td></tr></tbody></table><h3 id="使用体验"><a href="#使用体验" class="headerlink" title="使用体验"></a>使用体验</h3><table><thead><tr><th>维度</th><th align="center">grep</th><th align="center">ripgrep</th><th align="center">ast-grep</th></tr></thead><tbody><tr><td>学习曲线</td><td align="center">低</td><td align="center">低</td><td align="center">中</td></tr><tr><td>开箱即用</td><td align="center">✅</td><td align="center">✅</td><td align="center">⚠️ 需指定语言</td></tr><tr><td>配置需求</td><td align="center">无</td><td align="center">无</td><td align="center">可选配置文件</td></tr><tr><td>输出可读性</td><td align="center">中</td><td align="center">高</td><td align="center">高</td></tr><tr><td>跨平台</td><td align="center">✅</td><td align="center">✅</td><td align="center">✅</td></tr><tr><td>安装便捷性</td><td align="center">✅ 预装</td><td align="center">⚠️ 需安装</td><td align="center">⚠️ 需安装</td></tr></tbody></table><hr><h2 id="使用场景指南"><a href="#使用场景指南" class="headerlink" title="使用场景指南"></a>使用场景指南</h2><h3 id="选择-grep-的场景"><a href="#选择-grep-的场景" class="headerlink" title="选择 grep 的场景"></a>选择 grep 的场景</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ✅ 服务器环境（无权限安装新工具）</span></span><br><span class="line">ssh user@server <span class="string">"grep -r 'error' /var/log/"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 简单脚本中（兼容性优先）</span></span><br><span class="line"><span class="comment">#!/bin/bash</span></span><br><span class="line">grep -q <span class="string">"pattern"</span> file.txt &amp;&amp; <span class="built_in">echo</span> <span class="string">"found"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 管道链式操作</span></span><br><span class="line"><span class="built_in">cat</span> log.txt | grep <span class="string">"ERROR"</span> | grep -v <span class="string">"ignore"</span> | <span class="built_in">wc</span> -l</span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 非代码文本搜索</span></span><br><span class="line">grep <span class="string">"TODO"</span> notes.txt</span><br><span class="line">grep <span class="string">"^export"</span> ~/.zshrc</span><br></pre></td></tr></tbody></table></figure><h3 id="选择-ripgrep-的场景"><a href="#选择-ripgrep-的场景" class="headerlink" title="选择 ripgrep 的场景"></a>选择 ripgrep 的场景</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ✅ 日常代码搜索（推荐默认）</span></span><br><span class="line">rg <span class="string">"function"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 大型代码库</span></span><br><span class="line">rg <span class="string">"import React"</span> ~/projects/huge-monorepo/</span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 快速定位</span></span><br><span class="line">rg -l <span class="string">"deprecated"</span> ./src/  <span class="comment"># 只看文件列表</span></span><br><span class="line">rg -t js <span class="string">"class.*extends"</span>  <span class="comment"># 按类型过滤</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 与编辑器集成</span></span><br><span class="line"><span class="comment"># VSCode, Vim, Emacs 都有 rg 插件</span></span><br></pre></td></tr></tbody></table></figure><h3 id="选择-ast-grep-的场景"><a href="#选择-ast-grep-的场景" class="headerlink" title="选择 ast-grep 的场景"></a>选择 ast-grep 的场景</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># ✅ 代码重构</span></span><br><span class="line">sg -p <span class="string">'var $V = $E'</span> -r <span class="string">'let $V = $E'</span> -l js ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 代码审查规则</span></span><br><span class="line">sg scan --config ./lint-rules.yml ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 精确模式匹配（避免误匹配字符串/注释）</span></span><br><span class="line">sg -p <span class="string">'console.log($A)'</span> -l js</span><br><span class="line"><span class="comment"># 只匹配真正的 console.log 调用，不会匹配字符串中的 "console.log"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ✅ 复杂代码搜索</span></span><br><span class="line">sg -p <span class="string">'useEffect(() =&gt; { $$$ return () =&gt; { $$$ } })'</span> -l tsx</span><br><span class="line"><span class="comment"># 查找所有带清理函数的 useEffect</span></span><br></pre></td></tr></tbody></table></figure><h3 id="组合使用示例"><a href="#组合使用示例" class="headerlink" title="组合使用示例"></a>组合使用示例</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先用 rg 快速定位文件</span></span><br><span class="line">rg -l <span class="string">"TODO.*security"</span> ./src/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 再用 ast-grep 精确分析</span></span><br><span class="line">sg -p <span class="string">'TODO($AUTHOR): $$$'</span> -l js ./src/auth/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 最后用 grep 统计</span></span><br><span class="line">grep -c <span class="string">"TODO"</span> ./src/**/*.js | awk -F: <span class="string">'{sum+=$2} END {print sum}'</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="最佳实践与技巧"><a href="#最佳实践与技巧" class="headerlink" title="最佳实践与技巧"></a>最佳实践与技巧</h2><h3 id="ripgrep-技巧"><a href="#ripgrep-技巧" class="headerlink" title="ripgrep 技巧"></a>ripgrep 技巧</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 创建 ~/.ripgreprc 配置文件</span></span><br><span class="line">--smart-case</span><br><span class="line">--hidden</span><br><span class="line">--glob=!.git/*</span><br><span class="line">--glob=!node_modules/*</span><br><span class="line">--max-columns=150</span><br><span class="line">--max-columns-preview</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 设置环境变量</span></span><br><span class="line"><span class="built_in">export</span> RIPGREP_CONFIG_PATH=~/.ripgreprc</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 常用别名</span></span><br><span class="line"><span class="built_in">alias</span> rg=<span class="string">'rg --smart-case'</span></span><br><span class="line"><span class="built_in">alias</span> rgi=<span class="string">'rg --no-ignore'</span>  <span class="comment"># 包含 gitignore 文件</span></span><br><span class="line"><span class="built_in">alias</span> rgh=<span class="string">'rg --hidden'</span>     <span class="comment"># 包含隐藏文件</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 组合 fd 使用</span></span><br><span class="line">fd -e js -x rg <span class="string">"pattern"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="ast-grep-技巧"><a href="#ast-grep-技巧" class="headerlink" title="ast-grep 技巧"></a>ast-grep 技巧</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 调试模式（查看 AST 解析结果）</span></span><br><span class="line">sg -p <span class="string">'console.log($A)'</span> -l js --debug</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 交互式测试</span></span><br><span class="line">sg <span class="built_in">test</span></span><br><span class="line"><span class="comment"># 进入交互式 REPL 测试模式</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 项目级配置</span></span><br><span class="line"><span class="comment"># 在项目根目录创建 sgconfig.yml</span></span><br><span class="line">ruleDirs:</span><br><span class="line">  - ./lint-rules</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. CI 集成</span></span><br><span class="line"><span class="comment"># .github/workflows/lint.yml</span></span><br><span class="line">- name: Run ast-grep</span><br><span class="line">  run: sg scan --config ./sgconfig.yml ./src/</span><br></pre></td></tr></tbody></table></figure><h3 id="grep-技巧"><a href="#grep-技巧" class="headerlink" title="grep 技巧"></a>grep 技巧</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 1. 颜色输出</span></span><br><span class="line"><span class="built_in">export</span> GREP_COLORS=<span class="string">'ms=01;31:mc=01;31:sl=:cx=:fn=35:ln=32:bn=32:se=36'</span></span><br><span class="line">grep --color=auto <span class="string">"pattern"</span> file</span><br><span class="line"></span><br><span class="line"><span class="comment"># 2. 显示匹配行号和文件名</span></span><br><span class="line">grep -Hn <span class="string">"pattern"</span> *.txt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 3. 统计匹配次数并排序</span></span><br><span class="line">grep -ro <span class="string">"pattern"</span> ./ | <span class="built_in">sort</span> | <span class="built_in">uniq</span> -c | <span class="built_in">sort</span> -nr</span><br><span class="line"></span><br><span class="line"><span class="comment"># 4. 排除特定文件</span></span><br><span class="line">grep -r --exclude=<span class="string">"*.min.js"</span> <span class="string">"pattern"</span> ./</span><br><span class="line"></span><br><span class="line"><span class="comment"># 5. 使用 agrep 进行模糊搜索（如已安装）</span></span><br><span class="line">agrep -i <span class="string">"patern"</span> file  <span class="comment"># 允许拼写错误</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="如何选择"><a href="#如何选择" class="headerlink" title="如何选择"></a>如何选择</h2><h3 id="决策流程图"><a href="#决策流程图" class="headerlink" title="决策流程图"></a>决策流程图</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">开始</span><br><span class="line">  │</span><br><span class="line">  ├─ 是否需要理解代码语法？</span><br><span class="line">  │   ├─ 是 → ast-grep</span><br><span class="line">  │   └─ 否 ↓</span><br><span class="line">  │</span><br><span class="line">  ├─ 是否在服务器/无 root 环境？</span><br><span class="line">  │   ├─ 是 → grep</span><br><span class="line">  │   └─ 否 ↓</span><br><span class="line">  │</span><br><span class="line">  ├─ 是否需要极速搜索？</span><br><span class="line">  │   ├─ 是 → ripgrep</span><br><span class="line">  │   └─ 否 → grep (系统自带)</span><br><span class="line">  │</span><br><span class="line">  └─ 推荐：日常开发默认使用 ripgrep</span><br></pre></td></tr></tbody></table></figure><h3 id="推荐配置"><a href="#推荐配置" class="headerlink" title="推荐配置"></a>推荐配置</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装</span></span><br><span class="line">brew install grep          <span class="comment"># macOS 获取 GNU grep</span></span><br><span class="line">brew install ripgrep       <span class="comment"># 安装 rg</span></span><br><span class="line">brew install ast-grep      <span class="comment"># 安装 sg</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Shell 配置</span></span><br><span class="line"><span class="comment"># ~/.zshrc 或 ~/.bashrc</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ripgrep 别名</span></span><br><span class="line"><span class="built_in">alias</span> rg=<span class="string">'rg --smart-case'</span></span><br><span class="line"><span class="built_in">alias</span> rgi=<span class="string">'rg --no-ignore'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># ast-grep 别名  </span></span><br><span class="line"><span class="built_in">alias</span> sgjs=<span class="string">'sg -l js'</span></span><br><span class="line"><span class="built_in">alias</span> sgpy=<span class="string">'sg -l py'</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># grep 增强（macOS）</span></span><br><span class="line"><span class="built_in">alias</span> grep=<span class="string">'ggrep --color=auto'</span></span><br></pre></td></tr></tbody></table></figure><h3 id="团队协作建议"><a href="#团队协作建议" class="headerlink" title="团队协作建议"></a>团队协作建议</h3><table><thead><tr><th>场景</th><th>推荐工具</th><th>理由</th></tr></thead><tbody><tr><td>CI/CD 检查</td><td>ast-grep</td><td>可配置规则，输出标准化</td></tr><tr><td>代码审查</td><td>ast-grep</td><td>精确匹配，避免误报</td></tr><tr><td>日常搜索</td><td>ripgrep</td><td>速度快，开箱即用</td></tr><tr><td>文档搜索</td><td>grep / ripgrep</td><td>不需要语法感知</td></tr><tr><td>重构任务</td><td>ast-grep</td><td>安全替换，理解上下文</td></tr></tbody></table><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>三款工具各有千秋，选择的关键在于<strong>场景匹配</strong>：</p><table><thead><tr><th>工具</th><th>一句话总结</th><th align="center">推荐指数</th></tr></thead><tbody><tr><td><strong>grep</strong></td><td>无处不在的文本搜索标准</td><td align="center">⭐⭐⭐⭐</td></tr><tr><td><strong>ripgrep</strong></td><td>日常开发必备的速度利器</td><td align="center">⭐⭐⭐⭐⭐</td></tr><tr><td><strong>ast-grep</strong></td><td>代码重构与审查的语法专家</td><td align="center">⭐⭐⭐⭐</td></tr></tbody></table><h3 id="最终建议"><a href="#最终建议" class="headerlink" title="最终建议"></a>最终建议</h3><ol><li><strong>本地开发环境</strong>：首选 <strong>ripgrep</strong> 作为默认搜索工具</li><li><strong>代码重构任务</strong>：使用 <strong>ast-grep</strong> 确保精确安全</li><li><strong>服务器/脚本</strong>：使用 <strong>grep</strong> 确保兼容性</li><li><strong>团队项目</strong>：用 <strong>ast-grep</strong> 配置自定义 lint 规则</li></ol><hr><h2 id="延伸阅读"><a href="#延伸阅读" class="headerlink" title="延伸阅读"></a>延伸阅读</h2><ul><li><a href="https://github.com/BurntSushi/ripgrep">ripgrep 官方文档</a></li><li><a href="https://ast-grep.github.io/">ast-grep 官方文档</a></li><li><a href="https://www.gnu.org/software/grep/manual/">GNU grep 手册</a></li><li><a href="https://regexone.com/">正则表达式入门教程</a></li><li><a href="https://astexplorer.net/">AST 可视化工具</a></li></ul><hr><blockquote><p>💡 <strong>提示</strong>：工具没有绝对的好坏，只有适合与否。建议全部安装，根据场景灵活切换。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/grep-vs-ripgrep-vs-astgrep/</id>
    <link href="https://imwnk.cn/archives/grep-vs-ripgrep-vs-astgrep/"/>
    <published>2026-03-27T07:00:00.000Z</published>
    <summary>深入对比 grep、ripgrep (rg) 和 ast-grep (sg) 三款代码搜索工具的特性、性能、使用场景，帮助你选择最适合的开发工具</summary>
    <title>Grep vs Ripgrep vs AST-Grep - 代码搜索工具终极对比</title>
    <updated>2026-03-27T04:01:16.061Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="ai" scheme="https://imwnk.cn/tags/ai/"/>
    <category term="agent" scheme="https://imwnk.cn/tags/agent/"/>
    <category term="cli" scheme="https://imwnk.cn/tags/cli/"/>
    <category term="automation" scheme="https://imwnk.cn/tags/automation/"/>
    <content>
      <![CDATA[<blockquote><p><strong>CLI-Anything</strong> — <em>让今天的软件为明天的 AI Agent 而生。</em></p></blockquote><p>你的 AI 编码助手想要控制 GIMP 修图、操作 Blender 建模、甚至管理 LibreOffice 文档，但这些软件没有 API？CLI-Anything 让这一切成为可能。</p><h2 id="为什么需要-CLI-Anything？"><a href="#为什么需要-CLI-Anything？" class="headerlink" title="为什么需要 CLI-Anything？"></a>为什么需要 CLI-Anything？</h2><p>如果你经常使用 Claude Code、Cursor、OpenCode 等 AI 编码助手，你一定遇到过这样的困境：</p><ul><li>AI 能写代码，但无法直接操作你电脑上的专业软件</li><li>想要自动化处理图片、视频、文档，却苦于没有 API</li><li>每个软件的学习成本都很高，AI 也无法帮你”一键搞定”</li></ul><p><strong>CLI-Anything 解决了这个问题</strong> —— 它通过自动生成命令行接口，让任何软件都能被 AI Agent 控制。</p><h2 id="CLI-Anything-是什么？"><a href="#CLI-Anything-是什么？" class="headerlink" title="CLI-Anything 是什么？"></a>CLI-Anything 是什么？</h2><p>CLI-Anything 是由 <strong>香港大学数据科学实验室 (HKUDS)</strong> 开发的开源项目，核心目标是：</p><blockquote><p><strong>让世界上所有的软件都能被 AI Agent 原生控制</strong></p></blockquote><p>它通过分析软件源码，自动生成完整的 CLI 工具，包括：</p><ul><li>📐 <strong>命令设计</strong> — 自动映射软件功能到命令行参数</li><li>🔨 <strong>CLI 实现</strong> — 基于 Python Click 框架生成可执行工具</li><li>🧪 <strong>完整测试</strong> — 自动生成单元测试和 E2E 测试</li><li>📚 <strong>AI 技能定义</strong> — 生成 SKILL.md，让 AI 自动学习使用方法</li><li>📦 <strong>一键安装</strong> — <code>pip install</code> 即可使用</li></ul><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">软件源码 → CLI-Anything → 完整 CLI 工具 → AI Agent 控制</span><br></pre></td></tr></tbody></table></figure><h2 id="核心特性"><a href="#核心特性" class="headerlink" title="核心特性"></a>核心特性</h2><h3 id="1-多平台-AI-Agent-支持"><a href="#1-多平台-AI-Agent-支持" class="headerlink" title="1. 多平台 AI Agent 支持"></a>1. 多平台 AI Agent 支持</h3><p>CLI-Anything 支持目前主流的 AI 编码平台：</p><table><thead><tr><th>平台</th><th>安装方式</th><th>状态</th></tr></thead><tbody><tr><td>Claude Code</td><td><code>/plugin install cli-anything</code></td><td>✅ 官方支持</td></tr><tr><td>OpenCode</td><td><code>/cli-anything ./gimp</code></td><td>✅ 官方支持</td></tr><tr><td>OpenClaw</td><td><code>@cli-anything build ./gimp</code></td><td>✅ 社区支持</td></tr><tr><td>Codex</td><td><code>cli-anything build ./gimp</code></td><td>✅ 社区支持</td></tr><tr><td>Qodercli</td><td><code>/cli-anything:cli-anything ./gimp</code></td><td>✅ 社区支持</td></tr><tr><td>GitHub Copilot CLI</td><td><code>/cli-anything:cli-anything ./gimp</code></td><td>✅ 社区支持</td></tr><tr><td>Goose</td><td>通过 CLI Provider</td><td>🧪 实验性</td></tr></tbody></table><h3 id="2-七阶段自动化流程"><a href="#2-七阶段自动化流程" class="headerlink" title="2. 七阶段自动化流程"></a>2. 七阶段自动化流程</h3><p>CLI-Anything 采用严谨的七阶段流程生成 CLI：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">Phase 1: 分析 (Analyze) — 扫描源码，映射 GUI 动作到 API</span><br><span class="line">Phase 2: 设计 (Design) — 架构命令组、状态模型、输出格式</span><br><span class="line">Phase 3: 实现 (Implement) — 构建 Click CLI，支持 REPL、JSON 输出、撤销/重做</span><br><span class="line">Phase 4: 规划测试 (Plan Tests) — 创建 TEST.md，规划单元测试 + E2E 测试</span><br><span class="line">Phase 5: 编写测试 (Write Tests) — 实现完整测试套件</span><br><span class="line">Phase 6: 文档 (Document) — 更新 TEST.md 测试结果</span><br><span class="line">Phase 7: 发布 (Publish) — 创建 setup.py，安装到 PATH</span><br></pre></td></tr></tbody></table></figure><h3 id="3-已支持的软件（16-）"><a href="#3-已支持的软件（16-）" class="headerlink" title="3. 已支持的软件（16+）"></a>3. 已支持的软件（16+）</h3><p>CLI-Anything 社区已经贡献了 16+ 个软件的 CLI 封装：</p><p><strong>创意工具</strong></p><ul><li>🎨 GIMP — 图像编辑</li><li>🎬 Blender — 3D 建模与动画</li><li>🎵 Audacity — 音频编辑</li><li>🎼 MuseScore — 乐谱编辑</li><li>🎥 Kdenlive / Shotcut — 视频剪辑</li><li>🖼️ Krita — 数字绘画</li><li>📐 Inkscape — 矢量图形</li></ul><p><strong>生产力工具</strong></p><ul><li>📄 LibreOffice — 办公套件</li><li>📝 Mubu — 思维导图</li><li>📊 Draw.io — 流程图</li><li>📓 NotebookLM — 笔记管理</li></ul><p><strong>AI/开发工具</strong></p><ul><li>🧠 ComfyUI — AI 图像生成工作流</li><li>🦙 Ollama — 本地 LLM 管理</li><li>🌐 Novita AI — OpenAI 兼容 API</li><li>🛡️ AdGuard Home — 网络过滤</li></ul><h3 id="4-CLI-Hub-生态"><a href="#4-CLI-Hub-生态" class="headerlink" title="4. CLI-Hub 生态"></a>4. CLI-Hub 生态</h3><p>CLI-Anything 推出了 <a href="https://hkuds.github.io/CLI-Anything/">CLI-Hub</a> —— 一个中央注册表，你可以：</p><ul><li>🔍 浏览所有社区 CLI</li><li>📦 一键安装：<code>pip install cli-anything-gimp</code></li><li>🤖 <strong>Agent 自动发现</strong> — AI 可以自主浏览并安装所需 CLI</li></ul><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Agent 可以自主完成：</span></span><br><span class="line"><span class="string">"Find appropriate CLI software in CLI-Hub and complete the task: edit image"</span></span><br><span class="line"><span class="comment"># → 自动发现 GIMP CLI → pip install → 读取 SKILL.md → 执行任务</span></span><br></pre></td></tr></tbody></table></figure><h2 id="快速开始"><a href="#快速开始" class="headerlink" title="快速开始"></a>快速开始</h2><h3 id="Claude-Code-用户"><a href="#Claude-Code-用户" class="headerlink" title="Claude Code 用户"></a>Claude Code 用户</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 添加插件市场</span></span><br><span class="line">/plugin marketplace add HKUDS/CLI-Anything</span><br><span class="line"></span><br><span class="line"><span class="comment"># 安装插件</span></span><br><span class="line">/plugin install cli-anything</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成 CLI（以 GIMP 为例）</span></span><br><span class="line">/cli-anything:cli-anything ./gimp</span><br><span class="line"></span><br><span class="line"><span class="comment"># 可选：持续优化</span></span><br><span class="line">/cli-anything:refine ./gimp <span class="string">"batch processing and filters"</span></span><br></pre></td></tr></tbody></table></figure><h3 id="OpenCode-用户"><a href="#OpenCode-用户" class="headerlink" title="OpenCode 用户"></a>OpenCode 用户</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 复制命令到配置目录</span></span><br><span class="line"><span class="built_in">cp</span> CLI-Anything/opencode-commands/*.md ~/.config/opencode/commands/</span><br><span class="line"><span class="built_in">cp</span> CLI-Anything/cli-anything-plugin/HARNESS.md ~/.config/opencode/commands/</span><br><span class="line"></span><br><span class="line"><span class="comment"># 生成 CLI</span></span><br><span class="line">/cli-anything ./gimp</span><br></pre></td></tr></tbody></table></figure><h3 id="使用生成的-CLI"><a href="#使用生成的-CLI" class="headerlink" title="使用生成的 CLI"></a>使用生成的 CLI</h3><p>无论通过哪个平台生成，CLI 的使用方式都一样：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 安装到 PATH</span></span><br><span class="line"><span class="built_in">cd</span> gimp/agent-harness &amp;&amp; pip install -e .</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看帮助</span></span><br><span class="line">cli-anything-gimp --<span class="built_in">help</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 创建新项目</span></span><br><span class="line">cli-anything-gimp project new --width 1920 --height 1080 -o poster.json</span><br><span class="line"></span><br><span class="line"><span class="comment"># 添加图层</span></span><br><span class="line">cli-anything-gimp layer add -n <span class="string">"Background"</span> --<span class="built_in">type</span> solid --color <span class="string">"#1a1a2e"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 进入交互式 REPL</span></span><br><span class="line">cli-anything-gimp</span><br></pre></td></tr></tbody></table></figure><h2 id="为什么-CLI-是-Agent-的最佳接口？"><a href="#为什么-CLI-是-Agent-的最佳接口？" class="headerlink" title="为什么 CLI 是 Agent 的最佳接口？"></a>为什么 CLI 是 Agent 的最佳接口？</h2><p>CLI-Anything 选择 CLI 作为 AI Agent 和软件之间的桥梁，因为：</p><table><thead><tr><th>特性</th><th>CLI 优势</th></tr></thead><tbody><tr><td><strong>结构化 &amp; 可组合</strong></td><td>文本命令与 LLM 格式天然匹配，支持链式调用</td></tr><tr><td><strong>轻量 &amp; 通用</strong></td><td>最小开销，跨平台无需额外依赖</td></tr><tr><td><strong>自描述</strong></td><td><code>--help</code> 提供自动文档，Agent 可自动发现</td></tr><tr><td><strong>已被验证</strong></td><td>Claude Code 每天通过 CLI 运行数千个真实工作流</td></tr><tr><td><strong>Agent 优先设计</strong></td><td>JSON 输出消除解析复杂度</td></tr><tr><td><strong>确定性 &amp; 可靠</strong></td><td>一致的结果确保可预测的 Agent 行为</td></tr></tbody></table><h2 id="技术架构"><a href="#技术架构" class="headerlink" title="技术架构"></a>技术架构</h2><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line">┌─────────────────────────────────────────────────────────┐</span><br><span class="line">│                    AI Agent                              │</span><br><span class="line">│  (Claude Code / OpenCode / Cursor / Codex ...)          │</span><br><span class="line">└────────────────────┬────────────────────────────────────┘</span><br><span class="line">                     │ MCP / CLI</span><br><span class="line">┌────────────────────┴────────────────────────────────────┐</span><br><span class="line">│                 CLI-Anything Plugin                      │</span><br><span class="line">│  ┌─────────────┐ ┌─────────────┐ ┌───────────────────┐  │</span><br><span class="line">│  │   Analyze   │ │   Design    │ │   Implement       │  │</span><br><span class="line">│  │  (源码分析)  │ │  (命令设计)  │ │  (CLI 实现)        │  │</span><br><span class="line">│  └─────────────┘ └─────────────┘ └───────────────────┘  │</span><br><span class="line">│  ┌─────────────┐ ┌─────────────┐ ┌───────────────────┐  │</span><br><span class="line">│  │  Plan Tests │ │ Write Tests │ │   Document        │  │</span><br><span class="line">│  │  (测试规划)  │ │  (编写测试)  │ │   (文档生成)       │  │</span><br><span class="line">│  └─────────────┘ └─────────────┘ └───────────────────┘  │</span><br><span class="line">│  ┌───────────────────────────────────────────────────┐  │</span><br><span class="line">│  │              Publish (发布打包)                    │  │</span><br><span class="line">│  └───────────────────────────────────────────────────┘  │</span><br><span class="line">└────────────────────┬────────────────────────────────────┘</span><br><span class="line">                     │</span><br><span class="line">┌────────────────────┴────────────────────────────────────┐</span><br><span class="line">│              Generated CLI Package                       │</span><br><span class="line">│  ┌─────────────┐ ┌─────────────┐ ┌───────────────────┐  │</span><br><span class="line">│  │  CLI Tool   │ │   Tests     │ │   SKILL.md        │  │</span><br><span class="line">│  │ (Python pkg)│ │  (pytest)   │ │ (AI 可发现技能定义) │  │</span><br><span class="line">│  └─────────────┘ └─────────────┘ └───────────────────┘  │</span><br><span class="line">└─────────────────────────────────────────────────────────┘</span><br></pre></td></tr></tbody></table></figure><h2 id="实际应用场景"><a href="#实际应用场景" class="headerlink" title="实际应用场景"></a>实际应用场景</h2><h3 id="场景-1：自动化图像处理"><a href="#场景-1：自动化图像处理" class="headerlink" title="场景 1：自动化图像处理"></a>场景 1：自动化图像处理</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 批量处理图片</span></span><br><span class="line">cli-anything-gimp batch process \</span><br><span class="line">  --input ./photos/*.jpg \</span><br><span class="line">  --action <span class="string">"resize 1920x1080, apply filter 'vintage', export png"</span> \</span><br><span class="line">  --output ./processed/</span><br></pre></td></tr></tbody></table></figure><h3 id="场景-2：AI-辅助-3D-建模"><a href="#场景-2：AI-辅助-3D-建模" class="headerlink" title="场景 2：AI 辅助 3D 建模"></a>场景 2：AI 辅助 3D 建模</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 创建场景并渲染</span></span><br><span class="line">cli-anything-blender scene new --name <span class="string">"ProductShowcase"</span></span><br><span class="line">cli-anything-blender object add --<span class="built_in">type</span> cube --location <span class="string">"0,0,0"</span></span><br><span class="line">cli-anything-blender material apply --object Cube --material <span class="string">"Metallic"</span></span><br><span class="line">cli-anything-blender render --output ./render.png --resolution 4K</span><br></pre></td></tr></tbody></table></figure><h3 id="场景-3：自动化文档处理"><a href="#场景-3：自动化文档处理" class="headerlink" title="场景 3：自动化文档处理"></a>场景 3：自动化文档处理</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 批量转换文档格式</span></span><br><span class="line">cli-anything-libreoffice convert \</span><br><span class="line">  --input ./docs/*.docx \</span><br><span class="line">  --format pdf \</span><br><span class="line">  --output ./pdfs/</span><br></pre></td></tr></tbody></table></figure><h2 id="社区贡献"><a href="#社区贡献" class="headerlink" title="社区贡献"></a>社区贡献</h2><p>CLI-Anything 是一个活跃的开源项目，欢迎贡献：</p><ul><li>🌟 <strong>Star</strong> 项目表示支持</li><li>📝 提交新的软件 CLI</li><li>🔧 改进现有 CLI</li><li>🐛 报告 Bug</li><li>📖 完善文档</li></ul><p>贡献方式：Fork → 修改 → PR，CLI-Hub 会自动更新。</p><h2 id="与其他方案对比"><a href="#与其他方案对比" class="headerlink" title="与其他方案对比"></a>与其他方案对比</h2><table><thead><tr><th>方案</th><th>需要 API</th><th>需要重新编译</th><th>学习成本</th><th>Agent 友好</th></tr></thead><tbody><tr><td>原生 API</td><td>✅ 需要</td><td>❌ 不需要</td><td>高</td><td>取决于 API 设计</td></tr><tr><td>GUI 自动化</td><td>❌ 不需要</td><td>❌ 不需要</td><td>中</td><td>不稳定</td></tr><tr><td>重新封装</td><td>❌ 不需要</td><td>✅ 需要</td><td>极高</td><td>是</td></tr><tr><td><strong>CLI-Anything</strong></td><td>❌ 不需要</td><td>❌ 不需要</td><td>低</td><td>✅ 原生支持</td></tr></tbody></table><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>CLI-Anything 解决了 AI Agent 时代的核心问题：</p><blockquote><p><strong>如何让现有的软件生态为 AI Agent 所用？</strong></p></blockquote><p>它的答案是：<strong>自动生成 CLI 接口</strong> —— 不需要 API、不需要重新编译、不需要复杂的集成。</p><ol><li><strong>自动化</strong> — 七阶段流程自动生成完整 CLI</li><li><strong>通用性</strong> — 适用于任何开源软件</li><li><strong>Agent 原生</strong> — JSON 输出 + SKILL.md，AI 可自动学习使用</li><li><strong>社区驱动</strong> — 16+ 软件已支持，持续扩展</li></ol><p>如果你希望 AI Agent 能够控制更多软件、自动化更多工作流，CLI-Anything 绝对值得尝试。</p><hr><blockquote><p>📌 <strong>项目地址</strong>: <a href="https://github.com/HKUDS/CLI-Anything">https://github.com/HKUDS/CLI-Anything</a></p><p>🌐 <strong>CLI-Hub</strong>: <a href="https://hkuds.github.io/CLI-Anything/">https://hkuds.github.io/CLI-Anything/</a></p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/cli-anything/</id>
    <link href="https://imwnk.cn/archives/cli-anything/"/>
    <published>2026-03-24T06:30:00.000Z</published>
    <summary>CLI-Anything 是一个革命性的开源项目，通过自动生成 CLI 接口，让任何软件都能被 AI Agent 原生控制，无需 API、无需 GUI、无需重新编译</summary>
    <title>CLI-Anything - 让任意软件都能被 AI Agent 控制</title>
    <updated>2026-03-24T12:04:23.458Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="ai" scheme="https://imwnk.cn/tags/ai/"/>
    <category term="agent" scheme="https://imwnk.cn/tags/agent/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="workflow" scheme="https://imwnk.cn/tags/workflow/"/>
    <content>
      <![CDATA[<blockquote><p>让 AI 助手不再”跳过步骤”，变成真正可靠的编程伙伴。</p></blockquote><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E4%BB%80%E4%B9%88%E6%98%AF-superpowers">什么是 Superpowers？</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E7%90%86%E5%BF%B5%E6%B5%81%E7%A8%8B%E4%BC%98%E5%85%88">核心理念：流程优先</a></li><li><a href="#%E6%8A%80%E8%83%BD%E5%88%86%E7%B1%BB%E4%B8%80%E8%A7%88">技能分类一览</a></li><li><a href="#%E6%A0%B8%E5%BF%83%E6%8A%80%E8%83%BD%E8%AF%A6%E8%A7%A3">核心技能详解</a></li><li><a href="#%E5%AE%9E%E6%88%98%E7%A4%BA%E4%BE%8B%E4%B8%80%E4%B8%AA%E5%8A%9F%E8%83%BD%E7%9A%84%E5%AE%8C%E6%95%B4%E6%B5%81%E7%A8%8B">实战示例</a></li><li><a href="#%E6%9C%80%E4%BD%B3%E5%AE%9E%E8%B7%B5">最佳实践</a></li><li><a href="#%E5%AE%89%E8%A3%85%E4%B8%8E%E9%85%8D%E7%BD%AE">安装与配置</a></li></ol><hr><h2 id="什么是-Superpowers？"><a href="#什么是-Superpowers？" class="headerlink" title="什么是 Superpowers？"></a>什么是 Superpowers？</h2><p>想象一下这个场景：你让 AI 助手帮你实现一个新功能，它直接开始写代码。写完之后你发现遗漏了边界情况，修复后又引入了新 bug。反复几次后，你开始怀疑 AI 是否真的能帮你提效。</p><p><strong>这不是 AI 能力的问题，而是工作流程的问题。</strong></p><p>Superpowers 是由 <a href="https://blog.fsck.com/">Jesse Vincent</a> 和 <a href="https://primeradiant.com/">Prime Radiant</a> 团队开发的<strong>完整软件开发工作流</strong>，建立在一系列可组合的”技能”(Skills)之上。</p><p>它不是让 AI “更聪明”，而是给 AI 一套<strong>标准化的工作流程</strong>——就像给一个聪明但没有纪律的工程师一本详细的操作手册。</p><h3 id="工作原理"><a href="#工作原理" class="headerlink" title="工作原理"></a>工作原理</h3><ol><li><strong>启动时</strong>：当你启动编码助手，它不会直接跳进去写代码</li><li><strong>澄清需求</strong>：它会退一步，问你真正想做什么</li><li><strong>设计验证</strong>：提取规格后，分段展示让你审核</li><li><strong>计划制定</strong>：设计通过后，编写清晰的实现计划</li><li><strong>自主执行</strong>：启动子代理开发流程，自动工作数小时</li></ol><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">模糊需求 → Brainstorming → Writing Plans → TDD Implementation → Verification</span><br></pre></td></tr></tbody></table></figure><h2 id="核心理念：流程优先"><a href="#核心理念：流程优先" class="headerlink" title="核心理念：流程优先"></a>核心理念：流程优先</h2><p>Superpowers 的核心原则很简单：<strong>永远遵循流程，不跳过任何步骤。</strong></p><p>这套理念体现在它的”铁律”中：</p><table><thead><tr><th>Skill</th><th>铁律</th></tr></thead><tbody><tr><td><strong>TDD</strong></td><td>没有失败的测试，就不写生产代码</td></tr><tr><td><strong>Debugging</strong></td><td>没有找到根因，就不尝试修复</td></tr><tr><td><strong>Verification</strong></td><td>没有运行验证命令，就不声称完成</td></tr><tr><td><strong>Brainstorming</strong></td><td>没有设计文档被批准，就不开始实现</td></tr></tbody></table><p>听起来很死板？但正是这种”死板”，让 AI 的输出变得可预测、可信赖。</p><h3 id="设计哲学"><a href="#设计哲学" class="headerlink" title="设计哲学"></a>设计哲学</h3><ul><li><strong>测试驱动开发</strong> - 永远先写测试</li><li><strong>系统化优于临时方案</strong> - 流程优于猜测</li><li><strong>降低复杂度</strong> - 简洁是首要目标</li><li><strong>证据优于声称</strong> - 声明成功前必须验证</li></ul><h2 id="技能分类一览"><a href="#技能分类一览" class="headerlink" title="技能分类一览"></a>技能分类一览</h2><p>Superpowers 包含 14 个核心技能，按功能分为三类：</p><h3 id="流程控制类"><a href="#流程控制类" class="headerlink" title="流程控制类"></a>流程控制类</h3><table><thead><tr><th>技能</th><th>触发时机</th><th>作用</th></tr></thead><tbody><tr><td><code>using-superpowers</code></td><td>每次对话开始时</td><td>确保正确调用其他技能</td></tr><tr><td><code>brainstorming</code></td><td>任何创造性工作前</td><td>将模糊想法转化为清晰设计</td></tr><tr><td><code>writing-plans</code></td><td>有需求规格后</td><td>编写详细的实现计划</td></tr><tr><td><code>executing-plans</code></td><td>有实现计划后</td><td>执行计划中的任务</td></tr></tbody></table><h3 id="实施执行类"><a href="#实施执行类" class="headerlink" title="实施执行类"></a>实施执行类</h3><table><thead><tr><th>技能</th><th>触发时机</th><th>作用</th></tr></thead><tbody><tr><td><code>test-driven-development</code></td><td>实现功能或修复 bug 前</td><td>测试先行，红-绿-重构</td></tr><tr><td><code>systematic-debugging</code></td><td>遇到 bug 或测试失败时</td><td>系统化定位根因</td></tr><tr><td><code>subagent-driven-development</code></td><td>有独立任务时</td><td>并行执行多个子任务</td></tr><tr><td><code>dispatching-parallel-agents</code></td><td>有并发子代理工作时</td><td>并发子代理工作流</td></tr><tr><td><code>using-git-worktrees</code></td><td>设计批准后</td><td>创建隔离工作空间</td></tr></tbody></table><h3 id="质量保障类"><a href="#质量保障类" class="headerlink" title="质量保障类"></a>质量保障类</h3><table><thead><tr><th>技能</th><th>触发时机</th><th>作用</th></tr></thead><tbody><tr><td><code>verification-before-completion</code></td><td>声称完成前</td><td>确保验证证据</td></tr><tr><td><code>requesting-code-review</code></td><td>任务之间</td><td>按计划审查，报告严重问题</td></tr><tr><td><code>receiving-code-review</code></td><td>收到审查反馈后</td><td>处理审查意见</td></tr><tr><td><code>finishing-a-development-branch</code></td><td>任务完成时</td><td>验证测试，提供合并/PR/丢弃选项</td></tr></tbody></table><h2 id="核心技能详解"><a href="#核心技能详解" class="headerlink" title="核心技能详解"></a>核心技能详解</h2><h3 id="1-Brainstorming：从想法到设计"><a href="#1-Brainstorming：从想法到设计" class="headerlink" title="1. Brainstorming：从想法到设计"></a>1. Brainstorming：从想法到设计</h3><p><strong>触发条件</strong>：任何需要创造新功能、构建组件、修改行为的任务。</p><p>这个技能的核心价值是<strong>在写代码前先思考清楚</strong>。</p><p>流程：</p><ol><li>探索项目上下文</li><li>逐个提问澄清需求</li><li>提出 2-3 种方案（附推荐理由）</li><li>呈现设计方案</li><li>用户确认后编写设计文档</li><li>进入 writing-plans</li></ol><p><strong>关键规则</strong>：</p><ul><li><strong>一个问题一条消息</strong>：不 overwhelm 用户</li><li><strong>提供多选项</strong>：2-3 种方案，附带推荐理由</li><li><strong>增量验证</strong>：每个设计部分都需要确认</li><li><strong>YAGNI 原则</strong>：砍掉不必要的功能</li></ul><p><strong>实际对话示例</strong>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">AI: 我理解你想添加用户认证功能。让我先了解一下：</span><br><span class="line">    1. 需要支持哪些登录方式？（邮箱密码 / 社交登录 / 手机验证码）</span><br><span class="line">    2. 是否需要"记住我"功能？</span><br><span class="line">    3. 密码重置流程是邮件还是短信？</span><br><span class="line"></span><br><span class="line">你: 只需要邮箱密码，不要"记住我"，密码重置用邮件。</span><br><span class="line"></span><br><span class="line">AI: 好的，我推荐两种方案：</span><br><span class="line">    A) 使用 JWT 无状态认证 - 适合分布式部署，token 存客户端</span><br><span class="line">    B) 使用 Session 状态认证 - 实现简单，安全性高</span><br><span class="line">    </span><br><span class="line">    考虑到你是单体应用起步，我推荐 B 方案。你觉得呢？</span><br></pre></td></tr></tbody></table></figure><h3 id="2-Test-Driven-Development：测试先行"><a href="#2-Test-Driven-Development：测试先行" class="headerlink" title="2. Test-Driven Development：测试先行"></a>2. Test-Driven Development：测试先行</h3><p><strong>触发条件</strong>：实现任何功能或修复任何 bug 之前。</p><p>TDD 的铁律：<strong>没有看到测试失败，就不知道测试是否正确。</strong></p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST</span><br></pre></td></tr></tbody></table></figure><p><strong>红-绿-重构循环</strong>：</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># RED: 先写失败的测试</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_retry_failed_operations</span>():</span><br><span class="line">    attempts = <span class="number">0</span></span><br><span class="line">    <span class="keyword">def</span> <span class="title function_">operation</span>():</span><br><span class="line">        <span class="keyword">nonlocal</span> attempts</span><br><span class="line">        attempts += <span class="number">1</span></span><br><span class="line">        <span class="keyword">if</span> attempts &lt; <span class="number">3</span>:</span><br><span class="line">            <span class="keyword">raise</span> Exception(<span class="string">"fail"</span>)</span><br><span class="line">        <span class="keyword">return</span> <span class="string">"success"</span></span><br><span class="line">    </span><br><span class="line">    result = retry_operation(operation)</span><br><span class="line">    <span class="keyword">assert</span> result == <span class="string">"success"</span></span><br><span class="line">    <span class="keyword">assert</span> attempts == <span class="number">3</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行测试 -&gt; FAIL (function not defined)</span></span><br></pre></td></tr></tbody></table></figure><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># GREEN: 写最少的代码让测试通过</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">retry_operation</span>(<span class="params">fn, max_retries=<span class="number">3</span></span>):</span><br><span class="line">    <span class="keyword">for</span> i <span class="keyword">in</span> <span class="built_in">range</span>(max_retries):</span><br><span class="line">        <span class="keyword">try</span>:</span><br><span class="line">            <span class="keyword">return</span> fn()</span><br><span class="line">        <span class="keyword">except</span> Exception <span class="keyword">as</span> e:</span><br><span class="line">            <span class="keyword">if</span> i == max_retries - <span class="number">1</span>:</span><br><span class="line">                <span class="keyword">raise</span> e</span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行测试 -&gt; PASS</span></span><br></pre></td></tr></tbody></table></figure><p><strong>常见借口 vs 现实</strong>：</p><table><thead><tr><th>借口</th><th>现实</th></tr></thead><tbody><tr><td>“太简单不用测试”</td><td>简单代码也会出错，测试只需 30 秒</td></tr><tr><td>“我先实现再补测试”</td><td>先写的测试会立刻通过，证明不了什么</td></tr><tr><td>“TDD 太慢了”</td><td>TDD 比事后调试快得多</td></tr><tr><td>“我手动测过了”</td><td>手动测试无法重复，无法回归</td></tr></tbody></table><h3 id="3-Systematic-Debugging：根因驱动"><a href="#3-Systematic-Debugging：根因驱动" class="headerlink" title="3. Systematic Debugging：根因驱动"></a>3. Systematic Debugging：根因驱动</h3><p><strong>触发条件</strong>：遇到任何 bug、测试失败、意外行为时。</p><p>调试的铁律：<strong>没有找到根因，就不尝试修复。</strong></p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST</span><br></pre></td></tr></tbody></table></figure><p><strong>四阶段流程</strong>：</p><ol><li><strong>Phase 1: 根因调查</strong> - 读错误日志 → 重现问题 → 检查变更 → 收集证据</li><li><strong>Phase 2: 模式分析</strong> - 找正常案例 → 对比差异 → 理解依赖</li><li><strong>Phase 3: 假设测试</strong> - 单一假设 → 最小改动 → 验证结果</li><li><strong>Phase 4: 实施修复</strong> - 写测试 → 修复根因 → 验证通过</li></ol><p><strong>多组件系统的证据收集</strong>：</p><p>当问题涉及多个层面（CI → 构建 → 签名）时，在<strong>每个边界</strong>添加诊断：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Layer 1: Workflow</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"=== Secrets in workflow: ==="</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"IDENTITY: <span class="variable">${IDENTITY:+SET}</span><span class="variable">${IDENTITY:-UNSET}</span>"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Layer 2: Build script</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"=== Env vars in build: ==="</span></span><br><span class="line"><span class="built_in">env</span> | grep IDENTITY || <span class="built_in">echo</span> <span class="string">"IDENTITY not in environment"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Layer 3: Signing</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"=== Keychain state: ==="</span></span><br><span class="line">security find-identities -v</span><br></pre></td></tr></tbody></table></figure><p><strong>3 次修复失败法则</strong>：</p><p>如果 3 次修复尝试都失败了，<strong>停止修复</strong>，重新审视架构。这通常意味着不是 bug，而是设计问题。</p><h3 id="4-Verification-Before-Completion：证据为王"><a href="#4-Verification-Before-Completion：证据为王" class="headerlink" title="4. Verification Before Completion：证据为王"></a>4. Verification Before Completion：证据为王</h3><p><strong>触发条件</strong>：声称工作完成、修复成功、测试通过之前。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">NO COMPLETION CLAIMS WITHOUT FRESH VERIFICATION EVIDENCE</span><br></pre></td></tr></tbody></table></figure><p><strong>门禁函数</strong>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">声称任何状态之前：</span><br><span class="line">1. 确认：什么命令能证明这个声称？</span><br><span class="line">2. 运行：执行完整命令（全新的、完整的）</span><br><span class="line">3. 阅读：完整输出，检查退出码，统计失败数</span><br><span class="line">4. 验证：输出是否确认声称？</span><br><span class="line">5. 只有此时：才能做出声称</span><br></pre></td></tr></tbody></table></figure><p><strong>正确做法 vs 错误做法</strong>：</p><table><thead><tr><th>声称</th><th>需要</th><th>不够</th></tr></thead><tbody><tr><td>“测试通过”</td><td>测试命令输出：0 失败</td><td>“应该通过”</td></tr><tr><td>“Lint 干净”</td><td>Linter 输出：0 错误</td><td>部分检查、推断</td></tr><tr><td>“构建成功”</td><td>构建命令：exit 0</td><td>Linter 通过、日志看起来正常</td></tr><tr><td>“Bug 已修复”</td><td>测试原始症状：通过</td><td>代码改了，假设已修复</td></tr></tbody></table><h2 id="实战示例：一个功能的完整流程"><a href="#实战示例：一个功能的完整流程" class="headerlink" title="实战示例：一个功能的完整流程"></a>实战示例：一个功能的完整流程</h2><p>假设你要实现”用户登录限流”功能，Superpowers 的完整流程是这样的：</p><h3 id="Step-1-Brainstorming"><a href="#Step-1-Brainstorming" class="headerlink" title="Step 1: Brainstorming"></a>Step 1: Brainstorming</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">你: 帮我实现登录限流，防止暴力破解</span><br><span class="line"></span><br><span class="line">AI: 明白。让我澄清几个问题：</span><br><span class="line">    1. 限流策略是什么？（N 次失败后锁定 / 滑动窗口 / 令牌桶）</span><br><span class="line">    2. 锁定时间多长？</span><br><span class="line">    3. 是否需要区分 IP 和账号？</span><br><span class="line">    </span><br><span class="line">你: 5 次失败后锁定账号 15 分钟，不需要区分 IP</span><br><span class="line"></span><br><span class="line">AI: 推荐两种方案：</span><br><span class="line">    A) Redis 计数器 + TTL - 适合分布式，性能高</span><br><span class="line">    B) 数据库字段记录 - 实现简单，单机够用</span><br><span class="line">    </span><br><span class="line">    你的系统目前是单体，我推荐 B 方案。同意吗？</span><br><span class="line">    </span><br><span class="line">你: 同意</span><br><span class="line"></span><br><span class="line">AI: [呈现详细设计文档，包含数据模型、API 变更、错误处理...]</span><br><span class="line">    这部分设计看起来对吗？</span><br></pre></td></tr></tbody></table></figure><h3 id="Step-2-Using-Git-Worktrees"><a href="#Step-2-Using-Git-Worktrees" class="headerlink" title="Step 2: Using Git Worktrees"></a>Step 2: Using Git Worktrees</h3><p>设计批准后，AI 创建隔离的工作空间：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 自动在新分支上创建工作树</span></span><br><span class="line">git worktree add ../my-project-feature -b feature/login-rate-limit</span><br></pre></td></tr></tbody></table></figure><h3 id="Step-3-Writing-Plans"><a href="#Step-3-Writing-Plans" class="headerlink" title="Step 3: Writing Plans"></a>Step 3: Writing Plans</h3><p>AI 编写详细的实现计划（每个步骤 2-5 分钟）：</p><figure class="highlight markdown"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="section">## Task 1: 添加数据库字段</span></span><br><span class="line"></span><br><span class="line"><span class="strong">**Files:**</span></span><br><span class="line"><span class="bullet">-</span> Modify: <span class="code">`models/user.py`</span></span><br><span class="line"><span class="bullet">-</span> Test: <span class="code">`tests/models/test_user.py`</span></span><br><span class="line"></span><br><span class="line"><span class="bullet">-</span> [ ] Step 1: 写失败的测试</span><br><span class="line"><span class="bullet">-</span> [ ] Step 2: 运行测试确认失败</span><br><span class="line"><span class="bullet">-</span> [ ] Step 3: 添加字段定义</span><br><span class="line"><span class="bullet">-</span> [ ] Step 4: 运行测试确认通过</span><br><span class="line"><span class="bullet">-</span> [ ] Step 5: 提交</span><br><span class="line"></span><br><span class="line"><span class="section">## Task 2: 实现限流逻辑</span></span><br><span class="line">...</span><br><span class="line"></span><br><span class="line"><span class="section">## Task 3: 添加 API 端点处理</span></span><br><span class="line">...</span><br></pre></td></tr></tbody></table></figure><h3 id="Step-4-Subagent-Driven-Development"><a href="#Step-4-Subagent-Driven-Development" class="headerlink" title="Step 4: Subagent-Driven Development"></a>Step 4: Subagent-Driven Development</h3><p>启动子代理流程：</p><ul><li>每个任务启动<strong>全新的子代理</strong></li><li>两阶段审查：规格合规性 → 代码质量</li><li>Claude 可以自主工作数小时</li></ul><h3 id="Step-5-TDD-Implementation"><a href="#Step-5-TDD-Implementation" class="headerlink" title="Step 5: TDD Implementation"></a>Step 5: TDD Implementation</h3><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># RED</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">test_locks_account_after_5_failures</span>(<span class="params">db</span>):</span><br><span class="line">    user = create_user(db, password=<span class="string">"correct"</span>)</span><br><span class="line">    <span class="keyword">for</span> _ <span class="keyword">in</span> <span class="built_in">range</span>(<span class="number">5</span>):</span><br><span class="line">        result = login(user.email, <span class="string">"wrong"</span>)</span><br><span class="line">        <span class="keyword">assert</span> result.error == <span class="string">"Invalid credentials"</span></span><br><span class="line">    </span><br><span class="line">    result = login(user.email, <span class="string">"correct"</span>)  <span class="comment"># 即使密码正确</span></span><br><span class="line">    <span class="keyword">assert</span> result.error == <span class="string">"Account locked"</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 运行 -&gt; FAIL</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># GREEN</span></span><br><span class="line"><span class="keyword">def</span> <span class="title function_">check_login_limit</span>(<span class="params">user</span>):</span><br><span class="line">    <span class="keyword">if</span> user.failed_attempts &gt;= <span class="number">5</span>:</span><br><span class="line">        <span class="keyword">if</span> user.locked_until <span class="keyword">and</span> user.locked_until &gt; now():</span><br><span class="line">            <span class="keyword">raise</span> AccountLocked()</span><br><span class="line">    <span class="comment"># ...</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Step-6-Verification"><a href="#Step-6-Verification" class="headerlink" title="Step 6: Verification"></a>Step 6: Verification</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">$ pytest tests/auth/test_rate_limit.py -v</span><br><span class="line">===== <span class="built_in">test</span> session starts =====</span><br><span class="line">test_locks_account_after_5_failures PASSED</span><br><span class="line">test_unlocks_after_15_minutes PASSED</span><br><span class="line">test_resets_on_success PASSED</span><br><span class="line">===== 3 passed =====</span><br><span class="line"></span><br><span class="line">$ npm run lint</span><br><span class="line"><span class="comment"># 无错误</span></span><br><span class="line"></span><br><span class="line">$ npm run build</span><br><span class="line"><span class="comment"># exit 0</span></span><br></pre></td></tr></tbody></table></figure><p><strong>只有此时，AI 才能说：”功能已实现，测试全部通过。”</strong></p><h3 id="Step-7-Finishing-a-Development-Branch"><a href="#Step-7-Finishing-a-Development-Branch" class="headerlink" title="Step 7: Finishing a Development Branch"></a>Step 7: Finishing a Development Branch</h3><p>完成所有任务后，AI 提供：</p><ul><li>验证所有测试通过</li><li>提供选项：合并 / PR / 保留 / 丢弃</li><li>清理工作树</li></ul><h2 id="最佳实践"><a href="#最佳实践" class="headerlink" title="最佳实践"></a>最佳实践</h2><h3 id="1-不要跳过-Brainstorming"><a href="#1-不要跳过-Brainstorming" class="headerlink" title="1. 不要跳过 Brainstorming"></a>1. 不要跳过 Brainstorming</h3><p>即使需求看起来很简单，也要走一遍设计流程。”简单”的需求往往隐藏着最容易被忽视的假设。</p><h3 id="2-信任流程，不要”灵活变通”"><a href="#2-信任流程，不要”灵活变通”" class="headerlink" title="2. 信任流程，不要”灵活变通”"></a>2. 信任流程，不要”灵活变通”</h3><p>当 AI 说”这个很简单，直接开始写吧”时，正是最容易出问题的时候。</p><h3 id="3-让-AI-解释”为什么”"><a href="#3-让-AI-解释”为什么”" class="headerlink" title="3. 让 AI 解释”为什么”"></a>3. 让 AI 解释”为什么”</h3><p>如果 AI 跳过了某个步骤，问它：”为什么不需要走 X 流程？”</p><h3 id="4-善用-Red-Flags"><a href="#4-善用-Red-Flags" class="headerlink" title="4. 善用 Red Flags"></a>4. 善用 Red Flags</h3><p>每个 Superpowers 技能都有”Red Flags”列表——当 AI 有这些想法时，说明它在试图绕过流程。</p><p>常见的 Red Flags：</p><ul><li>“只是简单问题” / “这个太简单了”</li><li>“先试试这个改动能不能修复” / “让我先试试”</li><li>“应该可以了” / “应该能工作了”</li><li>“保持这份代码作为参考”（TDD 的 Red Flag）</li></ul><h3 id="5-要求看到失败的测试"><a href="#5-要求看到失败的测试" class="headerlink" title="5. 要求看到失败的测试"></a>5. 要求看到失败的测试</h3><p>如果 AI 说”测试通过了”，但你没看到它运行测试失败的过程，要求它演示 Red-Green 循环。</p><h2 id="安装与配置"><a href="#安装与配置" class="headerlink" title="安装与配置"></a>安装与配置</h2><blockquote><p><strong>注意</strong>：不同平台安装方式不同。Claude Code 和 Cursor 有内置插件市场，Codex 和 OpenCode 需要手动配置。</p></blockquote><h3 id="Claude-Code-官方市场"><a href="#Claude-Code-官方市场" class="headerlink" title="Claude Code 官方市场"></a>Claude Code 官方市场</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/plugin install superpowers@claude-plugins-official</span><br></pre></td></tr></tbody></table></figure><h3 id="Claude-Code（通过插件市场）"><a href="#Claude-Code（通过插件市场）" class="headerlink" title="Claude Code（通过插件市场）"></a>Claude Code（通过插件市场）</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 先注册市场</span></span><br><span class="line">/plugin marketplace add obra/superpowers-marketplace</span><br><span class="line"></span><br><span class="line"><span class="comment"># 然后安装</span></span><br><span class="line">/plugin install superpowers@superpowers-marketplace</span><br></pre></td></tr></tbody></table></figure><h3 id="Cursor"><a href="#Cursor" class="headerlink" title="Cursor"></a>Cursor</h3><p>在 Cursor Agent 聊天中：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/add-plugin superpowers</span><br></pre></td></tr></tbody></table></figure><p>或在插件市场中搜索 “superpowers”。</p><h3 id="Codex"><a href="#Codex" class="headerlink" title="Codex"></a>Codex</h3><p>告诉 Codex：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md</span><br></pre></td></tr></tbody></table></figure><h3 id="OpenCode"><a href="#OpenCode" class="headerlink" title="OpenCode"></a>OpenCode</h3><p>告诉 OpenCode：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md</span><br></pre></td></tr></tbody></table></figure><h3 id="Gemini-CLI"><a href="#Gemini-CLI" class="headerlink" title="Gemini CLI"></a>Gemini CLI</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gemini extensions install https://github.com/obra/superpowers</span><br></pre></td></tr></tbody></table></figure><p>更新：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gemini extensions update superpowers</span><br></pre></td></tr></tbody></table></figure><h3 id="验证安装"><a href="#验证安装" class="headerlink" title="验证安装"></a>验证安装</h3><p>启动新会话，请求触发技能的内容（如”帮我规划这个功能”或”调试这个问题”）。代理应自动调用相关的 superpowers 技能。</p><h2 id="更新"><a href="#更新" class="headerlink" title="更新"></a>更新</h2><p>通过插件更新自动更新技能：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/plugin update superpowers</span><br></pre></td></tr></tbody></table></figure><h2 id="社区与支持"><a href="#社区与支持" class="headerlink" title="社区与支持"></a>社区与支持</h2><ul><li><strong>Discord</strong>: <a href="https://discord.gg/Jd8Vphy9jq">加入社区</a></li><li><strong>Issues</strong>: <a href="https://github.com/obra/superpowers/issues">https://github.com/obra/superpowers/issues</a></li><li><strong>Marketplace</strong>: <a href="https://github.com/obra/superpowers-marketplace">https://github.com/obra/superpowers-marketplace</a></li></ul><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Superpowers 的核心价值不在于让 AI 变得更聪明，而在于<strong>给聪明但没有纪律的 AI 一套严格的工作流程</strong>。</p><p>它的价值体现在：</p><ol><li><strong>可预测性</strong>：你知道 AI 会怎么做，不会跳过什么步骤</li><li><strong>可追溯性</strong>：每个决策都有记录，每个实现都有测试</li><li><strong>可信赖性</strong>：声称完成之前，必须有验证证据</li></ol><p>如果你曾在使用 AI 编程助手时遇到过：</p><ul><li>AI 跳过测试，结果上线后出 bug</li><li>AI”修复”了一个问题，引入了两个新问题</li><li>AI 声称”完成”，实际上漏了很多需求</li></ul><p>那么 Superpowers 可能就是你需要的——不是更好的 AI，而是更有纪律的 AI。</p><hr><p><strong>延伸阅读</strong>：</p><ul><li><a href="https://blog.fsck.com/2025/10/09/superpowers/">Superpowers for Claude Code (官方博客)</a></li><li><a href="https://github.com/obra/superpowers">GitHub 仓库</a></li><li><a href="https://www.oreilly.com/library/view/test-driven-development/0321146530/">Test-Driven Development: By Example (Kent Beck)</a></li><li><a href="https://queue.acm.org/detail.cfm?id=3068754">The Debugging Mindset</a></li></ul>]]>
    </content>
    <id>https://imwnk.cn/archives/superpowers-guide/</id>
    <link href="https://imwnk.cn/archives/superpowers-guide/"/>
    <published>2026-03-20T03:00:00.000Z</published>
    <summary>Superpowers 是一套结构化的 AI 开发技能系统，通过标准化的工作流程让 AI 助手输出更稳定、更专业的代码</summary>
    <title>Superpowers 入门指南：让 AI 助手真正成为你的编程伙伴</title>
    <updated>2026-03-20T04:12:45.629Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="recommendation" scheme="https://imwnk.cn/categories/notes/recommendation/"/>
    <category term="linux" scheme="https://imwnk.cn/tags/linux/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="witr" scheme="https://imwnk.cn/tags/witr/"/>
    <category term="devops" scheme="https://imwnk.cn/tags/devops/"/>
    <content>
      <![CDATA[<blockquote><p><strong>GitHub</strong>: <a href="https://github.com/pranshuparmar/witr">pranshuparmar/witr</a><br><strong>Stars</strong>: 14k+</p></blockquote><h2 id="为什么需要-witr？"><a href="#为什么需要-witr？" class="headerlink" title="为什么需要 witr？"></a>为什么需要 witr？</h2><p>作为运维或开发者，你是否遇到过这些问题：</p><ul><li>某个端口被占用，但不知道是哪个进程？</li><li>发现一个陌生进程在运行，想知道它是怎么被启动的？</li><li>生产环境有异常进程，需要追溯它的启动链路？</li></ul><p>传统做法是用 <code>ps</code>、<code>lsof</code>、<code>ss</code>、<code>systemctl</code> 等工具组合查询，然后手动关联信息。这个过程繁琐且容易遗漏。</p><p><strong>witr</strong> 就是为了解决这个问题而生的 —— 它能直接告诉你：<strong>这个进程是从哪里来的，是谁启动的，完整的启动链是什么</strong>。</p><hr><h2 id="witr-是什么？"><a href="#witr-是什么？" class="headerlink" title="witr 是什么？"></a>witr 是什么？</h2><p>witr 的名字来自它的核心问题：**”Why is this running?”**</p><p>它是一个用 Go 语言编写的命令行工具，能够：</p><ul><li>追踪进程的<strong>完整启动链</strong>（从 init/systemd 一直到目标进程）</li><li>按进程名、PID、端口、文件等多种方式查询</li><li>显示进程的工作目录、环境变量、监听端口等信息</li><li>提供<strong>交互式 TUI 界面</strong>，实时探索系统状态</li></ul><hr><h2 id="核心功能"><a href="#核心功能" class="headerlink" title="核心功能"></a>核心功能</h2><h3 id="1-进程启动链追踪"><a href="#1-进程启动链追踪" class="headerlink" title="1. 进程启动链追踪"></a>1. 进程启动链追踪</h3><p>最核心的功能 —— 显示一个进程是从哪里启动的：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr node</span><br></pre></td></tr></tbody></table></figure><p>输出示例：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">Target      : node</span><br><span class="line"></span><br><span class="line">Process     : node (pid 14233)</span><br><span class="line">User        : pm2</span><br><span class="line">Command     : node index.js</span><br><span class="line">Started     : 2 days ago (Mon 2025-02-02 11:42:10 +05:30)</span><br><span class="line">Restarts    : 1</span><br><span class="line"></span><br><span class="line">Why It Exists :</span><br><span class="line">  systemd (pid 1) → pm2 (pid 5034) → node (pid 14233)</span><br><span class="line"></span><br><span class="line">Source      : pm2</span><br><span class="line"></span><br><span class="line">Working Dir : /opt/apps/expense-manager</span><br><span class="line">Git Repo    : expense-manager (main)</span><br><span class="line">Listening   : 127.0.0.1:5001</span><br></pre></td></tr></tbody></table></figure><p>一目了然：这个 node 进程是由 pm2 启动的，而 pm2 又是由 systemd 管理的。</p><h3 id="2-多种查询方式"><a href="#2-多种查询方式" class="headerlink" title="2. 多种查询方式"></a>2. 多种查询方式</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 按进程名</span></span><br><span class="line">witr nginx</span><br><span class="line"></span><br><span class="line"><span class="comment"># 按 PID</span></span><br><span class="line">witr --pid 1234</span><br><span class="line"></span><br><span class="line"><span class="comment"># 按端口号</span></span><br><span class="line">witr --port 5000</span><br><span class="line"></span><br><span class="line"><span class="comment"># 按文件（找出谁在使用这个文件）</span></span><br><span class="line">witr --file /var/lib/dpkg/lock</span><br><span class="line"></span><br><span class="line"><span class="comment"># 组合查询</span></span><br><span class="line">witr nginx --port 5432 --pid 1234</span><br></pre></td></tr></tbody></table></figure><h3 id="3-树形视图"><a href="#3-树形视图" class="headerlink" title="3. 树形视图"></a>3. 树形视图</h3><p>查看进程的父子关系：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr --pid 143895 --tree</span><br></pre></td></tr></tbody></table></figure><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">systemd (pid 1)</span><br><span class="line">  └─ init-systemd (pid 2)</span><br><span class="line">    └─ SessionLeader (pid 143858)</span><br><span class="line">      └─ Relay (pid 143859)</span><br><span class="line">        └─ bash (pid 143860)</span><br><span class="line">          └─ sh (pid 143886)</span><br><span class="line">            └─ node (pid 143895)</span><br><span class="line">              ├─ node (pid 143930)</span><br><span class="line">              ├─ node (pid 144189)</span><br><span class="line">              └─ node (pid 144234)</span><br></pre></td></tr></tbody></table></figure><h3 id="4-交互式-TUI"><a href="#4-交互式-TUI" class="headerlink" title="4. 交互式 TUI"></a>4. 交互式 TUI</h3><p>直接运行 <code>witr</code> 进入交互模式：</p><ul><li>实时进程列表，支持排序和过滤</li><li>端口视图，查看端口占用</li><li>进程详情，查看完整信息</li><li>支持<strong>鼠标操作</strong></li><li>可以直接发送信号（Kill、Terminate、Pause、Resume）</li></ul><h3 id="5-JSON-输出"><a href="#5-JSON-输出" class="headerlink" title="5. JSON 输出"></a>5. JSON 输出</h3><p>方便脚本处理：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr nginx --json</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><p>witr 支持<strong>几乎所有主流安装方式</strong>：</p><h3 id="Homebrew-macOS-x2F-Linux"><a href="#Homebrew-macOS-x2F-Linux" class="headerlink" title="Homebrew (macOS/Linux)"></a>Homebrew (macOS/Linux)</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install witr</span><br></pre></td></tr></tbody></table></figure><h3 id="快速安装脚本"><a href="#快速安装脚本" class="headerlink" title="快速安装脚本"></a>快速安装脚本</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Linux/macOS/FreeBSD</span></span><br><span class="line">curl -fsSL https://raw.githubusercontent.com/pranshuparmar/witr/main/install.sh | bash</span><br><span class="line"></span><br><span class="line"><span class="comment"># Windows (PowerShell)</span></span><br><span class="line">irm https://raw.githubusercontent.com/pranshuparmar/witr/main/install.ps1 | iex</span><br></pre></td></tr></tbody></table></figure><h3 id="其他方式"><a href="#其他方式" class="headerlink" title="其他方式"></a>其他方式</h3><ul><li><strong>Conda</strong>: <code>conda install -c conda-forge witr</code></li><li><strong>Winget</strong>: <code>winget install -e --id PranshuParmar.witr</code></li><li><strong>NPM</strong>: <code>npm install -g @pranshuparmar/witr</code></li><li><strong>Arch AUR</strong>: <code>yay -S witr-bin</code></li><li><strong>Go</strong>: <code>go install github.com/pranshuparmar/witr/cmd/witr@latest</code></li></ul><hr><h2 id="实用场景"><a href="#实用场景" class="headerlink" title="实用场景"></a>实用场景</h2><h3 id="场景一：端口占用排查"><a href="#场景一：端口占用排查" class="headerlink" title="场景一：端口占用排查"></a>场景一：端口占用排查</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr --port 3000</span><br></pre></td></tr></tbody></table></figure><p>立马知道是谁在占用端口，怎么启动的。</p><h3 id="场景二：异常进程调查"><a href="#场景二：异常进程调查" class="headerlink" title="场景二：异常进程调查"></a>场景二：异常进程调查</h3><p>发现一个陌生进程名，直接查：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr strange_process</span><br></pre></td></tr></tbody></table></figure><p>看启动链就知道是哪个服务或脚本启动的。</p><h3 id="场景三：容器内进程追踪"><a href="#场景三：容器内进程追踪" class="headerlink" title="场景三：容器内进程追踪"></a>场景三：容器内进程追踪</h3><p>在容器环境中，witr 能穿透显示真实的启动来源。</p><h3 id="场景四：系统服务调试"><a href="#场景四：系统服务调试" class="headerlink" title="场景四：系统服务调试"></a>场景四：系统服务调试</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">witr --port 5432</span><br></pre></td></tr></tbody></table></figure><p>快速定位数据库服务的启动配置来源。</p><hr><h2 id="为什么推荐？"><a href="#为什么推荐？" class="headerlink" title="为什么推荐？"></a>为什么推荐？</h2><ol><li><strong>解决痛点</strong>：把分散在多个工具中的信息聚合起来，直接给出答案</li><li><strong>跨平台</strong>：支持 Linux、macOS、Windows、FreeBSD</li><li><strong>零依赖</strong>：单二进制文件，开箱即用</li><li><strong>TUI 友好</strong>：交互式界面，不熟悉命令也能用</li><li><strong>活跃维护</strong>：14k+ Stars，持续更新</li></ol><hr><h2 id="常用命令速查"><a href="#常用命令速查" class="headerlink" title="常用命令速查"></a>常用命令速查</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看进程启动链</span></span><br><span class="line">witr &lt;进程名&gt;</span><br><span class="line">witr --pid &lt;PID&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 查看端口占用</span></span><br><span class="line">witr --port &lt;端口号&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment"># 树形显示</span></span><br><span class="line">witr --tree</span><br><span class="line"></span><br><span class="line"><span class="comment"># 简洁输出（只显示链路）</span></span><br><span class="line">witr --short</span><br><span class="line"></span><br><span class="line"><span class="comment"># 交互模式</span></span><br><span class="line">witr</span><br><span class="line">witr -i</span><br><span class="line"></span><br><span class="line"><span class="comment"># 显示环境变量</span></span><br><span class="line">witr &lt;name&gt; --<span class="built_in">env</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># JSON 输出</span></span><br><span class="line">witr &lt;name&gt; --json</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>witr 是一个<strong>简单但强大的运维工具</strong>，它把”为什么这个进程在运行”这个常见但繁琐的问题，用一条命令就解决了。</p><p>如果你经常需要排查进程来源、端口占用问题，或者只是想更清晰地了解系统运行状态，witr 绝对值得加入你的工具箱。</p><hr><h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2><ul><li>GitHub: <a href="https://github.com/pranshuparmar/witr">https://github.com/pranshuparmar/witr</a></li><li>Repology（包管理器支持）: <a href="https://repology.org/project/witr/versions">https://repology.org/project/witr/versions</a></li><li>作者的故事分享: <a href="https://medium.com/@pranshu.parmar/witr-why-is-this-running-a9a97cbedd18">witr: Why is this running?</a></li></ul>]]>
    </content>
    <id>https://imwnk.cn/archives/witr-why-is-this-running/</id>
    <link href="https://imwnk.cn/archives/witr-why-is-this-running/"/>
    <published>2026-03-20T00:00:00.000Z</published>
    <summary>一款回答&quot;Why is this running?&quot;的运维神器，帮你快速追踪进程、端口、文件的启动来源</summary>
    <title>witr - 追踪进程启动链的利器</title>
    <updated>2026-03-19T14:07:33.532Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="ai" scheme="https://imwnk.cn/tags/ai/"/>
    <category term="agent" scheme="https://imwnk.cn/tags/agent/"/>
    <category term="mcp" scheme="https://imwnk.cn/tags/mcp/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <content>
      <![CDATA[<blockquote><p><strong>engram</strong> <code>/ˈen.ɡræm/</code> — <em>神经科学</em>: 大脑中记忆的物理痕迹。</p></blockquote><p>你的 AI 编码助手在会话结束后会忘记一切。Engram 给了它一个”大脑”。</p><h2 id="为什么需要-AI-Agent-记忆系统？"><a href="#为什么需要-AI-Agent-记忆系统？" class="headerlink" title="为什么需要 AI Agent 记忆系统？"></a>为什么需要 AI Agent 记忆系统？</h2><p>如果你经常使用 Claude Code、OpenCode、Cursor 等 AI 编码助手，你一定遇到过这个问题：</p><ul><li>每次新会话，AI 都要从零开始了解项目</li><li>上次修复的 bug、做的架构决策，AI 完全不记得</li><li>重复解释相同的代码上下文，浪费时间和 token</li></ul><p><strong>Engram 解决了这个问题</strong> —— 它让 AI 助手能够跨会话保存和检索记忆。</p><h2 id="Engram-是什么？"><a href="#Engram-是什么？" class="headerlink" title="Engram 是什么？"></a>Engram 是什么？</h2><p>Engram 是一个 <strong>Agent 无关</strong> 的持久化记忆系统：</p><ul><li>📦 <strong>单一二进制文件</strong> - 无需 Node.js、Python、Docker</li><li>🔍 <strong>SQLite + FTS5</strong> - 本地存储，全文搜索</li><li>🔌 <strong>MCP 协议</strong> - 兼容所有支持 MCP 的 AI 助手</li><li>🖥️ <strong>多种接口</strong> - CLI、HTTP API、MCP Server、TUI</li></ul><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">Agent (Claude Code / OpenCode / Gemini CLI / Codex / VS Code / Cursor ...)</span><br><span class="line">    ↓ MCP stdio</span><br><span class="line">Engram (单一 Go 二进制文件)</span><br><span class="line">    ↓</span><br><span class="line">SQLite + FTS5 (~/.engram/engram.db)</span><br></pre></td></tr></tbody></table></figure><h2 id="核心特性"><a href="#核心特性" class="headerlink" title="核心特性"></a>核心特性</h2><h3 id="1-Agent-无关设计"><a href="#1-Agent-无关设计" class="headerlink" title="1. Agent 无关设计"></a>1. Agent 无关设计</h3><p>支持所有 MCP 兼容的 AI 助手：</p><table><thead><tr><th>Agent</th><th>一键安装命令</th></tr></thead><tbody><tr><td>Claude Code</td><td><code>claude plugin install engram</code></td></tr><tr><td>OpenCode</td><td><code>engram setup opencode</code></td></tr><tr><td>Gemini CLI</td><td><code>engram setup gemini-cli</code></td></tr><tr><td>Codex</td><td><code>engram setup codex</code></td></tr><tr><td>VS Code</td><td><code>code --add-mcp '{"name":"engram","command":"engram","args":["mcp"]}'</code></td></tr><tr><td>Cursor / Windsurf</td><td>手动 JSON 配置</td></tr></tbody></table><h3 id="2-结构化记忆保存"><a href="#2-结构化记忆保存" class="headerlink" title="2. 结构化记忆保存"></a>2. 结构化记忆保存</h3><p>不是无脑记录所有工具调用，而是让 AI 主动保存有价值的记忆：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">1. AI 完成重要工作（bugfix、架构决策等）</span><br><span class="line">2. AI 调用 mem_save → title, type, What/Why/Where/Learned</span><br><span class="line">3. Engram 持久化到 SQLite，FTS5 索引</span><br><span class="line">4. 下次会话：AI 搜索记忆，获取相关上下文</span><br></pre></td></tr></tbody></table></figure><h3 id="3-渐进式信息检索"><a href="#3-渐进式信息检索" class="headerlink" title="3. 渐进式信息检索"></a>3. 渐进式信息检索</h3><p>Token 高效的记忆检索 —— 不要一股脑全倒出来，按需深入：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. mem_search "auth middleware"     → 紧凑结果 + ID（~100 tokens）</span><br><span class="line">2. mem_timeline observation_id=42  → 该会话前后的时间线</span><br><span class="line">3. mem_get_observation id=42       → 完整未截断内容</span><br></pre></td></tr></tbody></table></figure><h3 id="4-Git-同步"><a href="#4-Git-同步" class="headerlink" title="4. Git 同步"></a>4. Git 同步</h3><p>跨机器同步记忆，使用压缩块 —— 无合并冲突，无巨大文件：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">engram <span class="built_in">sync</span>                    <span class="comment"># 导出新记忆为压缩块</span></span><br><span class="line">git add .engram/ &amp;&amp; git commit -m <span class="string">"sync engram memories"</span></span><br><span class="line">engram <span class="built_in">sync</span> --import           <span class="comment"># 在另一台机器导入</span></span><br></pre></td></tr></tbody></table></figure><h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><h3 id="macOS-x2F-Linux-Homebrew"><a href="#macOS-x2F-Linux-Homebrew" class="headerlink" title="macOS / Linux (Homebrew)"></a>macOS / Linux (Homebrew)</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew install gentleman-programming/tap/engram</span><br></pre></td></tr></tbody></table></figure><h3 id="Windows"><a href="#Windows" class="headerlink" title="Windows"></a>Windows</h3><p>从 <a href="https://github.com/Gentleman-Programming/engram/releases">Releases</a> 下载 <code>engram-windows-amd64.exe</code></p><h3 id="从源码安装"><a href="#从源码安装" class="headerlink" title="从源码安装"></a>从源码安装</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">clone</span> https://github.com/Gentleman-Programming/engram</span><br><span class="line"><span class="built_in">cd</span> engram</span><br><span class="line">go build -o engram ./cmd/engram</span><br></pre></td></tr></tbody></table></figure><h2 id="MCP-工具一览"><a href="#MCP-工具一览" class="headerlink" title="MCP 工具一览"></a>MCP 工具一览</h2><table><thead><tr><th>工具</th><th>用途</th></tr></thead><tbody><tr><td><code>mem_save</code></td><td>保存结构化观察（决策、bugfix、模式等）</td></tr><tr><td><code>mem_update</code></td><td>按 ID 更新现有观察</td></tr><tr><td><code>mem_delete</code></td><td>删除观察（默认软删除，可选硬删除）</td></tr><tr><td><code>mem_suggest_topic_key</code></td><td>为演化主题建议稳定的 topic_key</td></tr><tr><td><code>mem_search</code></td><td>全文搜索所有记忆</td></tr><tr><td><code>mem_session_summary</code></td><td>保存会话结束摘要</td></tr><tr><td><code>mem_context</code></td><td>获取之前会话的最近上下文</td></tr><tr><td><code>mem_timeline</code></td><td>特定观察周围的 chronological 上下文</td></tr><tr><td><code>mem_get_observation</code></td><td>按 ID 获取完整内容</td></tr><tr><td><code>mem_save_prompt</code></td><td>保存用户提示</td></tr><tr><td><code>mem_stats</code></td><td>记忆系统统计</td></tr><tr><td><code>mem_session_start</code></td><td>注册会话开始</td></tr><tr><td><code>mem_session_end</code></td><td>标记会话完成</td></tr></tbody></table><h2 id="会话生命周期"><a href="#会话生命周期" class="headerlink" title="会话生命周期"></a>会话生命周期</h2><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">会话开始 → AI 工作 → AI 主动保存记忆</span><br><span class="line">                        ↓</span><br><span class="line">会话结束 → AI 写入会话摘要（Goal/Discoveries/Accomplished/Files）</span><br><span class="line">                        ↓</span><br><span class="line">下次会话开始 → 之前的会话上下文自动注入</span><br></pre></td></tr></tbody></table></figure><h2 id="记忆保存最佳实践"><a href="#记忆保存最佳实践" class="headerlink" title="记忆保存最佳实践"></a>记忆保存最佳实践</h2><h3 id="何时保存"><a href="#何时保存" class="headerlink" title="何时保存"></a>何时保存</h3><p>AI 应该在以下情况主动调用 <code>mem_save</code>：</p><ul><li>✅ <strong>Bug 修复完成</strong> - 记录问题根因和解决方案</li><li>✅ <strong>架构决策</strong> - 记录设计权衡和选择原因</li><li>✅ <strong>发现非显而易见的问题</strong> - 记录坑点和边界情况</li><li>✅ <strong>配置变更</strong> - 记录环境设置</li><li>✅ <strong>建立模式/约定</strong> - 记录命名、结构、惯例</li></ul><h3 id="记忆格式"><a href="#记忆格式" class="headerlink" title="记忆格式"></a>记忆格式</h3><p>使用结构化格式确保记忆高质量：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">**What**: [做了什么，一句话]</span><br><span class="line">**Why**: [原因，用户请求或问题驱动]</span><br><span class="line">**Where**: [影响的文件/路径]</span><br><span class="line">**Learned**: [学到的坑点、边界情况（如有）]</span><br></pre></td></tr></tbody></table></figure><p><strong>示例</strong>：</p><figure class="highlight text"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">title: "Fixed N+1 query in UserList"</span><br><span class="line">type: bugfix</span><br><span class="line">content:</span><br><span class="line">  **What**: Wrapped getUserIds() in batch query instead of per-user DB call</span><br><span class="line">  **Why**: Page load was 15s for 100 users due to N+1 queries</span><br><span class="line">  **Where**: src/services/UserList.ts — fetchUserDetails()</span><br><span class="line">  **Learned**: Always check for loops containing async DB calls</span><br></pre></td></tr></tbody></table></figure><h2 id="终端-UI"><a href="#终端-UI" class="headerlink" title="终端 UI"></a>终端 UI</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">engram tui</span><br></pre></td></tr></tbody></table></figure><p>启动交互式终端界面：</p><ul><li><strong>导航</strong>: <code>j/k</code> vim 键，<code>Enter</code> 深入，<code>/</code> 搜索，<code>Esc</code> 返回</li><li><strong>主题</strong>: Catppuccin Mocha</li><li><strong>功能</strong>: 浏览记忆、搜索、时间线视图</li></ul><h2 id="CLI-参考"><a href="#CLI-参考" class="headerlink" title="CLI 参考"></a>CLI 参考</h2><table><thead><tr><th>命令</th><th>描述</th></tr></thead><tbody><tr><td><code>engram setup [agent]</code></td><td>安装 Agent 集成</td></tr><tr><td><code>engram serve [port]</code></td><td>启动 HTTP API（默认 7437）</td></tr><tr><td><code>engram mcp</code></td><td>启动 MCP server（stdio）</td></tr><tr><td><code>engram tui</code></td><td>启动终端 UI</td></tr><tr><td><code>engram search &lt;query&gt;</code></td><td>搜索记忆</td></tr><tr><td><code>engram save &lt;title&gt; &lt;msg&gt;</code></td><td>保存记忆</td></tr><tr><td><code>engram timeline &lt;obs_id&gt;</code></td><td>时间线上下文</td></tr><tr><td><code>engram context [project]</code></td><td>最近会话上下文</td></tr><tr><td><code>engram stats</code></td><td>记忆统计</td></tr><tr><td><code>engram export [file]</code></td><td>导出为 JSON</td></tr><tr><td><code>engram import &lt;file&gt;</code></td><td>从 JSON 导入</td></tr><tr><td><code>engram sync</code></td><td>Git 同步导出</td></tr><tr><td><code>engram version</code></td><td>显示版本</td></tr></tbody></table><h2 id="与其他方案对比"><a href="#与其他方案对比" class="headerlink" title="与其他方案对比"></a>与其他方案对比</h2><table><thead><tr><th>特性</th><th>Engram</th><th>claude-mem</th></tr></thead><tbody><tr><td>Agent 支持</td><td>所有 MCP 兼容 Agent</td><td>仅 Claude Code</td></tr><tr><td>依赖</td><td>零依赖（单一二进制）</td><td>Node.js</td></tr><tr><td>存储</td><td>SQLite + FTS5</td><td>JSON 文件</td></tr><tr><td>搜索</td><td>全文搜索</td><td>关键词匹配</td></tr><tr><td>同步</td><td>Git 压缩块</td><td>手动复制</td></tr><tr><td>UI</td><td>内置 TUI</td><td>无</td></tr></tbody></table><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>Engram 解决了 AI 编码助手的”失忆”问题：</p><ol><li><strong>持久化</strong> - 会话结束，记忆不丢失</li><li><strong>可检索</strong> - FTS5 全文搜索，快速找到相关记忆</li><li><strong>跨 Agent</strong> - 一套记忆，多种 AI 助手共享</li><li><strong>零依赖</strong> - 单一二进制文件，安装即用</li><li><strong>可控</strong> - AI 主动保存，不是无脑记录</li></ol><p>如果你经常使用 AI 编码助手，Engram 绝对值得尝试。</p><hr><blockquote><p>📌 <strong>项目地址</strong>: <a href="https://github.com/Gentleman-Programming/engram">https://github.com/Gentleman-Programming/engram</a></p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/engram-ai-agent-memory/</id>
    <link href="https://imwnk.cn/archives/engram-ai-agent-memory/"/>
    <published>2026-03-19T13:40:00.000Z</published>
    <summary>Engram 是一个为 AI 编码助手设计的持久化记忆系统，单一二进制文件，零依赖，支持所有 MCP 兼容的 AI 助手</summary>
    <title>Engram - 让 AI 编码助手拥有持久记忆</title>
    <updated>2026-03-19T13:39:10.775Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="tutorial" scheme="https://imwnk.cn/categories/notes/tutorial/"/>
    <category term="tools" scheme="https://imwnk.cn/tags/tools/"/>
    <category term="ghostty" scheme="https://imwnk.cn/tags/ghostty/"/>
    <category term="terminal" scheme="https://imwnk.cn/tags/terminal/"/>
    <content>
      <![CDATA[<blockquote><p><strong>版本</strong>: 基于 Ghostty 1.2.0+ 官方文档整理<br><strong>更新时间</strong>: 2026年2月</p></blockquote><h2 id="📋-目录"><a href="#📋-目录" class="headerlink" title="📋 目录"></a>📋 目录</h2><ol><li><a href="#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E4%BD%8D%E7%BD%AE">配置文件位置</a></li><li><a href="#%E5%9F%BA%E7%A1%80%E9%85%8D%E7%BD%AE">基础配置</a></li><li><a href="#%E5%A4%96%E8%A7%82%E4%B8%BB%E9%A2%98">外观主题</a></li><li><a href="#%E5%AD%97%E4%BD%93%E8%AE%BE%E7%BD%AE">字体设置</a></li><li><a href="#%E7%AA%97%E5%8F%A3%E8%A1%8C%E4%B8%BA">窗口行为</a></li><li><a href="#%E9%94%AE%E7%9B%98%E5%BF%AB%E6%8D%B7%E9%94%AE">键盘快捷键</a></li><li><a href="#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD">高级功能</a></li><li><a href="#macos-%E4%B8%93%E5%B1%9E%E9%85%8D%E7%BD%AE">macOS 专属配置</a></li><li><a href="#linuxgtk-%E4%B8%93%E5%B1%9E%E9%85%8D%E7%BD%AE">Linux/GTK 专属配置</a></li><li><a href="#%E5%AE%9E%E7%94%A8%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8B">实用配置示例</a></li></ol><hr><h2 id="配置文件位置"><a href="#配置文件位置" class="headerlink" title="配置文件位置"></a>配置文件位置</h2><h3 id="macOS"><a href="#macOS" class="headerlink" title="macOS"></a>macOS</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">~/Library/Application Support/com.mitchellh.ghostty/config</span><br></pre></td></tr></tbody></table></figure><h3 id="Linux"><a href="#Linux" class="headerlink" title="Linux"></a>Linux</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$XDG_CONFIG_HOME/ghostty/config</span><br><span class="line"># 或</span><br><span class="line">~/.config/ghostty/config</span><br></pre></td></tr></tbody></table></figure><h3 id="配置语法说明"><a href="#配置语法说明" class="headerlink" title="配置语法说明"></a>配置语法说明</h3><ul><li>使用 <code>key = value</code> 格式</li><li><code>#</code> 开头为注释</li><li>布尔值：<code>true</code> / <code>false</code></li><li>颜色格式：<code>#RRGGBB</code> 或 X11 颜色名</li><li>支持多行配置相同选项实现 fallback</li></ul><hr><h2 id="基础配置"><a href="#基础配置" class="headerlink" title="基础配置"></a>基础配置</h2><h3 id="Shell-设置"><a href="#Shell-设置" class="headerlink" title="Shell 设置"></a>Shell 设置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 指定启动的 shell（默认自动检测）</span></span><br><span class="line"><span class="attr">command</span> = /bin/zsh</span><br><span class="line"></span><br><span class="line"><span class="comment"># 仅首次启动时使用的命令</span></span><br><span class="line"><span class="attr">initial-command</span> = /opt/homebrew/bin/fish</span><br><span class="line"></span><br><span class="line"><span class="comment"># 工作目录继承设置</span></span><br><span class="line"><span class="attr">window-inherit-working-directory</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">working-directory</span> = inherit  <span class="comment"># 可选: home, inherit, 或绝对路径</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 环境变量</span></span><br><span class="line"><span class="attr">env</span> = EDITOR=nvim</span><br><span class="line"><span class="attr">env</span> = LANG=zh_CN.UTF-<span class="number">8</span></span><br></pre></td></tr></tbody></table></figure><h3 id="滚动回滚"><a href="#滚动回滚" class="headerlink" title="滚动回滚"></a>滚动回滚</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 回滚缓冲区大小（字节），默认无限</span></span><br><span class="line"><span class="attr">scrollback-limit</span> = <span class="number">10000000</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 是否自动滚动到底部</span></span><br><span class="line"><span class="attr">scroll-to-bottom-on-input</span> = keystroke  <span class="comment"># keystroke, output, none</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="外观主题"><a href="#外观主题" class="headerlink" title="外观主题"></a>外观主题</h2><h3 id="主题选择"><a href="#主题选择" class="headerlink" title="主题选择"></a>主题选择</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 使用内置主题（运行 ghostty +list-themes 查看所有主题）</span></span><br><span class="line"><span class="attr">theme</span> = catppuccin-mocha</span><br><span class="line"></span><br><span class="line"><span class="comment"># 亮色/暗色主题分别设置</span></span><br><span class="line"><span class="attr">theme</span> = light:Rose Pine Dawn,dark:Rose Pine</span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义主题文件路径</span></span><br><span class="line"><span class="attr">theme</span> = /path/to/my-theme</span><br></pre></td></tr></tbody></table></figure><h3 id="颜色配置"><a href="#颜色配置" class="headerlink" title="颜色配置"></a>颜色配置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 前景色和背景色</span></span><br><span class="line">foreground = <span class="comment">#cdd6f4</span></span><br><span class="line">background = <span class="comment">#1e1e2e</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 透明度设置</span></span><br><span class="line"><span class="attr">background-opacity</span> = <span class="number">0.95</span>          <span class="comment"># 0-1 之间</span></span><br><span class="line"><span class="attr">background-blur</span> = <span class="literal">true</span>             <span class="comment"># 启用毛玻璃效果</span></span><br><span class="line"><span class="attr">unfocused-split-opacity</span> = <span class="number">0.8</span>      <span class="comment"># 非活动分屏透明度</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 光标颜色</span></span><br><span class="line">cursor-color = <span class="comment">#f38ba8</span></span><br><span class="line">cursor-text = <span class="comment">#1e1e2e              # 光标下文字颜色</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 选中文字颜色</span></span><br><span class="line">selection-background = <span class="comment">#353749</span></span><br><span class="line">selection-foreground = <span class="comment">#cdd6f4</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 256色调色板</span></span><br><span class="line"><span class="attr">palette</span> = <span class="number">0</span>=<span class="comment">#45475a</span></span><br><span class="line"><span class="attr">palette</span> = <span class="number">1</span>=<span class="comment">#f38ba8</span></span><br><span class="line"><span class="attr">palette</span> = <span class="number">2</span>=<span class="comment">#a6e3a1</span></span><br><span class="line"><span class="attr">palette</span> = <span class="number">3</span>=<span class="comment">#f9e2af</span></span><br><span class="line"><span class="comment"># ... 继续定义 0-255</span></span><br></pre></td></tr></tbody></table></figure><h3 id="背景图片（1-2-0-）"><a href="#背景图片（1-2-0-）" class="headerlink" title="背景图片（1.2.0+）"></a>背景图片（1.2.0+）</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">background-image</span> = /path/to/wallpaper.png</span><br><span class="line"><span class="attr">background-image-opacity</span> = <span class="number">0.3</span></span><br><span class="line"><span class="attr">background-image-position</span> = center</span><br><span class="line"><span class="attr">background-image-fit</span> = cover       <span class="comment"># contain, cover, stretch, none</span></span><br><span class="line"><span class="attr">background-image-repeat</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="字体设置"><a href="#字体设置" class="headerlink" title="字体设置"></a>字体设置</h2><h3 id="基础字体"><a href="#基础字体" class="headerlink" title="基础字体"></a>基础字体</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 主字体（可多次指定实现 fallback）</span></span><br><span class="line"><span class="attr">font-family</span> = JetBrains Mo<span class="literal">no</span></span><br><span class="line"><span class="attr">font-family</span> = Maple Mo<span class="literal">no</span>           <span class="comment"># Fallback 字体</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 特定样式字体</span></span><br><span class="line"><span class="attr">font-family-bold</span> = JetBrains Mo<span class="literal">no</span> Bold</span><br><span class="line"><span class="attr">font-family-italic</span> = JetBrains Mo<span class="literal">no</span> Italic</span><br><span class="line"><span class="attr">font-family-bold-italic</span> = JetBrains Mo<span class="literal">no</span> Bold Italic</span><br><span class="line"></span><br><span class="line"><span class="comment"># 字体大小（点）</span></span><br><span class="line"><span class="attr">font-size</span> = <span class="number">13</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 字重调整（可变字体）</span></span><br><span class="line"><span class="attr">font-variation</span> = wght=<span class="number">450</span></span><br></pre></td></tr></tbody></table></figure><h3 id="字体特性"><a href="#字体特性" class="headerlink" title="字体特性"></a>字体特性</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 禁用编程连字（如将 != 显示为 ≠）</span></span><br><span class="line"><span class="attr">font-feature</span> = -calt</span><br><span class="line"><span class="attr">font-feature</span> = -liga</span><br><span class="line"><span class="attr">font-feature</span> = -dlig</span><br><span class="line"></span><br><span class="line"><span class="comment"># 禁用合成粗体/斜体</span></span><br><span class="line"><span class="attr">font-style</span> = <span class="literal">no</span>-bold,<span class="literal">no</span>-italic</span><br><span class="line"></span><br><span class="line"><span class="comment"># 字形微调</span></span><br><span class="line"><span class="attr">adjust-cell-height</span> = <span class="number">10</span>%           <span class="comment"># 单元格高度调整</span></span><br><span class="line"><span class="attr">adjust-cell-baseline</span> = <span class="number">2</span>           <span class="comment"># 基线位置</span></span><br><span class="line"><span class="attr">adjust-underline-position</span> = <span class="number">1</span>      <span class="comment"># 下划线位置</span></span><br><span class="line"><span class="attr">adjust-underline-thickness</span> = <span class="number">1</span>     <span class="comment"># 下划线粗细</span></span><br></pre></td></tr></tbody></table></figure><h3 id="字体渲染"><a href="#字体渲染" class="headerlink" title="字体渲染"></a>字体渲染</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 抗锯齿色彩空间（macOS）</span></span><br><span class="line"><span class="attr">alpha-blending</span> = linear-corrected  <span class="comment"># native, linear, linear-corrected</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># FreeType 设置（Linux）</span></span><br><span class="line"><span class="attr">freetype-load-flags</span> = hinting,force-autohint</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="窗口行为"><a href="#窗口行为" class="headerlink" title="窗口行为"></a>窗口行为</h2><h3 id="窗口尺寸与位置"><a href="#窗口尺寸与位置" class="headerlink" title="窗口尺寸与位置"></a>窗口尺寸与位置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 初始窗口大小（字符网格）</span></span><br><span class="line"><span class="attr">window-width</span> = <span class="number">120</span></span><br><span class="line"><span class="attr">window-height</span> = <span class="number">35</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 初始窗口位置（像素，macOS 专用）</span></span><br><span class="line"><span class="attr">window-position-x</span> = <span class="number">100</span></span><br><span class="line"><span class="attr">window-position-y</span> = <span class="number">100</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 窗口内边距</span></span><br><span class="line"><span class="attr">window-padding-x</span> = <span class="number">8</span></span><br><span class="line"><span class="attr">window-padding-y</span> = <span class="number">8</span></span><br><span class="line"><span class="attr">window-padding-balance</span> = <span class="literal">true</span>      <span class="comment"># 平衡四周留白</span></span><br><span class="line"><span class="attr">window-padding-color</span> = background  <span class="comment"># background, extend, extend-always</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 全屏设置</span></span><br><span class="line"><span class="attr">fullscreen</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><h3 id="窗口装饰"><a href="#窗口装饰" class="headerlink" title="窗口装饰"></a>窗口装饰</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 标题栏样式（通用）</span></span><br><span class="line"><span class="attr">window-decoration</span> = auto           <span class="comment"># auto, client, server, none</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 标签页设置</span></span><br><span class="line"><span class="attr">tab-bar</span> = auto                     <span class="comment"># always, auto, never</span></span><br><span class="line"><span class="attr">tab-position</span> = top                 <span class="comment"># GTK 专用</span></span><br></pre></td></tr></tbody></table></figure><h3 id="窗口状态"><a href="#窗口状态" class="headerlink" title="窗口状态"></a>窗口状态</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 窗口状态保存</span></span><br><span class="line"><span class="attr">window-save-state</span> = default        <span class="comment"># default, never, always</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 新窗口继承设置</span></span><br><span class="line"><span class="attr">window-inherit-font-size</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">window-inherit-working-directory</span> = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 关闭确认</span></span><br><span class="line"><span class="attr">confirm-close-surface</span> = <span class="literal">true</span>       <span class="comment"># true, false, always</span></span><br><span class="line"><span class="attr">quit-after-last-window-closed</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="键盘快捷键"><a href="#键盘快捷键" class="headerlink" title="键盘快捷键"></a>键盘快捷键</h2><h3 id="快捷键语法"><a href="#快捷键语法" class="headerlink" title="快捷键语法"></a>快捷键语法</h3><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">keybind = &lt;trigger&gt;=&lt;action&gt;</span><br><span class="line">keybind = &lt;trigger&gt;=&lt;action&gt;:&lt;parameter&gt;</span><br></pre></td></tr></tbody></table></figure><h3 id="常用快捷键配置"><a href="#常用快捷键配置" class="headerlink" title="常用快捷键配置"></a>常用快捷键配置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 复制粘贴</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+c=copy_to_clipboard</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+v=paste_from_clipboard</span><br><span class="line"></span><br><span class="line"><span class="comment"># 新建窗口/标签页</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+n=new_window</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+t=new_tab</span><br><span class="line"></span><br><span class="line"><span class="comment"># 分屏操作</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+d=new_split:right</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+minus=new_split:down</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+w=close_surface</span><br><span class="line"></span><br><span class="line"><span class="comment"># 切换标签页</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+tab=next_tab</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+tab=previous_tab</span><br><span class="line"><span class="attr">keybind</span> = ctrl+<span class="number">1</span>=goto_tab:<span class="number">1</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+<span class="number">2</span>=goto_tab:<span class="number">2</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 缩放字体</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+plus=increase_font_size:<span class="number">1</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+minus=decrease_font_size:<span class="number">1</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+<span class="number">0</span>=reset_font_size</span><br><span class="line"></span><br><span class="line"><span class="comment"># 快速终端（Quake 模式）</span></span><br><span class="line"><span class="attr">keybind</span> = f12=toggle_quick_terminal</span><br><span class="line"></span><br><span class="line"><span class="comment"># 重新加载配置</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+r=reload_config</span><br></pre></td></tr></tbody></table></figure><h3 id="快捷键前缀修饰符"><a href="#快捷键前缀修饰符" class="headerlink" title="快捷键前缀修饰符"></a>快捷键前缀修饰符</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># global: - 全局快捷键（即使 Ghostty 未聚焦）</span></span><br><span class="line"><span class="attr">keybind</span> = global:ctrl+grave=toggle_quick_terminal</span><br><span class="line"></span><br><span class="line"><span class="comment"># all: - 应用到所有终端表面</span></span><br><span class="line"><span class="attr">keybind</span> = all:ctrl+l=clear_screen</span><br><span class="line"></span><br><span class="line"><span class="comment"># unconsumed: - 不消费输入（同时发送给程序）</span></span><br><span class="line"><span class="attr">keybind</span> = unconsumed:ctrl+a=reload_config</span><br><span class="line"></span><br><span class="line"><span class="comment"># performable: - 仅在可执行时生效</span></span><br><span class="line"><span class="attr">keybind</span> = performable:ctrl+c=copy_to_clipboard</span><br></pre></td></tr></tbody></table></figure><h3 id="序列快捷键（Leader-Key）"><a href="#序列快捷键（Leader-Key）" class="headerlink" title="序列快捷键（Leader Key）"></a>序列快捷键（Leader Key）</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 类似 Vim 的 leader key</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;n=new_tab</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;d=new_split:right</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;q=quit</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="高级功能"><a href="#高级功能" class="headerlink" title="高级功能"></a>高级功能</h2><h3 id="鼠标设置"><a href="#鼠标设置" class="headerlink" title="鼠标设置"></a>鼠标设置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 鼠标点击超时（毫秒）</span></span><br><span class="line"><span class="attr">mouse-click-timeout</span> = <span class="number">500</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 右键菜单行为</span></span><br><span class="line"><span class="attr">mouse-right-click</span> = context-menu   <span class="comment"># context-menu, paste, copy, copy-or-paste, ignore</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Shift+点击行为</span></span><br><span class="line"><span class="attr">mouse-shift-capture</span> = <span class="literal">false</span>        <span class="comment"># true, false, always, never</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 滚轮滚动倍数</span></span><br><span class="line"><span class="attr">mouse-scroll-multiplier</span> = <span class="number">3</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 选中文本自动复制</span></span><br><span class="line"><span class="attr">clipboard-read</span> = allow             <span class="comment"># ask, allow, deny</span></span><br><span class="line"><span class="attr">clipboard-write</span> = allow            <span class="comment"># ask, allow, deny</span></span><br><span class="line"><span class="attr">copy-on-select</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><h3 id="链接与高亮"><a href="#链接与高亮" class="headerlink" title="链接与高亮"></a>链接与高亮</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># URL 识别与打开</span></span><br><span class="line"><span class="attr">link-url</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">link-url-previews</span> = <span class="literal">true</span>           <span class="comment"># 显示链接预览</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义链接匹配（暂不可用）</span></span><br><span class="line"><span class="comment"># link = regex:pattern,action:open</span></span><br></pre></td></tr></tbody></table></figure><h3 id="图像协议"><a href="#图像协议" class="headerlink" title="图像协议"></a>图像协议</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Kitty 图像协议内存限制</span></span><br><span class="line"><span class="attr">image-storage-limit</span> = <span class="number">320</span>MB        <span class="comment"># 每个屏幕的最大图像数据</span></span><br></pre></td></tr></tbody></table></figure><h3 id="提示音"><a href="#提示音" class="headerlink" title="提示音"></a>提示音</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">bell-features</span> = attention,title    <span class="comment"># system, audio, attention, title, border</span></span><br><span class="line"><span class="attr">bell-audio-path</span> = /path/to/sound.wav</span><br><span class="line"><span class="attr">bell-audio-volume</span> = <span class="number">0.5</span></span><br></pre></td></tr></tbody></table></figure><h3 id="自定义着色器（GLSL）"><a href="#自定义着色器（GLSL）" class="headerlink" title="自定义着色器（GLSL）"></a>自定义着色器（GLSL）</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">custom-shader</span> = /path/to/shader.glsl</span><br><span class="line"><span class="attr">custom-shader-animation</span> = <span class="literal">true</span>     <span class="comment"># true, false, always</span></span><br></pre></td></tr></tbody></table></figure><p>着色器 Uniform 变量：</p><ul><li><code>iChannel0</code> - 终端屏幕纹理</li><li><code>iResolution</code> - 输出尺寸</li><li><code>iTime</code> / <code>iTimeDelta</code> - 时间</li><li><code>iCurrentCursor</code> - 当前光标信息</li><li><code>iPreviousCursor</code> - 上一帧光标信息</li></ul><hr><h2 id="macOS-专属配置"><a href="#macOS-专属配置" class="headerlink" title="macOS 专属配置"></a>macOS 专属配置</h2><h3 id="标题栏样式"><a href="#标题栏样式" class="headerlink" title="标题栏样式"></a>标题栏样式</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 标题栏风格</span></span><br><span class="line"><span class="attr">macos-titlebar-style</span> = transparent  <span class="comment"># native, transparent, tabs, hidden</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 窗口按钮</span></span><br><span class="line"><span class="attr">macos-titlebar-buttons</span> = visible    <span class="comment"># visible, hidden</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 代理图标（当前文件夹图标）</span></span><br><span class="line"><span class="attr">macos-titlebar-proxy-icon</span> = visible</span><br><span class="line"></span><br><span class="line"><span class="comment"># 非原生全屏</span></span><br><span class="line"><span class="attr">macos-non-native-fullscreen</span> = <span class="literal">false</span>  <span class="comment"># true, false, visible-menu, padded-notch</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 窗口阴影</span></span><br><span class="line"><span class="attr">macos-window-shadow</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Option-键行为"><a href="#Option-键行为" class="headerlink" title="Option 键行为"></a>Option 键行为</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 将 Option 视为 Alt 键</span></span><br><span class="line"><span class="attr">macos-option-as-alt</span> = <span class="literal">true</span>          <span class="comment"># true, false, left, right</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Dock-与应用切换器"><a href="#Dock-与应用切换器" class="headerlink" title="Dock 与应用切换器"></a>Dock 与应用切换器</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 隐藏 Dock 图标（适合快速终端用户）</span></span><br><span class="line"><span class="attr">macos-hidden</span> = never                <span class="comment"># never, always</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自动安全输入（密码框）</span></span><br><span class="line"><span class="attr">macos-auto-secure-input</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">macos-secure-input-indicator</span> = <span class="literal">true</span></span><br></pre></td></tr></tbody></table></figure><h3 id="应用图标自定义"><a href="#应用图标自定义" class="headerlink" title="应用图标自定义"></a>应用图标自定义</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 预设图标风格</span></span><br><span class="line"><span class="attr">macos-icon</span> = blueprint              <span class="comment"># official, blueprint, chalkboard, microchip, glass, holographic, paper, retro, xray</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 自定义样式</span></span><br><span class="line"><span class="attr">macos-icon</span> = custom-style</span><br><span class="line"><span class="attr">macos-icon-frame</span> = aluminum         <span class="comment"># aluminum, beige, plastic, chrome</span></span><br><span class="line">macos-icon-ghost-color = <span class="comment">#89b4fa</span></span><br><span class="line">macos-icon-screen-color = <span class="comment">#1e1e2e,#313244</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 完全自定义图标</span></span><br><span class="line"><span class="attr">macos-icon</span> = custom</span><br><span class="line"><span class="attr">macos-custom-icon</span> = ~/.config/ghostty/Ghostty.icns</span><br></pre></td></tr></tbody></table></figure><h3 id="快捷指令集成"><a href="#快捷指令集成" class="headerlink" title="快捷指令集成"></a>快捷指令集成</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">macos-shortcuts</span> = ask               <span class="comment"># ask, allow, deny</span></span><br></pre></td></tr></tbody></table></figure><h3 id="快速终端（Quake-模式）"><a href="#快速终端（Quake-模式）" class="headerlink" title="快速终端（Quake 模式）"></a>快速终端（Quake 模式）</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">quick-terminal-position</span> = top       <span class="comment"># top, bottom, left, right, center</span></span><br><span class="line"><span class="attr">quick-terminal-size</span> = <span class="number">50</span>%,<span class="number">100</span>%      <span class="comment"># 高度,宽度</span></span><br><span class="line"><span class="attr">quick-terminal-screen</span> = main        <span class="comment"># main, mouse, macos-menu-bar</span></span><br><span class="line"><span class="attr">quick-terminal-animation-duration</span> = <span class="number">0.2</span></span><br><span class="line"><span class="attr">quick-terminal-autohide</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">quick-terminal-space-behavior</span> = move  <span class="comment"># move, remain</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="Linux-x2F-GTK-专属配置"><a href="#Linux-x2F-GTK-专属配置" class="headerlink" title="Linux/GTK 专属配置"></a>Linux/GTK 专属配置</h2><h3 id="单实例模式"><a href="#单实例模式" class="headerlink" title="单实例模式"></a>单实例模式</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">gtk-single-instance</span> = detect        <span class="comment"># true, false, detect</span></span><br></pre></td></tr></tbody></table></figure><h3 id="标签页设置"><a href="#标签页设置" class="headerlink" title="标签页设置"></a>标签页设置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 标签页位置</span></span><br><span class="line"><span class="attr">gtk-tabs-location</span> = top             <span class="comment"># top, bottom, hidden</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 标签页样式</span></span><br><span class="line"><span class="attr">gtk-wide-tabs</span> = <span class="literal">true</span>                <span class="comment"># true, false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 最大化时隐藏标题栏</span></span><br><span class="line"><span class="attr">gtk-titlebar-hide-when-maximized</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><h3 id="标题栏样式-1"><a href="#标题栏样式-1" class="headerlink" title="标题栏样式"></a>标题栏样式</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">gtk-titlebar-style</span> = native         <span class="comment"># native, tabs</span></span><br></pre></td></tr></tbody></table></figure><h3 id="标签栏外观"><a href="#标签栏外观" class="headerlink" title="标签栏外观"></a>标签栏外观</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">gtk-adwaita-toolbar-style</span> = flat    <span class="comment"># flat, raised, raised-border</span></span><br></pre></td></tr></tbody></table></figure><h3 id="自定义-CSS"><a href="#自定义-CSS" class="headerlink" title="自定义 CSS"></a>自定义 CSS</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">gtk-css</span> = /path/to/custom.css</span><br></pre></td></tr></tbody></table></figure><h3 id="桌面通知"><a href="#桌面通知" class="headerlink" title="桌面通知"></a>桌面通知</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">gtk-desktop-notifications</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">notification</span> = clipboard-copy       <span class="comment"># clipboard-copy, config-reload</span></span><br><span class="line"><span class="attr">notification</span> = <span class="literal">no</span>-config-reload     <span class="comment"># 禁用某项</span></span><br></pre></td></tr></tbody></table></figure><h3 id="Cgroup-隔离（资源管理）"><a href="#Cgroup-隔离（资源管理）" class="headerlink" title="Cgroup 隔离（资源管理）"></a>Cgroup 隔离（资源管理）</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">linux-cgroup</span> = single-instance      <span class="comment"># never, always, single-instance</span></span><br><span class="line"><span class="attr">linux-cgroup-memory-limit</span> = <span class="number">1</span>GB</span><br><span class="line"><span class="attr">linux-cgroup-processes-limit</span> = <span class="number">100</span></span><br><span class="line"><span class="attr">linux-cgroup-hard-fail</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="实用配置示例"><a href="#实用配置示例" class="headerlink" title="实用配置示例"></a>实用配置示例</h2><h3 id="🎨-开发环境推荐配置"><a href="#🎨-开发环境推荐配置" class="headerlink" title="🎨 开发环境推荐配置"></a>🎨 开发环境推荐配置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 主题与外观</span></span><br><span class="line"><span class="attr">theme</span> = catppuccin-mocha</span><br><span class="line"><span class="attr">background-opacity</span> = <span class="number">0.95</span></span><br><span class="line"><span class="attr">background-blur</span> = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 字体</span></span><br><span class="line"><span class="attr">font-family</span> = JetBrainsMo<span class="literal">no</span> Nerd Font</span><br><span class="line"><span class="attr">font-family</span> = Maple Mo<span class="literal">no</span> CN</span><br><span class="line"><span class="attr">font-size</span> = <span class="number">13</span></span><br><span class="line"><span class="attr">font-feature</span> = -calt</span><br><span class="line"></span><br><span class="line"><span class="comment"># 窗口</span></span><br><span class="line"><span class="attr">window-padding-x</span> = <span class="number">8</span></span><br><span class="line"><span class="attr">window-padding-y</span> = <span class="number">8</span></span><br><span class="line"><span class="attr">window-width</span> = <span class="number">120</span></span><br><span class="line"><span class="attr">window-height</span> = <span class="number">35</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Shell</span></span><br><span class="line"><span class="attr">command</span> = /opt/homebrew/bin/fish</span><br><span class="line"><span class="attr">window-inherit-working-directory</span> = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 快捷键</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+t=new_tab</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+d=new_split:right</span><br><span class="line"><span class="attr">keybind</span> = ctrl+shift+minus=new_split:down</span><br><span class="line"><span class="attr">keybind</span> = f12=toggle_quick_terminal</span><br></pre></td></tr></tbody></table></figure><h3 id="🖥️-极简透明风格"><a href="#🖥️-极简透明风格" class="headerlink" title="🖥️ 极简透明风格"></a>🖥️ 极简透明风格</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 完全透明</span></span><br><span class="line"><span class="attr">theme</span> = <span class="string">""</span></span><br><span class="line">background = <span class="comment">#000000</span></span><br><span class="line"><span class="attr">background-opacity</span> = <span class="number">0.85</span></span><br><span class="line"><span class="attr">background-blur</span> = <span class="literal">true</span></span><br><span class="line"><span class="attr">window-decoration</span> = <span class="literal">false</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 无边框</span></span><br><span class="line"><span class="attr">window-padding-x</span> = <span class="number">0</span></span><br><span class="line"><span class="attr">window-padding-y</span> = <span class="number">0</span></span><br><span class="line"><span class="attr">window-padding-balance</span> = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># 细字体</span></span><br><span class="line"><span class="attr">font-family</span> = SF Mo<span class="literal">no</span></span><br><span class="line"><span class="attr">font-size</span> = <span class="number">12</span></span><br><span class="line"><span class="attr">font-thicken</span> = <span class="literal">false</span></span><br></pre></td></tr></tbody></table></figure><h3 id="⌨️-Vim-用户优化"><a href="#⌨️-Vim-用户优化" class="headerlink" title="⌨️ Vim 用户优化"></a>⌨️ Vim 用户优化</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Leader key 风格快捷键</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;n=new_tab</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;d=new_split:right</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;s=new_split:down</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;h=goto_split:left</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;j=goto_split:bottom</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;k=goto_split:top</span><br><span class="line"><span class="attr">keybind</span> = ctrl+a&gt;l=goto_split:right</span><br><span class="line"></span><br><span class="line"><span class="comment"># 禁用可能与 Vim 冲突的快捷键</span></span><br><span class="line"><span class="attr">keybind</span> = ctrl+h=unbind</span><br><span class="line"><span class="attr">keybind</span> = ctrl+j=unbind</span><br><span class="line"><span class="attr">keybind</span> = ctrl+k=unbind</span><br><span class="line"><span class="attr">keybind</span> = ctrl+l=unbind</span><br></pre></td></tr></tbody></table></figure><h3 id="🔒-安全优先配置"><a href="#🔒-安全优先配置" class="headerlink" title="🔒 安全优先配置"></a>🔒 安全优先配置</h3><figure class="highlight ini"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 禁用潜在风险功能</span></span><br><span class="line"><span class="attr">clipboard-read</span> = ask</span><br><span class="line"><span class="attr">clipboard-write</span> = ask</span><br><span class="line"><span class="attr">title-report</span> = <span class="literal">false</span></span><br><span class="line"><span class="attr">confirm-close-surface</span> = always</span><br><span class="line"></span><br><span class="line"><span class="comment"># OSC 52 剪贴板控制</span></span><br><span class="line"><span class="attr">clipboard-read</span> = deny</span><br><span class="line"><span class="attr">clipboard-write</span> = deny</span><br></pre></td></tr></tbody></table></figure><hr><h2 id="常用-CLI-命令"><a href="#常用-CLI-命令" class="headerlink" title="常用 CLI 命令"></a>常用 CLI 命令</h2><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 列出所有可用主题</span></span><br><span class="line">ghostty +list-themes</span><br><span class="line"></span><br><span class="line"><span class="comment"># 列出系统字体</span></span><br><span class="line">ghostty +list-fonts</span><br><span class="line"></span><br><span class="line"><span class="comment"># 列出所有可绑定动作</span></span><br><span class="line">ghostty +list-actions</span><br><span class="line"></span><br><span class="line"><span class="comment"># 验证配置文件</span></span><br><span class="line">ghostty +validate-config</span><br><span class="line"></span><br><span class="line"><span class="comment"># 打印最终配置</span></span><br><span class="line">ghostty +show-config</span><br><span class="line"></span><br><span class="line"><span class="comment"># 以特定配置启动</span></span><br><span class="line">ghostty --config-file=/path/to/config</span><br><span class="line"></span><br><span class="line"><span class="comment"># 临时覆盖配置启动</span></span><br><span class="line">ghostty --font-size=15 --theme=<span class="string">"Dracula"</span></span><br></pre></td></tr></tbody></table></figure><hr><h2 id="故障排除"><a href="#故障排除" class="headerlink" title="故障排除"></a>故障排除</h2><h3 id="配置热重载"><a href="#配置热重载" class="headerlink" title="配置热重载"></a>配置热重载</h3><p>修改配置文件后，使用以下方式重新加载：</p><ul><li>快捷键：<code>ctrl+shift+r</code>（如果配置了）</li><li>菜单：Ghostty → Reload Configuration</li><li>命令：<code>killall -USR1 ghostty</code></li></ul><h3 id="调试配置问题"><a href="#调试配置问题" class="headerlink" title="调试配置问题"></a>调试配置问题</h3><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 查看详细日志</span></span><br><span class="line">ghostty --log-level=debug</span><br><span class="line"></span><br><span class="line"><span class="comment"># GTK 调试模式（Linux）</span></span><br><span class="line">GTK_DEBUG=interactive ghostty</span><br></pre></td></tr></tbody></table></figure><h3 id="常见问题"><a href="#常见问题" class="headerlink" title="常见问题"></a>常见问题</h3><p><strong>Q: 字体显示模糊？</strong><br>A: 尝试调整 alpha-blending = native 或 font-thicken = true</p><p><strong>Q: 透明背景无效？</strong><br>A: 确保 background-opacity &lt; 1，某些桌面环境可能需要额外配置</p><p><strong>Q: 快捷键不生效？</strong><br>A: 检查是否有 global: 前缀需要系统权限，或使用 ghostty +list-actions 确认动作名称</p><hr><blockquote><p>💡 <strong>提示</strong>: 本文档基于 Ghostty 1.2.0 版本编写，部分功能可能需要更新版本支持。建议定期查看官方文档获取最新信息。</p></blockquote>]]>
    </content>
    <id>https://imwnk.cn/archives/ghostty-config-guide/</id>
    <link href="https://imwnk.cn/archives/ghostty-config-guide/"/>
    <published>2026-02-25T13:00:00.000Z</published>
    <summary>Ghostty 终端模拟器的完整配置指南，涵盖基础配置、外观主题、字体设置、窗口行为、键盘快捷键、高级功能等</summary>
    <title>Ghostty 终端配置完全指南</title>
    <updated>2026-03-19T13:40:19.334Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="learn" scheme="https://imwnk.cn/categories/notes/learn/"/>
    <category term="docker" scheme="https://imwnk.cn/tags/docker/"/>
    <content>
      <![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><blockquote><p><code>Dockerfile</code> 是一个用来构建镜像的文本文件，Dockerfile 由一行行命令语句组成，并且支持以 <code>#</code> 开头的注释行。一般的，<code>Dockerfile</code> 分为四部分：基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。。</p></blockquote><p>官方文档：<a href="https://docs.docker.com/engine/reference/builder/">Dockerfile reference</a></p><p>Dockerfile 示例：<a href="https://github.com/dockerfile">Dockerfile example</a></p><figure class="highlight dockerfile"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># This dockerfile uses the ubuntu image</span></span><br><span class="line"><span class="comment"># VERSION 2 - EDITION 1</span></span><br><span class="line"><span class="comment"># Author: docker_user</span></span><br><span class="line"><span class="comment"># Command format: Instruction [arguments / command] ..</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Base image to use, this must be set as the first line</span></span><br><span class="line"><span class="keyword">FROM</span> ubuntu</span><br><span class="line"></span><br><span class="line"><span class="comment"># Maintainer: docker_user &lt;docker_user at email.com&gt; (@docker_user)</span></span><br><span class="line"><span class="keyword">MAINTAINER</span> docker_user docker_user@email.com</span><br><span class="line"></span><br><span class="line"><span class="comment"># Commands to update the image</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">echo</span> <span class="string">"deb http://archive.ubuntu.com/ubuntu/ raring main universe"</span> &gt;&gt; /etc/apt/sources.list</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> apt-get update &amp;&amp; apt-get install -y nginx</span></span><br><span class="line"><span class="keyword">RUN</span><span class="language-bash"> <span class="built_in">echo</span> <span class="string">"\ndaemon off;"</span> &gt;&gt; /etc/nginx/nginx.conf</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Commands when creating a new container</span></span><br><span class="line"><span class="keyword">CMD</span><span class="language-bash"> /usr/sbin/nginx</span></span><br></pre></td></tr></tbody></table></figure><h1 id="Dockerfile-结构"><a href="#Dockerfile-结构" class="headerlink" title="Dockerfile 结构"></a><code>Dockerfile</code> 结构</h1><p><code>Dockerfile</code> 结构主要分为四部分：</p><ul><li>基础镜像信息</li><li>维护者信息</li><li>镜像操作指令</li><li>容器启动时执行指令（CMD/ENTERYPOINT）</li></ul><blockquote><p>注意：<code>Dockerfile</code> 中的指令是不区分大小写的，但是最好还是按照约定的大小写来写。每条指令可携带多个参数（不支持&amp;&amp;），支持使用以 <code>#</code> 开头的注释行。</p></blockquote><h1 id="常用-Dockerfile-指令"><a href="#常用-Dockerfile-指令" class="headerlink" title="常用 Dockerfile 指令"></a>常用 <code>Dockerfile</code> 指令</h1><ul><li><code>ARG</code> — 定义创建镜像过程中使用的变量，唯一一个可以在 <code>FROM</code> 之前使用的指令。</li><li><code>FROM</code> — 基于某个镜像，<code>FROM</code> 前只能有一个或者多个 <code>ARG</code> 指令。</li><li><code>MAINTAINER</code> — 指定维护者信息。（已弃用）。</li><li><code>VOLUME</code> — 创建一个可以从本地主机或其他容器挂载的挂载点，一般用来存放数据库和需要保持的数据等，可以在 <code>docker run</code> 时使用 <code>-v</code> 参数来挂载宿主机目录。</li><li><code>RUN</code> — 在镜像中执行命令，可以执行多条命令，每条命令都会创建一个新的镜像层，并对镜像进行提交。</li><li><code>COPY</code> — 将宿主机的文件复制到镜像中。</li><li><code>ADD</code> — 将宿主机的文件复制到镜像中，支持 <code>URL</code>。</li><li><code>ENV</code> — 设置环境变量。</li><li><code>WORKDIR</code> — 为后续的 <code>RUN</code>、<code>CMD</code>、<code>ENTRYPOINT</code> 指令配置工作目录。</li><li><code>USER</code> — 指定运行容器时的用户名或 <code>UID</code>，后续的 <code>RUN</code> 也会使用指定用户。。</li><li><code>EXPOSE</code> — 暴露端口。</li><li><code>CMD</code> — 容器启动时执行命令，只能有一个，如果有多个，只有最后一个生效。</li><li><code>ENTRYPOINT</code> — 配置容器启动时执行的命令，<code>ENTRYPOINT</code> 会被 <code>CMD</code> 覆盖。</li><li><code>HEALTHCHECK</code> — 检查容器健康状态。</li><li><code>ONBUILD</code> — 配置当所创建的镜像作为其它新创建镜像的基础镜像时，所执行的操作指令。</li><li><code>LABEL</code> — 为镜像添加元数据。</li></ul>]]>
    </content>
    <id>https://imwnk.cn/archives/docker-basic/</id>
    <link href="https://imwnk.cn/archives/docker-basic/"/>
    <published>2022-01-31T22:25:14.000Z</published>
    <summary>
      <![CDATA[<h1 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h1><blockquote>
<p><code>Dockerfile</code> 是一个用来构建镜像的文本文件，Dockerfile 由一行行命令语]]>
    </summary>
    <title>Docker 镜像构建基础</title>
    <updated>2022-09-15T22:50:19.736Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="learn" scheme="https://imwnk.cn/categories/learn/"/>
    <category term="note" scheme="https://imwnk.cn/categories/learn/note/"/>
    <category term="golang" scheme="https://imwnk.cn/tags/golang/"/>
    <category term="cgo" scheme="https://imwnk.cn/tags/cgo/"/>
    <content>
      <![CDATA[<h2 id="什么是跨平台编译？"><a href="#什么是跨平台编译？" class="headerlink" title="什么是跨平台编译？"></a>什么是跨平台编译？</h2><ul><li>跨平台编译：即交叉编译，是在一个平台上生成另一个平台上的可执行文件。所谓平台，实际上包含两个概念：体系架构(Architecture)、操作系统 (Operating System）。同一个体系架构可以运行不同的操作系统；同样，同一个操作系统也可以在不同的体系架构上运行。</li><li>静态编译：在编译可执行文件的时候，将可执行文件需要调用的对应库都集成到可执行文件内部，使得可执行文件不需要其他任何依赖就能运行。</li></ul><p>Go 实现跨平台编译的思想其实很简单：通过保存可以生成最终机器码的多份翻译代码，在编译时根据 GOARCH=xxx 和 GOOS=xxx 参数（对应体系架构和操作系统）进行初始化设置，最终调用对应平台编写的特定方法来生成机器码，从而实现跨平台编译。</p><p>有一点需要注意：Go 所谓的跨平台编译只是针对 Go 代码部分，它是 Go 的跨平台编译器（cross-compiler toolchains）。当我们使用了 CGO 时，要想实现跨平台编译，同时需要让 C/C++代码也支持跨平台。</p><p>官方 Cgo 这块目前有一篇 <a href="https://blog.golang.org/c-go-cgo">博客</a> 和 <a href="https://golang.org/cmd/cgo/">命令行文档</a>。比如 sqlite 的 golang 驱动 <a href="https://github.com/mattn/go-sqlite3">go-sqlite3</a> 就是基于 Cgo 的实现。编译本地版本，Go 本身已经支持得非常好，基本不需要额外设置，直接通过 <code>go build</code> 编译即可，但是要想编译其他平台的二进制版本，就需要跨平台的 <code>$(CC)</code>, <code>$(CXX)</code> 支持。</p><h2 id="无-CGO-项目的交叉静态编译"><a href="#无-CGO-项目的交叉静态编译" class="headerlink" title="无 CGO 项目的交叉静态编译"></a>无 CGO 项目的交叉静态编译</h2><p>在不启用 CGO 的情况下，跨平台编译是非常简单的，如下：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags <span class="string">'-s -w --extldflags "-static -fpic"'</span> main.go</span><br></pre></td></tr></tbody></table></figure><ul><li><code>CGO_ENABLED=0</code> 这个值默认是 1，也就是开启的，需要手动指定为关闭，因为 CGO 是不支持跨平台编译的，使用 <code>go env CGO_ENABLED</code> 查看默认值</li><li>GOOS, <code>GOARCH</code> 构建的平台，<code>GOOS=linux</code> 是因为安卓底层就是 linux，<code>aarch64</code> 架构直接使用 arm64，如果 <code>GOARCH=arm</code>，则要使用 <code>GOARM=7</code>，指定 arm 版本可选 5,6,7，在 <a href="https://golang.google.cn/doc/install/source#environment">这里</a> 看完整支持列表</li><li><code>-ldflags</code> 编译选项，<code>-s -w</code> 去掉调试信息，可以减小构建后文件体积，</li><li><code>--extldflags "-static -fpic"</code> 完全静态编译，要跨平台编译放到其他系统和架构中运行，建议静态编译，否则程序启动的时候会提示找不到依赖的 <code>so</code> 文件</li></ul><p>这样编译生成的程序就可以任意放到指定平台下运行。由于 CGO 的存在，跨平台会编译失败。那该如何解决呢？</p><h2 id="CGO-项目的交叉静态编译"><a href="#CGO-项目的交叉静态编译" class="headerlink" title="CGO 项目的交叉静态编译"></a>CGO 项目的交叉静态编译</h2><p>和 Go 一样，当我们拥有目标平台的 C/C++代码编译器后，自然就能够编译为目标平台的可执行文件。</p><p>不同平台的编译器 <a href="https://musl.cc/">下载地址</a></p><p>以 <code>aarch64-linux</code> 为例，下载 <code>aarch64-linux</code> 的编译器： <a href="https://musl.cc/aarch64-linux-musl-cross.tgz">https://musl.cc/aarch64-linux-musl-cross.tgz</a></p><p>解压，然后把解压好的目录下 <code>bin</code> 文件路径放到 <code>PATH</code> 环境变量中</p><p>此时，通过指定 C/C++编译器为<code>/usr/local/bin/x86_64-linux-musl-gcc</code>，替换默认的 C/C++编译器（本机编译，可通过 <code>go env CC</code> 查看），即可完成含有 CGO 的 Go 代码跨平台编译任务。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ CGO_ENABLED=1 CC=aarch64-linux-musl-gcc CXX=aarch64-linux-musl-g++ GOOS=linux GOARCH=arm64 go build -o server -ldflags <span class="string">'-s -w --extldflags "-static -fpic"'</span> main.go</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><ul><li><code>CGO_ENABLED=1</code> 开启 CGO，因为项目用到了 C 语言的代码</li><li><code>CC=aarch64-linux-musl-gcc</code> 指定 <code>gcc</code> 的编译器为 <code>aarch64-linux-musl-gcc</code>，这个默认值是 <code>gcc</code>，也就是当前操作系统和架构使用的 <code>gcc</code>，使用命令 <code>$(go env CC) --target-help</code> 可以看看默认<code> gcc</code> 支持什么平台</li><li><code>CXX=aarch64-linux-musl-g++</code> 指定 <code>g++</code> 的编译器为 <code>aarch64-linux-musl-g++</code>，规则和 <code>CC</code> 一样，只是用来编 <code>C++</code> 代码的，如果还用到了 <code>C++</code> 代码，必须指定该项</li><li><code>-ldflags '-s -w'</code> go 编译选项，<code>-s -w</code> 去掉调试信息，可以减小构建后文件体积</li></ul><p>最终，在本机系统上就编译得到了 aarch64 linux 平台的可执行文件。</p>]]>
    </content>
    <id>https://imwnk.cn/archives/cgo-compile/</id>
    <link href="https://imwnk.cn/archives/cgo-compile/"/>
    <published>2021-02-24T04:25:48.000Z</published>
    <summary>golang 跨平台编译</summary>
    <title>CGO 跨平台静态编译</title>
    <updated>2022-09-15T08:28:03.460Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="learn" scheme="https://imwnk.cn/categories/learn/"/>
    <category term="note" scheme="https://imwnk.cn/categories/learn/note/"/>
    <category term="golang" scheme="https://imwnk.cn/tags/golang/"/>
    <content>
      <![CDATA[<blockquote><p>Go 语言的优势是可以很方便地编译出跨平台的应用程序，而不需要为每一个平台做代码适配，也不像 JAVA 一样需要预先安装 JDK 环境。相应的问题就是 go 编译出的程序体积较大，和 c/c++ 不同，它将大多数依赖都以静态编译的方式编译进了程序中。为什么要缩减Golang编译后的文件大小呢？不缩减可不可以呢。正常来说一般服务器硬盘资源相对来说都比较充足，但如果类似共享设备，嵌入式设备上，硬盘资源相对来说就不是那么充足，这时就需要我们斤斤计较文件大小了。</p></blockquote><h2 id="压缩可执行文件"><a href="#压缩可执行文件" class="headerlink" title="压缩可执行文件"></a>压缩可执行文件</h2><h3 id="指定编译参数-ldflags"><a href="#指定编译参数-ldflags" class="headerlink" title="指定编译参数 -ldflags"></a>指定编译参数 <code>-ldflags</code></h3><p><code>go build</code> 编译程序时可以通过 <code>-ldflags</code> 来指定编译参数。</p><p><code>-s</code> 的作用是去掉符号信息。 <code>-w</code> 的作用是去掉调试信息。</p><p>测试加与不加 <code>-ldflags</code> 编译出的应用大小。</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">go build -o tmp/olaindex ./cmd/olaindex</span><br><span class="line">-rwxr-xr-x  1 fate  staff  33056092 Dec 10 15:49 olaindex</span><br><span class="line"></span><br><span class="line">go build -ldflags <span class="string">"-s -w"</span> -o tmp/olaindex_opt ./cmd/olaindex</span><br><span class="line">-rwxr-xr-x  1 fate  staff   14181376 Dec 10 15:49 olaindex_opt</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p><strong>减小了接近 <code>50%</code> 的体积。</strong></p><h3 id="UPX-压缩"><a href="#UPX-压缩" class="headerlink" title="UPX 压缩"></a>UPX 压缩</h3><p>UPX (the Ultimate Packer for eXecutables)是一款先进的可执行程序文件压缩器，压缩过的可执行文件体积缩小50%-70% ，这样减少了磁盘占用空间、网络上传下载的时间和其它分布以及存储费用。 通过 UPX 压缩过的程序和程序库完全没有功能损失和压缩之前一样可正常地运行，对于支持的大多数格式没有运行时间或内存的不利后果。 UPX 支持许多不同的可执行文件格式 包含 Windows 95/98/ME/NT/2000/XP/CE 程序和动态链接库、DOS 程序、 Linux 可执行文件和核心。</p><p>通过各系统的包管理工具一般可以自动安装 <code>UPX</code>。</p><p><code>-o</code> 指定压缩后的文件名。 <code>-9</code> 指定压缩级别，<code>1-9</code>。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">upx -9 -o .\tmp\olaindex_upx.exe .\cmd\olaindex_opt.exe</span><br><span class="line"></span><br><span class="line">-rwxr-xr-x  1 fate  staff   4831744 Dec 10 15:49 olaindex_upx</span><br></pre></td></tr></tbody></table></figure><p>可以看到文件又缩小了接近1/3，效果十分显著，有需要的赶紧试试吧。。</p><p>需要注意的是，UPX 可能并不能正确的压缩所有平台的程序，压缩完成后最好自行在对应平台运行测试一下。</p><p>Linux、Win 系统下 <a href="https://github.com/upx/upx/releases">UPX</a> 下载地址</p>]]>
    </content>
    <id>https://imwnk.cn/archives/reduce_golang_program_size/</id>
    <link href="https://imwnk.cn/archives/reduce_golang_program_size/"/>
    <published>2021-01-28T01:11:53.000Z</published>
    <summary>研究一下 `go build` 产生的可执行文件的压缩</summary>
    <title>减小 golang 编译出程序的体积</title>
    <updated>2022-09-15T08:28:03.462Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="learn" scheme="https://imwnk.cn/categories/notes/learn/"/>
    <category term="git" scheme="https://imwnk.cn/tags/git/"/>
    <category term="gitignore规则不生效的解决办法" scheme="https://imwnk.cn/tags/gitignore%E8%A7%84%E5%88%99%E4%B8%8D%E7%94%9F%E6%95%88%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95/"/>
    <content>
      <![CDATA[<p>在git中如果想忽略掉某个文件，不让这个文件提交到版本库中，可以使用修改根目录中 <code>.gitignore</code> 文件的方法（如无，则需手动创建此文件）。此文件每一行保存了一个匹配的规则。<br>如下：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 此为注释 将被git忽略</span></span><br><span class="line">*.a        <span class="comment"># 忽略所有.a 结尾的文件</span></span><br><span class="line">!.gitignore    <span class="comment"># 但.gitignore 除外</span></span><br><span class="line">/data <span class="comment"># 仅仅忽略项目根目录下的data文件，不包括subdir/data</span></span><br><span class="line">lib/  <span class="comment"># 忽略 lib/目录下的所有文件</span></span><br><span class="line">doc/*.txt <span class="comment"># 忽略doc/notes.txt 但不包括doc/server/arch.txt</span></span><br></pre></td></tr></tbody></table></figure><p>如果在开发过程中，发现有些文件需要加入忽略规则，按照上述方法定义后发现并未生效。</p><p>原因： <code>.gitignore</code> 只能忽略那些原来没有被track的文件，如果某些文件已经被纳入了版本管理中，则修改<br><code>.gitignore</code> 文件是无效的。</p><p>解决方法：把本地缓存删除（改变成未track状态），然后再提交：</p><figure class="highlight bash"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">git <span class="built_in">rm</span> -r --cached .</span><br><span class="line">git add .</span><br><span class="line">git commit -m <span class="string">"update .gitignore"</span></span><br></pre></td></tr></tbody></table></figure>]]>
    </content>
    <id>https://imwnk.cn/archives/handle-gitignore/</id>
    <link href="https://imwnk.cn/archives/handle-gitignore/"/>
    <published>2020-11-30T01:32:31.000Z</published>
    <summary>
      <![CDATA[<p>在git中如果想忽略掉某个文件，不让这个文件提交到版本库中，可以使用修改根目录中 <code>.gitignore</code> 文件的方法（如无，则需手动创建此文件）。此文件每一行保存了一个匹配的规则。<br>如下：</p>
<figure class="highligh]]>
    </summary>
    <title>处理.gitignore规则不生效的解决办法</title>
    <updated>2022-09-15T08:28:03.461Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="正则" scheme="https://imwnk.cn/tags/%E6%AD%A3%E5%88%99/"/>
    <category term="Vim" scheme="https://imwnk.cn/tags/Vim/"/>
    <content>
      <![CDATA[<p>总有人问我 Vim 中能不能查找，当然能！而且是超级强的查找！ 这篇文章来详细介绍 Vim 中查找相关的设置和使用方法。 包括查找与替换、查找光标所在词、高亮前景/背景色、切换高亮状态、大小写敏感查找等。</p><span id="more"></span><h2 id="查找"><a href="#查找" class="headerlink" title="查找"></a>查找</h2><p>在normal模式下按下<code>/</code>即可进入查找模式，输入要查找的字符串并按下回车。 Vim会跳转到第一个匹配。按下<code>n</code>查找下一个，按下<code>N</code>查找上一个。</p><p>Vim查找支持正则表达式，例如<code>/vim$</code>匹配行尾的<code>"vim"</code>。 需要查找特殊字符需要转义，例如<code>/vim\$</code>匹配<code>"vim$"</code>。</p><blockquote><p>注意查找回车应当用<code>\n</code>，而替换为回车应当用<code>\r</code>（相当于<code>&lt;CR&gt;</code>）。</p></blockquote><h3 id="大小写敏感查找"><a href="#大小写敏感查找" class="headerlink" title="大小写敏感查找"></a>大小写敏感查找</h3><p>在查找模式中加入<code>\c</code>表示大小写不敏感查找，<code>\C</code>表示大小写敏感查找。例如：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/foo\c</span><br></pre></td></tr></tbody></table></figure><p>将会查找所有的<code>"foo"</code>,<code>"FOO"</code>,<code>"Foo"</code>等字符串。</p><h3 id="大小写敏感配置"><a href="#大小写敏感配置" class="headerlink" title="大小写敏感配置"></a>大小写敏感配置</h3><p>Vim 默认采用大小写敏感的查找，为了方便我们常常将其配置为大小写不敏感：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">" 设置默认进行大小写不敏感查找</span><br><span class="line">set ignorecase</span><br><span class="line">" 如果有一个大写字母，则切换到大小写敏感查找</span><br><span class="line">set smartcase </span><br></pre></td></tr></tbody></table></figure><blockquote><p>将上述设置粘贴到你的<code>~/.vimrc</code>，重新打开Vim即可生效。</p></blockquote><h3 id="查找当前单词"><a href="#查找当前单词" class="headerlink" title="查找当前单词"></a>查找当前单词</h3><p>在normal模式下按下<code>*</code>即可查找光标所在单词（word）， 要求每次出现的前后为空白字符或标点符号。例如当前为<code>foo</code>， 可以匹配<code>foo bar</code>中的<code>foo</code>，但不可匹配<code>foobar</code>中的<code>foo</code>。 这在查找函数名、变量名时非常有用。</p><p>按下<code>g*</code>即可查找光标所在单词的字符序列，每次出现前后字符无要求。 即<code>foo bar</code>和<code>foobar</code>中的<code>foo</code>均可被匹配到。</p><h3 id="其他设置"><a href="#其他设置" class="headerlink" title="其他设置"></a>其他设置</h3><p><code>:set incsearch</code> 可以在敲键的同时搜索，按下回车把移动光标移动到匹配的词； 按下 Esc 取消搜索。</p><p><code>:set wrapscan</code> 用来设置到文件尾部后是否重新从文件头开始搜索。</p><h2 id="查找与替换"><a href="#查找与替换" class="headerlink" title="查找与替换"></a>查找与替换</h2><p><code>:s</code>（substitute）命令用来查找和替换字符串。语法如下：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:{作用范围}s/{目标}/{替换}/{替换标志}</span><br></pre></td></tr></tbody></table></figure><p>例如<code>:%s/foo/bar/g</code>会在全局范围(<code>%</code>)查找<code>foo</code>并替换为<code>bar</code>，所有出现都会被替换（<code>g</code>）。</p><h3 id="作用范围"><a href="#作用范围" class="headerlink" title="作用范围"></a>作用范围</h3><p>作用范围分为当前行、全文、选区等等。</p><p>当前行：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:s/foo/bar/g</span><br></pre></td></tr></tbody></table></figure><p>全文：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:%s/foo/bar/g</span><br></pre></td></tr></tbody></table></figure><p>选区，在Visual模式下选择区域后输入<code>:</code>，Vim即可自动补全为 <code>:'&lt;,'&gt;</code>。</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:'&lt;,'&gt;s/foo/bar/g</span><br></pre></td></tr></tbody></table></figure><p>2-11行：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:5,12s/foo/bar/g</span><br></pre></td></tr></tbody></table></figure><p>当前行<code>.</code>与接下来两行<code>+2</code>：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:.,+2s/foo/bar/g</span><br></pre></td></tr></tbody></table></figure><h3 id="替换标志"><a href="#替换标志" class="headerlink" title="替换标志"></a>替换标志</h3><p>上文中命令结尾的<code>g</code>即是替换标志之一，表示全局<code>global</code>替换（即替换目标的所有出现）。 还有很多其他有用的替换标志：</p><p>空替换标志表示只替换从光标位置开始，目标的第一次出现：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:%s/foo/bar</span><br></pre></td></tr></tbody></table></figure><p><code>i</code>表示大小写不敏感查找，<code>I</code>表示大小写敏感：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:%s/foo/bar/i</span><br><span class="line"># 等效于模式中的\c（不敏感）或\C（敏感）</span><br><span class="line">:%s/foo\c/bar</span><br></pre></td></tr></tbody></table></figure><p><code>c</code>表示需要确认，例如全局查找<code>"foo"</code>替换为<code>"bar"</code>并且需要确认：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">:%s/foo/bar/gc</span><br></pre></td></tr></tbody></table></figure><p>回车后Vim会将光标移动到每一次<code>"foo"</code>出现的位置，并提示</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">replace with bar (y/n/a/q/l/^E/^Y)?</span><br></pre></td></tr></tbody></table></figure><p>按下<code>y</code>表示替换，<code>n</code>表示不替换，<code>a</code>表示替换所有，<code>q</code>表示退出查找模式， <code>l</code>表示替换当前位置并退出。<code>^E</code>与<code>^Y</code>是光标移动快捷键，参考： <a href="https://harttle.land/2015/11/07/vim-cursor.html">Vim中如何快速进行光标移动</a>。</p><h2 id="高亮设置"><a href="#高亮设置" class="headerlink" title="高亮设置"></a>高亮设置</h2><h3 id="高亮颜色设置"><a href="#高亮颜色设置" class="headerlink" title="高亮颜色设置"></a>高亮颜色设置</h3><p>如果你像我一样觉得高亮的颜色不太舒服，可以在 <code>~/.vimrc</code> 中进行设置：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">highlight Search ctermbg=yellow ctermfg=black </span><br><span class="line">highlight IncSearch ctermbg=black ctermfg=yellow </span><br><span class="line">highlight MatchParen cterm=underline ctermbg=NONE ctermfg=NONE</span><br></pre></td></tr></tbody></table></figure><p>上述配置指定 Search 结果的前景色（foreground）为黑色，背景色（background）为灰色； 渐进搜索的前景色为黑色，背景色为黄色；光标处的字符加下划线。</p><blockquote><p>更多的CTERM颜色可以查阅：<a href="http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim">http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim</a></p></blockquote><h3 id="禁用-x2F-启用高亮"><a href="#禁用-x2F-启用高亮" class="headerlink" title="禁用/启用高亮"></a>禁用/启用高亮</h3><p>有木有觉得每次查找替换后 Vim 仍然高亮着搜索结果？ 可以手动让它停止高亮，在normal模式下输入：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">:nohighlight</span><br><span class="line">" 等效于</span><br><span class="line">:nohl</span><br></pre></td></tr></tbody></table></figure><p>其实上述命令禁用了所有高亮，只禁用搜索高亮的命令是<code>:set nohlsearch</code>。 下次搜索时需要<code>:set hlsearch</code>再次启动搜索高亮。</p><h4 id="延时禁用"><a href="#延时禁用" class="headerlink" title="延时禁用"></a>延时禁用</h4><p>怎么能够让Vim查找/替换后一段时间自动取消高亮，发生查找时自动开启呢？</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">" 当光标一段时间保持不动了，就禁用高亮</span><br><span class="line">autocmd cursorhold * set nohlsearch</span><br><span class="line">" 当输入查找命令时，再启用高亮</span><br><span class="line">noremap n :set hlsearch&lt;cr&gt;n</span><br><span class="line">noremap N :set hlsearch&lt;cr&gt;N</span><br><span class="line">noremap / :set hlsearch&lt;cr&gt;/</span><br><span class="line">noremap ? :set hlsearch&lt;cr&gt;?</span><br><span class="line">noremap * *:set hlsearch&lt;cr&gt;</span><br></pre></td></tr></tbody></table></figure><blockquote><p>将上述配置粘贴到<code>~/.vimrc</code>，重新打开vim即可生效。</p></blockquote><h4 id="一键禁用"><a href="#一键禁用" class="headerlink" title="一键禁用"></a>一键禁用</h4><p>如果延时禁用搜索高亮仍然不够舒服，可以设置快捷键来一键禁用/开启搜索高亮：</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">noremap n :set hlsearch&lt;cr&gt;n</span><br><span class="line">noremap N :set hlsearch&lt;cr&gt;N</span><br><span class="line">noremap / :set hlsearch&lt;cr&gt;/</span><br><span class="line">noremap ? :set hlsearch&lt;cr&gt;?</span><br><span class="line">noremap * *:set hlsearch&lt;cr&gt;</span><br><span class="line"></span><br><span class="line">nnoremap &lt;c-h&gt; :call DisableHighlight()&lt;cr&gt;</span><br><span class="line">function! DisableHighlight()</span><br><span class="line">    set nohlsearch</span><br><span class="line">endfunc</span><br></pre></td></tr></tbody></table></figure><p>希望关闭高亮时只需要按下 <code>Ctrl+H</code>，当发生下次搜索时又会自动启用。</p><h2 id="参考阅读"><a href="#参考阅读" class="headerlink" title="参考阅读"></a>参考阅读</h2><ul><li>XTERM 256色：<a href="http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim">http://vim.wikia.com/wiki/Xterm256_color_names_for_console_Vim</a></li><li>Vim Wikia - 查找与替换：<a href="http://vim.wikia.com/wiki/Search_and_replace">http://vim.wikia.com/wiki/Search_and_replace</a></li><li>用 Vim 打造 IDE 环境：<a href="https://harttle.land/2015/11/04/vim-ide.html">https://harttle.land/2015/11/04/vim-ide.html</a></li></ul><p>本文转载来源： <a href="/2016/08/08/vim-search-in-file.html">https://harttle.land/2016/08/08/vim-search-in-file.html</a></p>]]>
    </content>
    <id>https://imwnk.cn/archives/vim-search-in-file/</id>
    <link href="https://imwnk.cn/archives/vim-search-in-file/"/>
    <published>2020-08-18T18:42:16.000Z</published>
    <summary>
      <![CDATA[<p>总有人问我 Vim 中能不能查找，当然能！而且是超级强的查找！ 这篇文章来详细介绍 Vim 中查找相关的设置和使用方法。 包括查找与替换、查找光标所在词、高亮前景/背景色、切换高亮状态、大小写敏感查找等。</p>]]>
    </summary>
    <title>在 Vim 中优雅地查找和替换</title>
    <updated>2022-09-15T08:28:03.463Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="learn" scheme="https://imwnk.cn/categories/learn/"/>
    <category term="note" scheme="https://imwnk.cn/categories/learn/note/"/>
    <category term="python" scheme="https://imwnk.cn/tags/python/"/>
    <content>
      <![CDATA[<p><strong>目录[-]</strong></p><ul><li><a href="#1%E4%BD%BF%E7%94%A8os%E6%A8%A1%E5%9D%97">1.使用os模块</a></li><li><a href="#%E5%88%A4%E6%96%AD%E6%96%87%E4%BB%B6%E6%98%AF%E5%90%A6%E5%8F%AF%E5%81%9A%E8%AF%BB%E5%86%99%E6%93%8D%E4%BD%9C">判断文件是否可做读写操作</a></li><li><a href="#2%E4%BD%BF%E7%94%A8try%E8%AF%AD%E5%8F%A5">2.使用Try语句</a></li><li><a href="#3-%E4%BD%BF%E7%94%A8pathlib%E6%A8%A1%E5%9D%97">3. 使用pathlib模块</a></li></ul><p>通常在读写文件之前，需要判断文件或目录是否存在，不然某些处理方法可能会使程序出错。所以最好在做任何操作之前，先判断文件是否存在。</p><p>这里将介绍三种判断文件或文件夹是否存在的方法，分别使用<code>os模块</code>、<code>Try语句</code>、<code>pathlib模块</code>。</p><h2 id="1-使用os模块"><a href="#1-使用os模块" class="headerlink" title="1.使用os模块"></a>1.使用os模块</h2><p>os模块中的<code>os.path.exists()</code>方法用于检验文件是否存在。</p><ul><li>判断文件是否存在</li></ul><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.path.exists(test_file.txt)</span><br><span class="line"><span class="comment">#True</span></span><br><span class="line"></span><br><span class="line">os.path.exists(no_exist_file.txt)</span><br><span class="line"><span class="comment">#False</span></span><br></pre></td></tr></tbody></table></figure><ul><li>判断文件夹是否存在</li></ul><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.path.exists(test_dir)</span><br><span class="line"><span class="comment">#True</span></span><br><span class="line"></span><br><span class="line">os.path.exists(no_exist_dir)</span><br><span class="line"><span class="comment">#False</span></span><br></pre></td></tr></tbody></table></figure><p>可以看出用<code>os.path.exists()</code>方法，判断文件和文件夹是一样。</p><p>其实这种方法还是有个问题，假设你想检查文件“test_data”是否存在，但是当前路径下有个叫“test_data”的文件夹，这样就可能出现误判。为了避免这样的情况，可以这样:</p><ul><li>只检查文件</li></ul><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line">os.path.isfile(<span class="string">"test-data"</span>)</span><br></pre></td></tr></tbody></table></figure><p>通过这个方法，如果文件”test-data”不存在将返回False，反之返回True。</p><p>即是文件存在，你可能还需要判断文件是否可进行读写操作。</p><h2 id="判断文件是否可做读写操作"><a href="#判断文件是否可做读写操作" class="headerlink" title="判断文件是否可做读写操作"></a>判断文件是否可做读写操作</h2><p>使用<code>os.access()</code>方法判断文件是否可进行读写操作。</p><p>语法：</p><blockquote><p>os.access(path, mode)</p></blockquote><p>path为文件路径，mode为操作模式，有这么几种:</p><ul><li><p>os.F_OK: 检查文件是否存在;</p></li><li><p>os.R_OK: 检查文件是否可读;</p></li><li><p>os.W_OK: 检查文件是否可以写入;</p></li><li><p>os.X_OK: 检查文件是否可以执行</p></li></ul><p>该方法通过判断文件路径是否存在和各种访问模式的权限返回True或者False。</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">if</span> os.access(<span class="string">"/file/path/foo.txt"</span>, os.F_OK):</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"Given file path is exist."</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> os.access(<span class="string">"/file/path/foo.txt"</span>, os.R_OK):</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"File is accessible to read"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> os.access(<span class="string">"/file/path/foo.txt"</span>, os.W_OK):</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"File is accessible to write"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> os.access(<span class="string">"/file/path/foo.txt"</span>, os.X_OK):</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"File is accessible to execute"</span></span><br></pre></td></tr></tbody></table></figure><h2 id="2-使用Try语句"><a href="#2-使用Try语句" class="headerlink" title="2.使用Try语句"></a>2.使用Try语句</h2><p>可以在程序中直接使用<code>open()</code>方法来检查文件是否存在和可读写。</p><p>语法：</p><blockquote><p>open([HTML_REMOVED])</p></blockquote><p>如果你open的文件不存在，程序会抛出错误，使用try语句来捕获这个错误。</p><p>程序无法访问文件，可能有很多原因：</p><ul><li><p>如果你open的文件不存在，将抛出一个<code>FileNotFoundError</code>的异常;</p></li><li><p>文件存在，但是没有权限访问，会抛出一个<code>PersmissionError</code>的异常。</p></li></ul><p>所以可以使用下面的代码来判断文件是否存在:</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    f =<span class="built_in">open</span>()</span><br><span class="line">    f.close()</span><br><span class="line"><span class="keyword">except</span> FileNotFoundError:</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"File is not found."</span></span><br><span class="line"><span class="keyword">except</span> PersmissionError:</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"You don't have permission to access this file."</span></span><br></pre></td></tr></tbody></table></figure><p>其实没有必要去这么细致的处理每个异常，上面的这两个异常都是<code>IOError</code>的子类。所以可以将程序简化一下:</p><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span>:</span><br><span class="line">    f =<span class="built_in">open</span>()</span><br><span class="line">    f.close()</span><br><span class="line"><span class="keyword">except</span> IOError:</span><br><span class="line">    <span class="built_in">print</span> <span class="string">"File is not accessible."</span></span><br></pre></td></tr></tbody></table></figure><p>使用try语句进行判断，处理所有异常非常简单和优雅的。而且相比其他不需要引入其他外部模块。</p><h2 id="3-使用pathlib模块"><a href="#3-使用pathlib模块" class="headerlink" title="3. 使用pathlib模块"></a>3. 使用pathlib模块</h2><p>pathlib模块在Python3版本中是内建模块，但是在Python2中是需要单独安装三方模块。</p><p>使用pathlib需要先使用文件路径来创建path对象。此路径可以是文件名或目录路径。</p><ul><li>检查路径是否存在</li></ul><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">path = pathlib.Path(<span class="string">"path/file"</span>)</span><br><span class="line">path.exist()</span><br></pre></td></tr></tbody></table></figure><ul><li>检查路径是否是文件</li></ul><figure class="highlight python"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">path = pathlib.Path(<span class="string">"path/file"</span>)</span><br><span class="line">path.is_file()</span><br></pre></td></tr></tbody></table></figure>]]>
    </content>
    <id>https://imwnk.cn/archives/python-file-exits/</id>
    <link href="https://imwnk.cn/archives/python-file-exits/"/>
    <published>2020-08-17T22:57:53.000Z</published>
    <summary>
      <![CDATA[<p><strong>目录[-]</strong></p>
<ul>
<li><a href="#1%E4%BD%BF%E7%94%A8os%E6%A8%A1%E5%9D%97">1.使用os模块</a></li>
<li><a href="#%E5%88%A4%E6%96%AD]]>
    </summary>
    <title>Python判断文件是否存在的三种方法</title>
    <updated>2022-09-15T08:28:03.462Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="github-actions" scheme="https://imwnk.cn/tags/github-actions/"/>
    <category term="server-chan" scheme="https://imwnk.cn/tags/server-chan/"/>
    <content>
      <![CDATA[<blockquote><p>🔝 利用Github Actions 通过Serve酱自动发送微博、知乎、v2ex热门内容到微信，可配置 workflow 的触发条件为 schedule，实现周期性定时发送热门内容。</p></blockquote><h3 id="项目地址"><a href="#项目地址" class="headerlink" title="项目地址"></a>项目地址</h3><p><a href="https://github.com/WangNingkai/ServerChan-Push">ServerChan-Push</a></p><h3 id="示例"><a href="#示例" class="headerlink" title="示例"></a>示例</h3><p>clone 此 GitHub 仓库，修改.github/workflows/ 文件夹下一个 main.yml 文件，内容如下：</p><figure class="highlight yml"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">name:</span> <span class="string">'Push News'</span></span><br><span class="line"></span><br><span class="line"><span class="attr">on:</span></span><br><span class="line">  <span class="attr">push:</span></span><br><span class="line">    <span class="attr">branches:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="string">master</span></span><br><span class="line">  <span class="attr">schedule:</span></span><br><span class="line">    <span class="bullet">-</span> <span class="attr">cron:</span> <span class="string">'0 */3 * * *'</span> <span class="comment"># 定义 cron 表达式</span></span><br><span class="line">  <span class="attr">watch:</span></span><br><span class="line">    <span class="attr">types:</span> [<span class="string">started</span>] <span class="comment"># 定义star是自动发送</span></span><br><span class="line"></span><br><span class="line"><span class="attr">env:</span></span><br><span class="line">  <span class="attr">TZ:</span> <span class="string">Asia/Shanghai</span></span><br><span class="line"></span><br><span class="line"><span class="attr">jobs:</span></span><br><span class="line">  <span class="attr">Gitfolio-Spider:</span></span><br><span class="line">    <span class="attr">runs-on:</span> <span class="string">ubuntu-latest</span></span><br><span class="line">    <span class="attr">steps:</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">Checkout</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/checkout@v2</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">'Set up Python'</span></span><br><span class="line">        <span class="attr">uses:</span> <span class="string">actions/setup-python@v2</span></span><br><span class="line">        <span class="attr">with:</span></span><br><span class="line">          <span class="attr">python-version:</span> <span class="number">3.8</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">'Install dependencies'</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">python</span> <span class="string">-m</span> <span class="string">pip</span> <span class="string">install</span> <span class="string">--upgrade</span> <span class="string">pip</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">'Install requirements'</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">pip</span> <span class="string">install</span> <span class="string">-r</span> <span class="string">./requirements.txt</span></span><br><span class="line">      <span class="bullet">-</span> <span class="attr">name:</span> <span class="string">'Working'</span></span><br><span class="line">        <span class="attr">env:</span></span><br><span class="line">          <span class="attr">SECRET:</span> <span class="string">${{</span> <span class="string">secrets.SECRET</span> <span class="string">}}</span> <span class="comment"># 设置的密钥</span></span><br><span class="line">        <span class="attr">timeout-minutes:</span> <span class="number">350</span></span><br><span class="line">        <span class="attr">run:</span> <span class="string">|</span></span><br><span class="line"><span class="string">          echo SECRET=$SECRET &gt; .env</span></span><br><span class="line"><span class="string">          python main.py</span></span><br><span class="line"><span class="string">          rm -f .env</span></span><br><span class="line"><span class="string"></span></span><br></pre></td></tr></tbody></table></figure><p><strong>注意</strong></p><ul><li>cron 是 UTC 时间，使用时请将北京时间转换为 UTC 进行配置。</li><li>请在项目的 Settings -&gt; Secrets 路径下配置好SECRET(server酱密钥)，不要直接在 .yml 文件中暴露地址跟密钥</li><li>SECRET 设置为 <code>xxxxxx</code></li></ul><h3 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h3><p><img src="https://cdn.jsdelivr.net/gh/wangningkai/wangningkai/assets/20200811085352.png"></p>]]>
    </content>
    <id>https://imwnk.cn/archives/server-chan-push/</id>
    <link href="https://imwnk.cn/archives/server-chan-push/"/>
    <published>2020-08-13T19:44:16.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p>🔝 利用Github Actions 通过Serve酱自动发送微博、知乎、v2ex热门内容到微信，可配置 workflow 的触发条件为 schedule，实现周期性定时发送热门内容。</p>
</blockquote>
<h3 id="项目地址]]>
    </summary>
    <title>Serve酱定时推送热门资讯</title>
    <updated>2022-09-15T08:28:03.463Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="project" scheme="https://imwnk.cn/categories/project/"/>
    <category term="github" scheme="https://imwnk.cn/tags/github/"/>
    <category term="gitfolio" scheme="https://imwnk.cn/tags/gitfolio/"/>
    <category term="website" scheme="https://imwnk.cn/tags/website/"/>
    <content>
      <![CDATA[<p><img src="https://cdn.jsdelivr.net/gh/wangningkai/wangningkai/assets/20200726173312.png"></p><h1 id="Gitfolio-online"><a href="#Gitfolio-online" class="headerlink" title="Gitfolio-online"></a>Gitfolio-online</h1><blockquote><p><strong><a href="./README_CN.md">中文 README</a></strong></p></blockquote><h2 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h2><blockquote><p>适合每个 Github 用户的在线个人网站</p></blockquote><p>Gitfolio 将帮助你组建一个可以展示 Github 成果的网站.</p><p>点击这里查看演示 <a href="https://gitfolio-online.vercel.app/u/wangningkai">live demo</a>.</p><h2 id="特性"><a href="#特性" class="headerlink" title="特性"></a>特性</h2><ul><li>简单快捷</li><li>支持黑白主题</li><li>可定制化的</li></ul><h2 id="Getting-Started"><a href="#Getting-Started" class="headerlink" title="Getting Started"></a>Getting Started</h2><p>复制下面内容在浏览器打开!</p><p>修改 <code>username</code> 为你的 GitHub’s 用户名.</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">https://gitfolio-online.vercel.app/user/{username}?theme={theme}&amp;includeFork={includeFork}&amp;cache_seconds={cache_seconds}</span><br><span class="line">https://gitfolio-online.vercel.app/u/{username}?theme={theme}&amp;includeFork={includeFork}&amp;cache_seconds={cache_seconds}</span><br></pre></td></tr></tbody></table></figure><h4 id="主题"><a href="#主题" class="headerlink" title="主题"></a>主题</h4><p>使用 <code>?theme=THEME_NAME</code> 参数像这样 :-</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://gitfolio-online.vercel.app/u/{username}?theme=dark/light</span><br></pre></td></tr></tbody></table></figure><h4 id="引入-Forks-仓库"><a href="#引入-Forks-仓库" class="headerlink" title="引入 Forks 仓库"></a>引入 Forks 仓库</h4><p>使用 <code>?includeFork=true/false</code> 参数选择是否显示 Forks 仓库</p><figure class="highlight plaintext"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://gitfolio-online.vercel.app/u/{username}?includeFork=true/false</span><br></pre></td></tr></tbody></table></figure><h4 id="参数"><a href="#参数" class="headerlink" title="参数"></a>参数</h4><p>你可以通过以下参数自定义显示内容</p><table><thead><tr><th>Option</th><th>type</th><th>description</th><th>default</th></tr></thead><tbody><tr><td>username</td><td>string</td><td>set username</td><td>‘wangningkai’</td></tr><tr><td>theme</td><td>string</td><td>sets inbuilt theme</td><td>‘dark’</td></tr><tr><td>cache_seconds</td><td>number</td><td>manually set custom cache control</td><td>1800</td></tr><tr><td>includeFork</td><td>bool</td><td>select whether to display fork repos</td><td>false</td></tr></tbody></table><h2 id="部署到-Vercel-实例"><a href="#部署到-Vercel-实例" class="headerlink" title="部署到 Vercel 实例"></a>部署到 Vercel 实例</h2><p>因为 GitHub 的 API 每个小时只允许 5 千次请求，我的 <code>https://gitfolio-online.vercel.app/api</code> 很有可能会触发限制 如果你将其托管在自己的 Vercel 服务器上，那么你就不必为此担心。点击 deploy 按钮来开始你的部署！</p><p><a href="https://vercel.com/import/project?template=https://github.com/wangningkai/gitfolio-online"><img src="https://vercel.com/button" alt="Deploy to Vercel"></a></p><h2 id="问题反馈"><a href="#问题反馈" class="headerlink" title="问题反馈"></a>问题反馈</h2><blockquote><p>进行任何操作前请先阅读 <a href="https://github.com/ruby-china/How-To-Ask-Questions-The-Smart-Way/blob/master/README-zh_CN.md">《提问的智慧》</a></p></blockquote><p>当前获取帮助有三种方式：</p><ol><li>通过 <a href="https://github.com/WangNingkai/gitfolio-online/issues">GitHub issue</a> 提交问题（仅限问题反馈）</li><li>通过 <a href="https://imwnk.cn/">个人博客</a> 评论留言</li><li>通过个人邮箱联系 <a href="mailto:i@ningkai.wang">i@ningkai.wang</a></li></ol><h2 id="sparkling-heart-支持这个项目"><a href="#sparkling-heart-支持这个项目" class="headerlink" title=":sparkling_heart: 支持这个项目"></a><span class="github-emoji" style="display:inline;vertical-align:middle"><span>💖</span><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f496.png?v8" aria-hidden="true" onerror="this.parent.classList.add('github-emoji-fallback')"></span> 支持这个项目</h2><p>我尽己所能地进行开源，并且我尽量回复每个在使用项目时需要帮助的人。很明显，这需要时间，但你可以免费享受这些。</p><p>然而, 如果你正在使用这个项目并感觉良好，或只是想要支持我继续开发，你可以通过如下方式：</p><ul><li>Star 并 分享这个项目 <span class="github-emoji" style="display:inline;vertical-align:middle"><span>🚀</span><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f680.png?v8" aria-hidden="true" onerror="this.parent.classList.add('github-emoji-fallback')"></span></li><li><a href="https://www.paypal.me/wangningkai"><img src="https://ionicabizau.github.io/badges/paypal.svg" alt="paypal.me/wangningkai"></a> - 你可以通过 PayPal 一次性捐款. 我多半会买一杯 咖啡 茶. <span class="github-emoji" style="display:inline;vertical-align:middle"><span>🍵</span><img src="https://github.githubassets.com/images/icons/emoji/unicode/1f375.png?v8" aria-hidden="true" onerror="this.parent.classList.add('github-emoji-fallback')"></span></li><li><a href="https://pay.ningkai.wang/">Wechat &amp; AliPay</a></li></ul><p>谢谢! <span class="github-emoji" style="display:inline;vertical-align:middle"><span>❤</span><img src="https://github.githubassets.com/images/icons/emoji/unicode/2764.png?v8" aria-hidden="true" onerror="this.parent.classList.add('github-emoji-fallback')"></span></p><h2 id="License"><a href="#License" class="headerlink" title="License"></a>License</h2><p><img src="https://img.shields.io/github/license/imfunniee/gitfolio.svg?style=popout-square" alt="GitHub"></p><hr><p>欢迎贡献哦! &lt;3</p><p>Made with ❤️ and JavaScript.</p>]]>
    </content>
    <id>https://imwnk.cn/archives/gitfolio/</id>
    <link href="https://imwnk.cn/archives/gitfolio/"/>
    <published>2020-08-13T00:10:34.000Z</published>
    <summary>An online personal website for every Github user.</summary>
    <title>Gitfolio 适合每个 Github 用户的在线个人网站</title>
    <updated>2022-09-15T08:28:03.461Z</updated>
  </entry>
  <entry>
    <author>
      <name>WangNingkai</name>
    </author>
    <category term="notes" scheme="https://imwnk.cn/categories/notes/"/>
    <category term="learn" scheme="https://imwnk.cn/categories/notes/learn/"/>
    <category term="php" scheme="https://imwnk.cn/tags/php/"/>
    <content>
      <![CDATA[<blockquote><p>Trait [treɪt] 翻译过来是 “特性”、”特点” 、”特质”，是一种在 PHP 中复用代码的形式。</p></blockquote><blockquote><p>Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。Trait 为了减少单继承语言的限制，使开发人员能够自由地在不同层次结构内独立的类中复用 method。 Trait 和 Class 组合的语义定义了一种减少复杂性的方式，避免传统多继承和 Mixin 类相关典型问题。</p></blockquote><h2 id="提出"><a href="#提出" class="headerlink" title="提出"></a>提出</h2><p>为什么 PHP 会引入 Trait ? 我们先来看看软件开发中的两种常用代码复用模式，<strong>继承</strong>和<strong>组合</strong>。</p><ul><li>继承：强调 <strong>父类与子类</strong> 的关系，即子类是父类的一个特殊类型；</li><li>组合：强调 <strong>整体与局部</strong> 的关系，侧重的一种需要的关系；</li></ul><p>软件开发中有一条原则，叫做<strong>组合优于继承</strong>。这是因为<strong>从耦合度来看，继承要高于组合</strong>。继承关系中，子类与父类保持着高度的依赖关系，加上 PHP 不支持多继承，为了避免重写编写代码，很多功能都被统一封装到父类中。这样做有两个坏处：一是随着继承的层数和子类的增加，代码复杂度不断增加，大量的方法都将面临着重写；二是这些功能对于一些子类来说可能是不必要的，破坏了代码的封装性。</p><p>Trait  的提出弥补了 PHP 对组合支持的不足，一个 Trait  就相当于一个模块，不同的 Trait 以组合的方式注入到类中。我们以 Laravel 的控制器为例，来介绍下继承和组合是如何在具体的场景中使用的。</p><p>首先，<strong>底层的代码应当多使用组合</strong>。Yii 的底层Model只继承了一个简单的 ActiveRecord ，结构相对稳定。同时，Model 中使用了  <code>Trait</code> 来组织代码，避免了对象的臃肿，极大程度的保持了架构的灵活性。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title class_">common</span>\<span class="title class_">models</span>\<span class="title class_">base</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">use</span> <span class="title">Yii</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">yii</span>\<span class="title">db</span>\<span class="title">ActiveRecord</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">common</span>\<span class="title">lib</span>\<span class="title">traits</span>\<span class="title">HelperModel</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Base</span> <span class="keyword">extends</span> <span class="title">ActiveRecord</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">HelperModel</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title class_">common</span>\<span class="title class_">lib</span>\<span class="title class_">traits</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">HelperModel</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment">     * 格式化显示错误</span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> string</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">showErrors</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="variable">$errors</span> = <span class="string">''</span>;</span><br><span class="line">        <span class="keyword">foreach</span> (<span class="variable language_">$this</span>-&gt;errors <span class="keyword">as</span> <span class="variable">$v</span>) {</span><br><span class="line">            <span class="keyword">foreach</span> (<span class="variable">$v</span> <span class="keyword">as</span> <span class="variable">$v2</span>) {</span><br><span class="line">                <span class="variable">$errors</span> .= <span class="variable">$v2</span> . <span class="string">"\n"</span>;</span><br><span class="line">            }</span><br><span class="line">        }</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$errors</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 自定义时间显示</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">showCreatedAt</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_ invoke__">date</span>(<span class="string">'Y-m-d H:i:s'</span>, <span class="variable">$this</span>-&gt;created_at);</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">showUpdatedAt</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_ invoke__">date</span>(<span class="string">'Y-m-d H:i:s'</span>, <span class="variable">$this</span>-&gt;updated_at);</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">showDateTime</span>(<span class="params"><span class="variable">$time</span></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$time</span> ? <span class="title function_ invoke__">date</span>(<span class="string">'Y-m-d H:i:s'</span>, <span class="variable">$time</span>) : <span class="number">0</span>;</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">showShortDateTime</span>(<span class="params"><span class="variable">$time</span></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="keyword">return</span> <span class="variable">$time</span> ? <span class="title function_ invoke__">date</span>(<span class="string">'Y-m-d'</span>, <span class="variable">$time</span>) : <span class="number">0</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br></pre></td></tr></tbody></table></figure><p>而<strong>具体的业务逻辑或顶层代码应当多使用继承</strong>，这样能够大大提高的开发效率</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="keyword">use</span> <span class="title">common</span>\<span class="title">models</span>\<span class="title">base</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">User</span> <span class="keyword">extends</span> <span class="title">Base</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">fields</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="variable">$fields</span> = <span class="built_in">parent</span>::<span class="title function_ invoke__">fields</span>();</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_ invoke__">array_merge</span>(<span class="built_in">parent</span>::<span class="title function_ invoke__">fields</span>(), [</span><br><span class="line">        <span class="string">'created_at'</span> =&gt; function (<span class="built_in">self</span> <span class="variable">$model</span>) {</span><br><span class="line">                <span class="keyword">return</span> <span class="variable">$model</span>-&gt;<span class="title function_ invoke__">showDateTime</span>(<span class="variable">$model</span>-&gt;created_at);</span><br><span class="line">            },</span><br><span class="line">        ]);</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>以上就是继承和组合的简单介绍。接下来看看 <code>Trait</code> 的具体使用。</p><h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><h3 id="规范"><a href="#规范" class="headerlink" title="规范"></a>规范</h3><p>Symfony 编码规范建议在每个 <code>Trait</code> 之后添加 <code>Trait</code> 关键字。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">namespace</span> <span class="title class_">Symfony</span>\<span class="title class_">Contracts</span>\<span class="title class_">Translation</span>;</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">TranslatorTrait</span> </span>{</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>PSR-12 规范建议在每个 <code>Trait</code> 使用一个 <code>use</code> 语句来声明，同时 <code>Trait</code> 与类的其他成员需要保持一行空行。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">ClassName</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">FirstTrait</span>;</span><br><span class="line">    <span class="keyword">use</span> <span class="title">SecondTrait</span>;</span><br><span class="line">    <span class="keyword">use</span> <span class="title">ThirdTrait</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="variable">$a</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="成员"><a href="#成员" class="headerlink" title="成员"></a>成员</h3><p><code>Trait</code> 中可包含属性、方法 与 抽象方法，这三者的结合既可以复用代码，也可以对代码的使用作出一些约定，例如 Yii 中的自动维护 <code>fullname</code> 字段</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">namespace</span> <span class="title class_">common</span>\<span class="title class_">lib</span>\<span class="title class_">traits</span>;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">UserTrait</span> </span></span><br><span class="line"><span class="class"></span>{   </span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">fields</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function">    </span>{</span><br><span class="line">        <span class="variable">$fields</span> = <span class="built_in">parent</span>::<span class="title function_ invoke__">fields</span>();</span><br><span class="line">        <span class="keyword">return</span> <span class="title function_ invoke__">array_merge</span>(<span class="variable">$fields</span>, [</span><br><span class="line">            <span class="string">'fullname'</span> =&gt; function (<span class="built_in">self</span> <span class="variable">$model</span>) {</span><br><span class="line">                <span class="keyword">return</span> <span class="variable">$model</span>-&gt;fullname; <span class="comment">// 获取fullname字段</span></span><br><span class="line">            }</span><br><span class="line">        ]);</span><br><span class="line">    }</span><br><span class="line"></span><br><span class="line">    <span class="comment">/**</span></span><br><span class="line"><span class="comment">     * fullname 字段</span></span><br><span class="line"><span class="comment">     * </span></span><br><span class="line"><span class="comment">     * <span class="doctag">@return</span> string</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">abstract</span> <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">getFullname</span>(<span class="params"></span>): <span class="title">string</span></span>;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p><code>Trait</code> 中也可以包括静态属性和静态方法，以下是一个单例模式的简单封装。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">Singleton</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="keyword">private</span> <span class="built_in">static</span> <span class="variable">$instance</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">public</span> <span class="built_in">static</span> <span class="function"><span class="keyword">function</span> <span class="title">getInstance</span>(<span class="params"></span>) </span>{</span><br><span class="line">        <span class="keyword">if</span> (!(<span class="built_in">self</span>::<span class="variable">$instance</span> <span class="keyword">instanceof</span> <span class="built_in">self</span>)) {</span><br><span class="line">            <span class="built_in">self</span>::<span class="variable">$instance</span> = <span class="keyword">new</span> <span class="built_in">self</span>;</span><br><span class="line">        }</span><br><span class="line">        <span class="keyword">return</span> <span class="built_in">self</span>::<span class="variable">$instance</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>每个 <code>Trait</code> 中可以包含其他 <code>Trait</code>，进一步提高了代码的灵活性</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">Hello</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>) </span>{</span><br><span class="line">        <span class="keyword">echo</span> <span class="string">"Hello"</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">World</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">sayWorld</span>(<span class="params"></span>) </span>{</span><br><span class="line">        <span class="keyword">echo</span> <span class="string">"World"</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyWorld</span></span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">Hello</span>;</span><br><span class="line">    <span class="keyword">use</span> <span class="title">World</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="Trait-与类的冲突处理"><a href="#Trait-与类的冲突处理" class="headerlink" title="Trait 与类的冲突处理"></a>Trait 与类的冲突处理</h3><p>当存在同名方法时，当前类的方法会覆盖 <code>Trait</code> 中的方法，而 <code>Trait</code> 中的方法会覆盖父类的方法。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="comment">// 父类，优先级最低</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Base</span> </span>{</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>) </span>{</span><br><span class="line">        <span class="keyword">echo</span> <span class="string">'Hello '</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// Trait 优先级大于父类</span></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">SayWorld</span> </span>{</span><br><span class="line">    <span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>) </span>{</span><br><span class="line">    <span class="built_in">parent</span>::<span class="title function_ invoke__">sayHello</span>();</span><br><span class="line">        <span class="keyword">echo</span> <span class="string">'World!'</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 当前类，优先级最高</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyHelloWorld</span> <span class="keyword">extends</span> <span class="title">Base</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">SayWorld</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable">$o</span> = <span class="keyword">new</span> <span class="title class_">MyHelloWorld</span>();</span><br><span class="line"><span class="variable">$o</span>-&gt;<span class="title function_ invoke__">sayHello</span>();  <span class="comment">// Hello, World</span></span><br></pre></td></tr></tbody></table></figure><p>当存在同名属性时，类的属性<strong>必须</strong>与 <code>Trait</code> 的属性兼容（相同的访问性、相同的初始值），否则会报<strong>致命错误</strong>。</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"><span class="class"><span class="keyword">trait</span> <span class="title">Foo</span> </span>{</span><br><span class="line">    <span class="keyword">public</span> <span class="variable">$same</span> = <span class="literal">true</span>; </span><br><span class="line">    <span class="keyword">public</span> <span class="variable">$different</span> = <span class="literal">false</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Bar</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">Foo</span>;</span><br><span class="line">    <span class="keyword">public</span> <span class="variable">$same</span> = <span class="literal">true</span>; <span class="comment">// 合法</span></span><br><span class="line">    <span class="keyword">public</span> <span class="variable">$different</span> = <span class="literal">true</span>; <span class="comment">// fatal error</span></span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><h3 id="Trait-与-Trait-的冲突处理"><a href="#Trait-与-Trait-的冲突处理" class="headerlink" title="Trait 与 Trait 的冲突处理"></a>Trait 与 Trait 的冲突处理</h3><p>当一个类包含多个 <code>Trait</code> 时，不同 <code>Trait</code> 之间可能会存在属性和方法的冲突。</p><p>当存在相同属性时，属性<strong>必须</strong>兼容，跟 <code>Trait</code> 与类的冲突处理类似</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">Trait A {</span><br><span class="line"><span class="keyword">public</span> <span class="variable">$a</span> = <span class="string">'foo'</span>;</span><br><span class="line">}</span><br><span class="line">Trait B {</span><br><span class="line"><span class="keyword">public</span> <span class="variable">$a</span> = <span class="string">'foo'</span>;</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Foo</span> </span></span><br><span class="line"><span class="class"></span>{</span><br><span class="line"><span class="keyword">use</span> <span class="title">A</span>;</span><br><span class="line"><span class="keyword">use</span> <span class="title">B</span>;</span><br><span class="line">}</span><br></pre></td></tr></tbody></table></figure><p>当存在方法冲突时，需要使用 <code>insteadof</code> 来手动处理冲突，否则会报致命错误</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line">Trait A {</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="string">"A foo"</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">Trait B {</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="string">"B foo"</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Bar</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">A</span>, <span class="title">B</span> {</span><br><span class="line">    <span class="title">B</span>::<span class="title">foo</span> <span class="title">insteadof</span> <span class="title">A</span>;  <span class="comment">// 用 B 的 foo 方法来代替 A</span></span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable">$bar</span> = <span class="keyword">new</span> <span class="title class_">Bar</span>();</span><br><span class="line"><span class="keyword">echo</span> <span class="variable">$bar</span>-&gt;<span class="title function_ invoke__">foo</span>();  <span class="comment">// B foo</span></span><br></pre></td></tr></tbody></table></figure><p>这时候如果想要保留 A 的 <code>foo</code> 方法，可以用 <code>as</code> 定义别名来进行调用。注意，起别名仅仅代表可以用别名来调用该方法，仍然需要用 <code>insteadof</code> 处理冲突</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Bar</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">A</span>, <span class="title">B</span> {</span><br><span class="line">    <span class="title">B</span>::<span class="title">foo</span> <span class="title">insteadof</span> <span class="title">A</span>;  <span class="comment">// 用 B 的 foo 方法来代替 A</span></span><br><span class="line">    A::<span class="variable constant_">foo</span> <span class="keyword">as</span> aFoo; <span class="comment">// A 的  foo 方法用 aFoo 来调用</span></span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable">$bar</span> = <span class="keyword">new</span> <span class="title class_">Bar</span>();</span><br><span class="line"><span class="keyword">echo</span> <span class="variable">$bar</span>-&gt;<span class="title function_ invoke__">aFoo</span>(); <span class="comment">// A foo</span></span><br></pre></td></tr></tbody></table></figure><p><code>as</code> 关键字还可以用来更改方法法的访问控制</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line">Trait A {</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="string">"A foo"</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Bar</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">A</span> {</span><br><span class="line">    <span class="title">A</span>::<span class="title">foo</span> <span class="keyword">as</span> <span class="title">private</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable">$bar</span> = <span class="keyword">new</span> <span class="title class_">Bar</span>();</span><br><span class="line"><span class="keyword">echo</span> <span class="variable">$bar</span>-&gt;<span class="title function_ invoke__">foo</span>(); <span class="comment">// Fatal error: Uncaught Error: Call to private method Bar::foo()</span></span><br></pre></td></tr></tbody></table></figure><p>这两者可以结合起来用，这时候原有方法的访问控制就不会受到影响</p><figure class="highlight php"><table><tbody><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">&lt;?php</span></span><br><span class="line"></span><br><span class="line">Trait A {</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>)</span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">return</span> <span class="string">"A foo"</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Bar</span> </span>{</span><br><span class="line">    <span class="keyword">use</span> <span class="title">A</span> {</span><br><span class="line">    <span class="title">A</span>::<span class="title">foo</span> <span class="keyword">as</span> <span class="title">private</span> <span class="title">aFoo</span>;</span><br><span class="line">    }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="variable">$bar</span> = <span class="keyword">new</span> <span class="title class_">Bar</span>();</span><br><span class="line"><span class="keyword">echo</span> <span class="variable">$bar</span>-&gt;<span class="title function_ invoke__">foo</span>(); <span class="comment">// A foo，照常调用</span></span><br><span class="line"><span class="keyword">echo</span> <span class="variable">$bar</span>-&gt;<span class="title function_ invoke__">aFoo</span>(); <span class="comment">// 被设置成私有方法，因此报错。Fatal error: Uncaught Error: Call to private method Bar::foo()</span></span><br></pre></td></tr></tbody></table></figure><p>简单说一下 Trait 在底层的运行原理：PHP 解释器在编译代码时会把 Trait 部分代码复制粘贴到类的定义体中，但是不会处理这个操作引入的不兼容问题，他不仅降低了代码的耦合性，还提升了代码的可读性。依我看来，他不光是某种特性的集合，更像是将某个功能细化了的代码块。</p>]]>
    </content>
    <id>https://imwnk.cn/archives/php_trait/</id>
    <link href="https://imwnk.cn/archives/php_trait/"/>
    <published>2019-12-01T03:35:46.000Z</published>
    <summary>
      <![CDATA[<blockquote>
<p>Trait [treɪt] 翻译过来是 “特性”、”特点” 、”特质”，是一种在 PHP 中复用代码的形式。</p>
</blockquote>
<blockquote>
<p>Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制。T]]>
    </summary>
    <title>PHP 核心特性 - Trait</title>
    <updated>2022-09-15T08:28:03.462Z</updated>
  </entry>
</feed>
