<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Zsh on Tarragon</title><link>https://tarrragon.github.io/blog/tags/zsh/</link><description>Recent content in Zsh on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Mon, 29 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/zsh/index.xml" rel="self" type="application/rss+xml"/><item><title>Zsh 模組化配置</title><link>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/zsh-modular-config/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/zsh-modular-config/</guid><description>&lt;p>Shell 配置是 dotfile 管理裡最基礎也最常失控的一層。&lt;code>.zshrc&lt;/code> 或 &lt;code>.bashrc&lt;/code> 通常是開發者第一個開始客製的檔案，也是最容易長成數百行無結構巨檔的對象。&lt;/p>
&lt;h2 id="zsh-vs-bash-的配置檔載入順序">Zsh vs Bash 的配置檔載入順序&lt;/h2>
&lt;p>理解配置檔的載入順序是結構化拆分的前提。不知道哪個檔案在什麼時機被讀取，就無法判斷設定該放在哪。&lt;/p>
&lt;h3 id="bash-的載入順序">Bash 的載入順序&lt;/h3>
&lt;p>Bash 區分 login shell 和 non-login shell，兩者讀取的檔案不同：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Login shell&lt;/strong>（SSH 進來、&lt;code>bash --login&lt;/code>）：讀 &lt;code>~/.bash_profile&lt;/code>（如果不存在，依序嘗試 &lt;code>~/.bash_login&lt;/code> → &lt;code>~/.profile&lt;/code>）&lt;/li>
&lt;li>&lt;strong>Non-login interactive shell&lt;/strong>（開一個新終端機視窗）：讀 &lt;code>~/.bashrc&lt;/code>&lt;/li>
&lt;li>常見做法：在 &lt;code>~/.bash_profile&lt;/code> 裡 source &lt;code>~/.bashrc&lt;/code>，確保設定不管怎麼進來都一致&lt;/li>
&lt;/ul>
&lt;h3 id="zsh-的載入順序">Zsh 的載入順序&lt;/h3>
&lt;p>Zsh 的載入鏈比 Bash 更細緻：&lt;/p>
&lt;ol>
&lt;li>&lt;code>~/.zshenv&lt;/code> — 每次都讀（login、non-login、script 都會），放環境變數&lt;/li>
&lt;li>&lt;code>~/.zprofile&lt;/code> — 只有 login shell 讀，對應 Bash 的 &lt;code>~/.bash_profile&lt;/code>&lt;/li>
&lt;li>&lt;code>~/.zshrc&lt;/code> — interactive shell 讀，放 alias、function、prompt、plugin&lt;/li>
&lt;li>&lt;code>~/.zlogin&lt;/code> — login shell 在 &lt;code>.zshrc&lt;/code> 之後讀（少用）&lt;/li>
&lt;li>&lt;code>~/.zlogout&lt;/code> — logout 時讀（少用）&lt;/li>
&lt;/ol>
&lt;p>實務上 90% 的設定都進 &lt;code>.zshrc&lt;/code>，環境變數（&lt;code>PATH&lt;/code>、&lt;code>EDITOR&lt;/code>）放 &lt;code>.zshenv&lt;/code>。&lt;/p>
&lt;h2 id="結構化拆分從單一巨檔到模組化">結構化拆分：從單一巨檔到模組化&lt;/h2>
&lt;p>一個典型的失控 &lt;code>.zshrc&lt;/code> 長這樣：PATH 設定、alias、function、plugin 載入、prompt 配置、各種工具的 eval/source 全混在一起，改一個東西要在五百行裡找位置。&lt;/p>
&lt;p>模組化的目標是依職責拆檔，&lt;code>.zshrc&lt;/code> 本身只負責 source 這些模組：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># ~/.zshrc — 只做 source，不放具體設定&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="c1"># 環境變數（PATH 在 .zshenv，這裡放其他 interactive 專用的）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/env.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="c1"># Alias&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/aliases.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="c1"># Function&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/functions.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="c1"># Plugin manager&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/plugins.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl">&lt;span class="c1"># Prompt / theme&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/prompt.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl">&lt;span class="c1"># 工具整合（fzf, nvm, pyenv, etc.）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl">&lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/tools.zsh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl">&lt;span class="c1"># 機器專屬設定（不進 Git）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl">&lt;span class="o">[[&lt;/span> -f &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/local.zsh&amp;#34;&lt;/span> &lt;span class="o">]]&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.config/zsh/local.zsh&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="各模組的職責">各模組的職責&lt;/h2>
&lt;h3 id="aliaseszsh--短指令對映">aliases.zsh — 短指令對映&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 檔案操作&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">ll&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;ls -alF&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">la&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;ls -A&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="c1"># Git 常用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">gs&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;git status&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">gd&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;git diff&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">gco&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;git checkout&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> &lt;span class="nv">gp&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;git push&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">&lt;span class="c1"># 導航&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> ..&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;cd ..&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">&lt;span class="nb">alias&lt;/span> ...&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;cd ../..&amp;#39;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>判讀準則：alias 適合「不帶參數的簡單替換」。如果需要參數處理或條件判斷，改用 function。&lt;/p>
&lt;h3 id="functionszsh--帶邏輯的常用操作">functions.zsh — 帶邏輯的常用操作&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 建目錄並進入&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">mkcd&lt;span class="o">()&lt;/span> &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl"> mkdir -p &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">cd&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$1&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="c1"># 在 Git repo 根目錄搜尋&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">ggrep&lt;span class="o">()&lt;/span> &lt;span class="o">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl"> git grep &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$@&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>git rev-parse --show-toplevel&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="o">}&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="toolszsh--第三方工具的初始化">tools.zsh — 第三方工具的初始化&lt;/h3>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># fzf&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="o">[[&lt;/span> -f ~/.fzf.zsh &lt;span class="o">]]&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">source&lt;/span> ~/.fzf.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># nvm&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">NVM_DIR&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.nvm&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="o">[[&lt;/span> -s &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$NVM_DIR&lt;/span>&lt;span class="s2">/nvm.sh&amp;#34;&lt;/span> &lt;span class="o">]]&lt;/span> &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">source&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$NVM_DIR&lt;/span>&lt;span class="s2">/nvm.sh&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">&lt;span class="c1"># pyenv&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">&lt;span class="nb">command&lt;/span> -v pyenv &amp;gt;/dev/null &lt;span class="o">&amp;amp;&amp;amp;&lt;/span> &lt;span class="nb">eval&lt;/span> &lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="k">$(&lt;/span>pyenv init -&lt;span class="k">)&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>每個工具的 init 前面加存在性檢查（&lt;code>command -v&lt;/code> 或 &lt;code>[[ -f ]]&lt;/code>），避免在沒裝該工具的機器上報錯。&lt;/p></description><content:encoded><![CDATA[<p>Shell 配置是 dotfile 管理裡最基礎也最常失控的一層。<code>.zshrc</code> 或 <code>.bashrc</code> 通常是開發者第一個開始客製的檔案，也是最容易長成數百行無結構巨檔的對象。</p>
<h2 id="zsh-vs-bash-的配置檔載入順序">Zsh vs Bash 的配置檔載入順序</h2>
<p>理解配置檔的載入順序是結構化拆分的前提。不知道哪個檔案在什麼時機被讀取，就無法判斷設定該放在哪。</p>
<h3 id="bash-的載入順序">Bash 的載入順序</h3>
<p>Bash 區分 login shell 和 non-login shell，兩者讀取的檔案不同：</p>
<ul>
<li><strong>Login shell</strong>（SSH 進來、<code>bash --login</code>）：讀 <code>~/.bash_profile</code>（如果不存在，依序嘗試 <code>~/.bash_login</code> → <code>~/.profile</code>）</li>
<li><strong>Non-login interactive shell</strong>（開一個新終端機視窗）：讀 <code>~/.bashrc</code></li>
<li>常見做法：在 <code>~/.bash_profile</code> 裡 source <code>~/.bashrc</code>，確保設定不管怎麼進來都一致</li>
</ul>
<h3 id="zsh-的載入順序">Zsh 的載入順序</h3>
<p>Zsh 的載入鏈比 Bash 更細緻：</p>
<ol>
<li><code>~/.zshenv</code> — 每次都讀（login、non-login、script 都會），放環境變數</li>
<li><code>~/.zprofile</code> — 只有 login shell 讀，對應 Bash 的 <code>~/.bash_profile</code></li>
<li><code>~/.zshrc</code> — interactive shell 讀，放 alias、function、prompt、plugin</li>
<li><code>~/.zlogin</code> — login shell 在 <code>.zshrc</code> 之後讀（少用）</li>
<li><code>~/.zlogout</code> — logout 時讀（少用）</li>
</ol>
<p>實務上 90% 的設定都進 <code>.zshrc</code>，環境變數（<code>PATH</code>、<code>EDITOR</code>）放 <code>.zshenv</code>。</p>
<h2 id="結構化拆分從單一巨檔到模組化">結構化拆分：從單一巨檔到模組化</h2>
<p>一個典型的失控 <code>.zshrc</code> 長這樣：PATH 設定、alias、function、plugin 載入、prompt 配置、各種工具的 eval/source 全混在一起，改一個東西要在五百行裡找位置。</p>
<p>模組化的目標是依職責拆檔，<code>.zshrc</code> 本身只負責 source 這些模組：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># ~/.zshrc — 只做 source，不放具體設定</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"># 環境變數（PATH 在 .zshenv，這裡放其他 interactive 專用的）</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/env.zsh&#34;</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"># Alias</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/aliases.zsh&#34;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"># Function</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/functions.zsh&#34;</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"># Plugin manager</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/plugins.zsh&#34;</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1"># Prompt / theme</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/prompt.zsh&#34;</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"># 工具整合（fzf, nvm, pyenv, etc.）</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/tools.zsh&#34;</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c1"># 機器專屬設定（不進 Git）</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="o">[[</span> -f <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/local.zsh&#34;</span> <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.config/zsh/local.zsh&#34;</span></span></span></code></pre></div><h2 id="各模組的職責">各模組的職責</h2>
<h3 id="aliaseszsh--短指令對映">aliases.zsh — 短指令對映</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 檔案操作</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="nb">alias</span> <span class="nv">ll</span><span class="o">=</span><span class="s1">&#39;ls -alF&#39;</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="nb">alias</span> <span class="nv">la</span><span class="o">=</span><span class="s1">&#39;ls -A&#39;</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"># Git 常用</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="nb">alias</span> <span class="nv">gs</span><span class="o">=</span><span class="s1">&#39;git status&#39;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="nb">alias</span> <span class="nv">gd</span><span class="o">=</span><span class="s1">&#39;git diff&#39;</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="nb">alias</span> <span class="nv">gco</span><span class="o">=</span><span class="s1">&#39;git checkout&#39;</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="nb">alias</span> <span class="nv">gp</span><span class="o">=</span><span class="s1">&#39;git push&#39;</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"># 導航</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="nb">alias</span> ..<span class="o">=</span><span class="s1">&#39;cd ..&#39;</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="nb">alias</span> ...<span class="o">=</span><span class="s1">&#39;cd ../..&#39;</span></span></span></code></pre></div><p>判讀準則：alias 適合「不帶參數的簡單替換」。如果需要參數處理或條件判斷，改用 function。</p>
<h3 id="functionszsh--帶邏輯的常用操作">functions.zsh — 帶邏輯的常用操作</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 建目錄並進入</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">mkcd<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">    mkdir -p <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">cd</span> <span class="s2">&#34;</span><span class="nv">$1</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="o">}</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="c1"># 在 Git repo 根目錄搜尋</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">ggrep<span class="o">()</span> <span class="o">{</span>
</span></span><span class="line"><span class="ln">8</span><span class="cl">    git grep <span class="s2">&#34;</span><span class="nv">$@</span><span class="s2">&#34;</span> <span class="s2">&#34;</span><span class="k">$(</span>git rev-parse --show-toplevel<span class="k">)</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="o">}</span></span></span></code></pre></div><h3 id="toolszsh--第三方工具的初始化">tools.zsh — 第三方工具的初始化</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># fzf</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="o">[[</span> -f ~/.fzf.zsh <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">source</span> ~/.fzf.zsh
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># nvm</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nb">export</span> <span class="nv">NVM_DIR</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.nvm&#34;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="o">[[</span> -s <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh&#34;</span> <span class="o">]]</span> <span class="o">&amp;&amp;</span> <span class="nb">source</span> <span class="s2">&#34;</span><span class="nv">$NVM_DIR</span><span class="s2">/nvm.sh&#34;</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl">
</span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="c1"># pyenv</span>
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="nb">command</span> -v pyenv &gt;/dev/null <span class="o">&amp;&amp;</span> <span class="nb">eval</span> <span class="s2">&#34;</span><span class="k">$(</span>pyenv init -<span class="k">)</span><span class="s2">&#34;</span></span></span></code></pre></div><p>每個工具的 init 前面加存在性檢查（<code>command -v</code> 或 <code>[[ -f ]]</code>），避免在沒裝該工具的機器上報錯。</p>
<h3 id="localzsh--機器專屬不進-git">local.zsh — 機器專屬、不進 Git</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 公司 VPN 設定</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">export</span> <span class="nv">CORP_PROXY</span><span class="o">=</span><span class="s2">&#34;http://proxy.corp:8080&#34;</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 只有這台機器需要的 PATH</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/corp-tools/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span></span></span></code></pre></div><p>在 dotfile repo 的 <code>.gitignore</code> 裡排除這個檔案。<code>.zshrc</code> 裡用 <code>[[ -f ... ]] &amp;&amp; source</code> 確保不存在也不報錯。</p>
]]></content:encoded></item><item><title>PATH、Plugin 與 Prompt</title><link>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/path-plugin-prompt/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/path-plugin-prompt/</guid><description>&lt;p>PATH、plugin manager 和 prompt 是 shell 配置裡「每個開發者都會碰到、但容易放任不管」的三個區域。&lt;/p>
&lt;h2 id="path-管理">PATH 管理&lt;/h2>
&lt;p>PATH 是最容易腐化的環境變數——每裝一個工具就加一條，最後 PATH 變成一長串看不懂的路徑，順序還會互相影響。&lt;/p>
&lt;p>管理原則：&lt;/p>
&lt;ul>
&lt;li>PATH 設定集中在一個地方（&lt;code>.zshenv&lt;/code> 或 &lt;code>env.zsh&lt;/code>），不散落在多個檔案&lt;/li>
&lt;li>新增前先想：這個路徑是所有機器都需要、還是特定機器才需要？共用的進 env.zsh，特定的進 local.zsh&lt;/li>
&lt;li>用 &lt;code>typeset -U PATH&lt;/code> (Zsh) 自動去除重複項目，避免多次 source 導致 PATH 不斷加長&lt;/li>
&lt;/ul>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># ~/.config/zsh/env.zsh&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">&lt;span class="nb">typeset&lt;/span> -U PATH &lt;span class="c1"># 去重&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">&lt;span class="c1"># 自己的 script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/.local/bin:&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">&lt;span class="nb">export&lt;/span> &lt;span class="nv">PATH&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="nv">$HOME&lt;/span>&lt;span class="s2">/bin:&lt;/span>&lt;span class="nv">$PATH&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="plugin-manager-選型">Plugin Manager 選型&lt;/h2>
&lt;p>Zsh plugin manager 的選擇很多，差異主要在載入速度和功能豐富度：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>無 plugin manager&lt;/strong>：直接 git clone plugin 到某個目錄，手動 source。最簡單、最透明、但更新要自己管&lt;/li>
&lt;li>&lt;strong>zinit&lt;/strong>（原 zplugin）：載入速度最快（turbo mode 延遲載入）、功能最多、但配置語法學習曲線高&lt;/li>
&lt;li>&lt;strong>antidote&lt;/strong>：宣告式（一個 &lt;code>.zsh_plugins.txt&lt;/code> 列出所有 plugin），概念簡單&lt;/li>
&lt;li>&lt;strong>sheldon&lt;/strong>：Rust 寫的、速度快、設定用 TOML&lt;/li>
&lt;/ul>
&lt;p>常用 plugin：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>zsh-autosuggestions&lt;/strong>：根據歷史指令自動補全建議（灰色字，按右箭頭接受）&lt;/li>
&lt;li>&lt;strong>zsh-syntax-highlighting&lt;/strong>：指令行即時語法高亮&lt;/li>
&lt;li>&lt;strong>zsh-completions&lt;/strong>：額外的 tab 補全定義&lt;/li>
&lt;/ul>
&lt;h2 id="prompt-設計">Prompt 設計&lt;/h2>
&lt;p>Prompt 是每次按 Enter 都會看到的東西，值得花時間設計但不需要複雜。&lt;/p>
&lt;p>基本款（不用框架）：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">&lt;span class="c1"># 顯示目錄 + git branch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">autoload -Uz vcs_info
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">precmd&lt;span class="o">()&lt;/span> &lt;span class="o">{&lt;/span> vcs_info &lt;span class="o">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">zstyle &lt;span class="s1">&amp;#39;:vcs_info:git:*&amp;#39;&lt;/span> formats &lt;span class="s1">&amp;#39; (%b)&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">&lt;span class="nv">PROMPT&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;%F{blue}%~%f%F{green}${vcs_info_msg_0_}%f %# &amp;#39;&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>框架款：Starship（跨 shell、用 TOML 設定、Rust 寫的速度快）是目前最常被推薦的 prompt 工具。它的配置進 &lt;code>~/.config/starship.toml&lt;/code>，也是 dotfile 的一部分。&lt;/p>
&lt;h2 id="dotfile-結構對應">Dotfile 結構對應&lt;/h2>
&lt;p>&lt;a href="https://tarrragon.github.io/blog/linux/dotfile/01-dotfile-management/" data-link-title="模組一：管理工具與目錄結構" data-link-desc="要把散落在家目錄的配置檔集中版控時，選 bare repo、stow 還是 chezmoi、目錄該怎麼組織">管理工具與目錄結構&lt;/a>裡的 stow 目錄結構，shell 配置的對應：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">~/dotfiles/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">└── zsh/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> ├── .zshenv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl"> ├── .zshrc
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> └── .config/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> └── zsh/
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl"> ├── aliases.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> ├── functions.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> ├── plugins.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl"> ├── prompt.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> ├── tools.zsh
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> └── env.zsh&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>stow zsh&lt;/code> 會在家目錄建立 &lt;code>.zshenv&lt;/code> 和 &lt;code>.zshrc&lt;/code> 的 symlink，在 &lt;code>.config/zsh/&lt;/code> 下建立各模組檔案的 symlink。&lt;code>local.zsh&lt;/code> 不在 repo 裡，各機器自己建。&lt;/p></description><content:encoded><![CDATA[<p>PATH、plugin manager 和 prompt 是 shell 配置裡「每個開發者都會碰到、但容易放任不管」的三個區域。</p>
<h2 id="path-管理">PATH 管理</h2>
<p>PATH 是最容易腐化的環境變數——每裝一個工具就加一條，最後 PATH 變成一長串看不懂的路徑，順序還會互相影響。</p>
<p>管理原則：</p>
<ul>
<li>PATH 設定集中在一個地方（<code>.zshenv</code> 或 <code>env.zsh</code>），不散落在多個檔案</li>
<li>新增前先想：這個路徑是所有機器都需要、還是特定機器才需要？共用的進 env.zsh，特定的進 local.zsh</li>
<li>用 <code>typeset -U PATH</code> (Zsh) 自動去除重複項目，避免多次 source 導致 PATH 不斷加長</li>
</ul>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># ~/.config/zsh/env.zsh</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="nb">typeset</span> -U PATH  <span class="c1"># 去重</span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 自己的 script</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/.local/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="nb">export</span> <span class="nv">PATH</span><span class="o">=</span><span class="s2">&#34;</span><span class="nv">$HOME</span><span class="s2">/bin:</span><span class="nv">$PATH</span><span class="s2">&#34;</span></span></span></code></pre></div><h2 id="plugin-manager-選型">Plugin Manager 選型</h2>
<p>Zsh plugin manager 的選擇很多，差異主要在載入速度和功能豐富度：</p>
<ul>
<li><strong>無 plugin manager</strong>：直接 git clone plugin 到某個目錄，手動 source。最簡單、最透明、但更新要自己管</li>
<li><strong>zinit</strong>（原 zplugin）：載入速度最快（turbo mode 延遲載入）、功能最多、但配置語法學習曲線高</li>
<li><strong>antidote</strong>：宣告式（一個 <code>.zsh_plugins.txt</code> 列出所有 plugin），概念簡單</li>
<li><strong>sheldon</strong>：Rust 寫的、速度快、設定用 TOML</li>
</ul>
<p>常用 plugin：</p>
<ul>
<li><strong>zsh-autosuggestions</strong>：根據歷史指令自動補全建議（灰色字，按右箭頭接受）</li>
<li><strong>zsh-syntax-highlighting</strong>：指令行即時語法高亮</li>
<li><strong>zsh-completions</strong>：額外的 tab 補全定義</li>
</ul>
<h2 id="prompt-設計">Prompt 設計</h2>
<p>Prompt 是每次按 Enter 都會看到的東西，值得花時間設計但不需要複雜。</p>
<p>基本款（不用框架）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 顯示目錄 + git branch</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">autoload -Uz vcs_info
</span></span><span class="line"><span class="ln">3</span><span class="cl">precmd<span class="o">()</span> <span class="o">{</span> vcs_info <span class="o">}</span>
</span></span><span class="line"><span class="ln">4</span><span class="cl">zstyle <span class="s1">&#39;:vcs_info:git:*&#39;</span> formats <span class="s1">&#39; (%b)&#39;</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="nv">PROMPT</span><span class="o">=</span><span class="s1">&#39;%F{blue}%~%f%F{green}${vcs_info_msg_0_}%f %# &#39;</span></span></span></code></pre></div><p>框架款：Starship（跨 shell、用 TOML 設定、Rust 寫的速度快）是目前最常被推薦的 prompt 工具。它的配置進 <code>~/.config/starship.toml</code>，也是 dotfile 的一部分。</p>
<h2 id="dotfile-結構對應">Dotfile 結構對應</h2>
<p><a href="/blog/linux/dotfile/01-dotfile-management/" data-link-title="模組一：管理工具與目錄結構" data-link-desc="要把散落在家目錄的配置檔集中版控時，選 bare repo、stow 還是 chezmoi、目錄該怎麼組織">管理工具與目錄結構</a>裡的 stow 目錄結構，shell 配置的對應：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">~/dotfiles/
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">└── zsh/
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    ├── .zshenv
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ├── .zshrc
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    └── .config/
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        └── zsh/
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">            ├── aliases.zsh
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">            ├── functions.zsh
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">            ├── plugins.zsh
</span></span><span class="line"><span class="ln">10</span><span class="cl">            ├── prompt.zsh
</span></span><span class="line"><span class="ln">11</span><span class="cl">            ├── tools.zsh
</span></span><span class="line"><span class="ln">12</span><span class="cl">            └── env.zsh</span></span></code></pre></div><p><code>stow zsh</code> 會在家目錄建立 <code>.zshenv</code> 和 <code>.zshrc</code> 的 symlink，在 <code>.config/zsh/</code> 下建立各模組檔案的 symlink。<code>local.zsh</code> 不在 repo 裡，各機器自己建。</p>
]]></content:encoded></item><item><title>模組二：Shell 配置</title><link>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/</guid><description>&lt;p>Shell 配置是 dotfile 管理裡最基礎也最常失控的一層。&lt;code>.zshrc&lt;/code> 或 &lt;code>.bashrc&lt;/code> 通常是開發者第一個開始客製的檔案，也是最容易長成數百行無結構巨檔的對象。這個模組教的是怎麼把 shell 配置拆成可維護的模組化結構。&lt;/p>
&lt;h2 id="章節文章">章節文章&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>文章&lt;/th>
 &lt;th>主題&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/zsh-modular-config/" data-link-title="Zsh 模組化配置" data-link-desc=".zshrc 長到數百行不敢動時回來讀">Zsh 模組化配置&lt;/a>&lt;/td>
 &lt;td>zsh/bash 載入順序、.zshrc 只做 source 的拆分結構、各模組的職責&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;a href="https://tarrragon.github.io/blog/linux/dotfile/02-shell-config/path-plugin-prompt/" data-link-title="PATH、Plugin 與 Prompt" data-link-desc="PATH 越來越長不知道怎麼管、要選 zsh plugin manager、或想設計 prompt 時回來讀">PATH、Plugin 與 Prompt&lt;/a>&lt;/td>
 &lt;td>PATH 管理原則、plugin manager 選型、prompt 設計、dotfile 目錄結構對應&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="跨分類引用">跨分類引用&lt;/h2>
&lt;ul>
&lt;li>→ &lt;a href="https://tarrragon.github.io/blog/linux/dotfile/01-dotfile-management/management-strategies/" data-link-title="管理策略與選型" data-link-desc="要選 dotfile 管理工具時回來讀 — bare repo、stow、chezmoi 的適用場景與選型判讀">模組一：管理策略&lt;/a>：stow 的 package 概念怎麼對應 shell 配置的目錄結構&lt;/li>
&lt;li>→ &lt;a href="https://tarrragon.github.io/blog/linux/dotfile/01-dotfile-management/cross-platform-one-repo/" data-link-title="跨平台共用一個 Repo" data-link-desc="macOS 跟 Linux 要共用同一個 dotfile repo、不想維護兩份時回來讀">模組一：跨平台共用一個 Repo&lt;/a>：path.zsh 和 tools.zsh 裡的 OS 分流做法&lt;/li>
&lt;li>→ &lt;a href="https://tarrragon.github.io/blog/linux/dotfile/03-terminal-ecosystem/" data-link-title="模組三：終端機與編輯器" data-link-desc="終端機相關工具的配置檔散落在不同位置、不確定哪些該進 dotfile repo 時回來讀">模組三：終端機與編輯器&lt;/a>：terminal emulator 的配色跟 shell prompt 的配色協調&lt;/li>
&lt;/ul></description><content:encoded><![CDATA[<p>Shell 配置是 dotfile 管理裡最基礎也最常失控的一層。<code>.zshrc</code> 或 <code>.bashrc</code> 通常是開發者第一個開始客製的檔案，也是最容易長成數百行無結構巨檔的對象。這個模組教的是怎麼把 shell 配置拆成可維護的模組化結構。</p>
<h2 id="章節文章">章節文章</h2>
<table>
  <thead>
      <tr>
          <th>文章</th>
          <th>主題</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><a href="/blog/linux/dotfile/02-shell-config/zsh-modular-config/" data-link-title="Zsh 模組化配置" data-link-desc=".zshrc 長到數百行不敢動時回來讀">Zsh 模組化配置</a></td>
          <td>zsh/bash 載入順序、.zshrc 只做 source 的拆分結構、各模組的職責</td>
      </tr>
      <tr>
          <td><a href="/blog/linux/dotfile/02-shell-config/path-plugin-prompt/" data-link-title="PATH、Plugin 與 Prompt" data-link-desc="PATH 越來越長不知道怎麼管、要選 zsh plugin manager、或想設計 prompt 時回來讀">PATH、Plugin 與 Prompt</a></td>
          <td>PATH 管理原則、plugin manager 選型、prompt 設計、dotfile 目錄結構對應</td>
      </tr>
  </tbody>
</table>
<h2 id="跨分類引用">跨分類引用</h2>
<ul>
<li>→ <a href="/blog/linux/dotfile/01-dotfile-management/management-strategies/" data-link-title="管理策略與選型" data-link-desc="要選 dotfile 管理工具時回來讀 — bare repo、stow、chezmoi 的適用場景與選型判讀">模組一：管理策略</a>：stow 的 package 概念怎麼對應 shell 配置的目錄結構</li>
<li>→ <a href="/blog/linux/dotfile/01-dotfile-management/cross-platform-one-repo/" data-link-title="跨平台共用一個 Repo" data-link-desc="macOS 跟 Linux 要共用同一個 dotfile repo、不想維護兩份時回來讀">模組一：跨平台共用一個 Repo</a>：path.zsh 和 tools.zsh 裡的 OS 分流做法</li>
<li>→ <a href="/blog/linux/dotfile/03-terminal-ecosystem/" data-link-title="模組三：終端機與編輯器" data-link-desc="終端機相關工具的配置檔散落在不同位置、不確定哪些該進 dotfile repo 時回來讀">模組三：終端機與編輯器</a>：terminal emulator 的配色跟 shell prompt 的配色協調</li>
</ul>
]]></content:encoded></item></channel></rss>