換腦袋了
老派的浪漫:換零件!不過,這很重要嗎?現代手機電腦在設計之初就想好了生命週期,想要換零件?不用那麼麻煩,整個換掉就好了!而且,在零件還來不及壞掉之前,廠商早己使出升級專有軟體這招強迫你換機。其它電子產品也不例外,最近有個新名詞:快科技,正是在講這現象的背後產生了多少難以回收的電子垃圾。

老派的浪漫

這一台 高齡 筆記型電腦能升級的零件幾乎都被我升級了,除了硬碟,也就是儲存資料的地方還沒有換過,用人體來比喻的話就是腦袋的海馬迴仍然是同一顆。是,換零件!現在的筆電走向零件高度整合,也就是我的零件規格只有自己的產品能夠密合地使用,別人無法用,這反應出模組化已退流行,漸漸地不再能一體適用,說白了,愈難以升級筆電。

(預備更換成Kingston SA400S37/240G的SSD固態硬碟)
(預備更換成Kingston SA400S37/240G的SSD固態硬碟)

主打輕薄機型要省空間,所以零件全是焊死的,當然也不用想換了;不論何種機型,電池幾乎是內建,無法讓人拔出來,當然也不能更換;能讓人升級記憶體和硬碟的商務或遊戲類機型,從整體市場來看,近幾年來也愈來愈走向整合。

不過,這很重要嗎?現代手機電腦在設計之初就想好了生命週期,想要換零件?不用那麼麻煩,整個換掉就好了!而且,在零件還來不及壞掉之前,廠商早己使出升級 專有軟體 這招強迫你換機。其它電子產品也不例外,最近有個新名詞: 快科技 ,正是在講這現象的背後產生了多少難以回收的電子垃圾。

清楚自己的需求

電腦規格有多少,市場的需求就有多少,除了最直接的市場和客製化之外,還有其它技術上的原因,舉我能升級到頂的 Intel 第二代CPU中央處理器 i5-2520M來說,她的上下一級就有2430M、2540M這些型號,規格分那麼細是怎麼回事?性能差那一點點,我是感覺得出來嗎?還是圖一個心情好?其實還有以下幾種原因:

  1. 晶片良率與binning機制
  • 一顆晶片 ≠ 一個產品:晶圓廠生產出來的 CPU,不是每顆都能達到最高規格,Intel 會依照測試結果,把晶片分 bin,簡單說就是把這些元件分類,跑到最高頻率的賣高階型號 i9、i7;跑不到,但穩定在較低頻率的,把它降級成 i5、i3。
  • 同一個核心設計,會被切成不同型號代碼來賣,所以有時候一顆 i5-2520M 和 i7-2620M 其實是同一顆晶片,只是被設定不同倍頻/功能而已。
  1. 實驗性/技術試探
  • 新工藝過渡期:在新製程,例如從我cpu的32nm製程要過渡到22nm時,Intel 會推出一堆型號測試市場與工藝成熟度。部分型號可能關掉某一些功能,既是市場區隔,也是在試驗客戶需求。

  • 不同需求的 TDP 調整:簡單說,就是實驗這顆CPU在滿載運作時產生多少熱能,要散去多少熱量才好?有些型號是為了實驗不同電壓/功耗平衡點,例如超低電壓版 (ULV)就是在正常 CPU 上調教出來的。

不該是身份地位的象徵

清楚知道自己拿電腦來做什麼事,才能夠選出符合自己需求的型號,我的要求很簡單:文書處理;有姊妹在做繪圖工作,有弟兄要打電動,所以買了桌上型電腦,當然要配上厲害的顯示卡,才不會卡頓到懷疑人生。選購這件事沒有什麼好評價的,只擔心把手機電腦也當成身份地位的象徵,如同現代人賦予汽車、房子一樣的標籤,甚至有些連嫁老公娶老婆都是如此!如果最在乎的是上得了廳堂、帶出門夠體面嗎?那我只能說,這樣子的需求已經不是人事物本身了,而是自己的虛榮。

我承認,我以東西用很久為榮,對老派的人事物有莫名的情感。

換成SSD並clone repo

傳統HDD換成SSD真的很有感覺,心情也有,主要還是讀取資料的速度變快了,開機、開啟應用程式的速度跟著快很多!

換成SSD後要複製回來的重要資料是放在Github上的hugo站點,也就是jujublog的網誌。以下為技術文件,記錄自己換零件並恢復本機上相關設定的過程,這對我有幫助。如果您早已使用以Linux為核心的任何一套 作業系統 ,一定很熟悉這些操作過程。

設置環境並複製回本機

  1. 安裝 Hugo Extended v0.147.2 到 /usr/local/bin,版本與本機及Github一致。

  2. SSH 金鑰建立、加到 GitHub,ssh -T git@github.com 認證成功。

  3. 從 GitHub clone 我的 repo 到新 SSD/home/bengju/hugo

  4. 停用 push URL(防手滑):origin (push) = DISABLED

  5. submodule 初始化(有主題或外掛時使用)。

  6. 本機預覽成功(Hugo serve 可跑、頁數統計正常)。

  7. .gitignore 忽略 /public,清乾淨建置產物的干擾。

  8. 撰寫並測試 彩色輸出的部署腳本:

    • deploy_test.shgit push --dry-run,不會真的推)
    • deploy.sh(正式推送用;目前 push 被停用,不會誤發)

指令 & 用意

1.建置環境 »» 產生金鑰

# === Hugo Extended v0.147.2 安裝 + SSH 檢查 一鍵腳本 ===
set -euo pipefail

HUGO_VER="0.147.2"
INSTALL_PREFIX="/usr/local"
TMPDIR="$(mktemp -d)"
cleanup(){ rm -rf "$TMPDIR"; }
trap cleanup EXIT

echo "== 檢查是否有舊的非 Extended 版 hugo(若有將移除 apt 版本避免混淆)=="
if command -v hugo >/dev/null 2>&1; then
  hugo version || true
fi
if dpkg -l | grep -q '^ii\s\+hugo\s'; then
  echo "偵測到 apt 安裝的 hugo,先移除以避免路徑衝突..."
  sudo apt remove -y hugo || true
fi

echo "== 下載 Hugo Extended v${HUGO_VER} =="
cd "$TMPDIR"

# 先嘗試新版檔名(Linux-amd64),失敗再退回(Linux-64bit)
TAR_AMD64="hugo_extended_${HUGO_VER}_Linux-amd64.tar.gz"
TAR_64BIT="hugo_extended_${HUGO_VER}_Linux-64bit.tar.gz"

URL_AMD64="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/${TAR_AMD64}"
URL_64BIT="https://github.com/gohugoio/hugo/releases/download/v${HUGO_VER}/${TAR_64BIT}"

if curl -fsSLO "$URL_AMD64"; then
  TAR="$TAR_AMD64"
elif curl -fsSLO "$URL_64BIT"; then
  TAR="$TAR_64BIT"
else
  echo "下載失敗:找不到 v${HUGO_VER} 的 Linux 發行包。請檢查版本號。"; exit 1
fi

echo "== 安裝到 ${INSTALL_PREFIX}/bin/hugo =="
tar -xzf "$TAR" hugo
sudo mv -f hugo "${INSTALL_PREFIX}/bin/hugo"
sudo chmod 0755 "${INSTALL_PREFIX}/bin/hugo"

echo "== 驗證 Hugo 版本(需含 extended)=="
which -a hugo
HVER="$(hugo version)"
echo "$HVER"
if ! echo "$HVER" | grep -qi 'extended'; then
  echo "安裝的不是 Extended 版,請確認發行包是否為 extended。"; exit 1
fi

echo "== SSH 金鑰檢查:~/.ssh/id_ed25519 是否存在 =="
mkdir -p ~/.ssh
chmod 700 ~/.ssh
KEY=~/.ssh/id_ed25519
if [[ -f "$KEY" ]]; then
  echo "已找到金鑰:$KEY(不重新產生)"
else
  echo "未找到金鑰,將建立新的 ed25519 金鑰(每台機器一把較安全)"
  COMMENT="$(whoami)@$(hostname -f 2>/dev/null || hostname)"
  ssh-keygen -t ed25519 -C "$COMMENT" -f "$KEY"
fi

echo "== 啟動 ssh-agent 並加入金鑰(方便後續不用每次輸入密語)=="
eval "$(ssh-agent -s)"
ssh-add "$KEY"

echo "== 這是你的公鑰,請複製到 GitHub → Settings → SSH and GPG keys → New SSH key =="
echo "------------------------------------------------------------"
cat "${KEY}.pub"
echo "------------------------------------------------------------"

echo "== 測試連線到 GitHub(只測試,不會寫入任何東西)=="
# 第一次可能會問要不要信任 GitHub host key,輸入 yes
set +e
ssh -T git@github.com
RC=$?
set -e
if [ $RC -ne 1 ] && [ $RC -ne 0 ]; then
  echo "SSH 測試異常(返回碼 $RC)。若未加入公鑰到 GitHub,請先加入再重試 ssh -T git@github.com"
else
  echo "SSH 測試完成(出現 Welcome/Successfully authenticated 即代表可用)。"
fi

echo "== 完成:Hugo Extended v${HUGO_VER} 已安裝,SSH 也就緒。=="
echo "接下來你可以 git clone 你的 repo,或告訴我要繼續下一步。"

2.複製回來 »» 本機預覽

建立clone-and-serve.sh腳本並給可執行的權限chmod +x clone-and-serve.sh後,於所在目錄執行./clone-and-serve.sh

#!/usr/bin/env bash
set -euo pipefail

# === 1) 設定路徑 ===
WORKDIR="/home/<你的使用者名稱>"
REPONAME="<你的repo名稱>"
REPOURL="git@github.com:<你的GitHub帳號>/<你的repo名稱>.git"
CONFIGFILE="hugo.toml"

cd "$WORKDIR"

# === 2) Clone repo 到本機(如果資料夾已存在就先提示)===
if [[ -d "$WORKDIR/$REPONAME" ]]; then
  echo "⚠️  目錄 $WORKDIR/$REPONAME 已存在,請先確認是否要刪除或備份再執行。"
  exit 1
fi

echo "== Clone repo =="
git clone "$REPOURL"
cd "$REPONAME"

# === 3) 防呆:暫時停用 push,避免手滑 ===
git remote set-url --push origin DISABLED
echo "== Remote 設定如下(push 應為 DISABLED)=="
git remote -v

# === 4) 初始化/更新 submodules(若主題用 submodule)===
echo "== 更新 submodules(若有)=="
git submodule update --init --recursive || true

# === 5) 若 Git 有 safe.directory 限制,加入白名單 ===
git config --global --add safe.directory "$WORKDIR/$REPONAME" || true

# === 6) 檢查 hugo.toml 是否存在 ===
if [[ ! -f "$CONFIGFILE" ]]; then
  echo "❌ 找不到 $CONFIGFILE,請確認 repo 內的設定檔名稱。"
  exit 1
fi
echo "✅ 找到設定檔 $CONFIGFILE"

# === 7) 本機預覽(http://localhost:1313/)===
echo "== 啟動本機 Hugo 預覽(使用 hugo.toml)=="
hugo serve --config hugo.toml -DF --disableFastRender --gc

3. 調整 .gitignore、清理追蹤的 public、忽略 /resources/_gen/ 並清理出 Git 追蹤

echo "/public/" >> .gitignore
git rm -r --cached public
git add .gitignore
git commit -m "chore: ignore Hugo build output in /public"

cd /home/bengju/hugo

echo "== Step 1: 更新 .gitignore,加入 /resources/_gen/ =="
# 如果還沒加入,才追加一行
grep -qE '^/resources/_gen/?$' .gitignore || echo "/resources/_gen/" >> .gitignore

echo "== Step 2: 從 Git 追蹤中移除,但保留實體檔案 =="
git rm -r --cached resources/_gen || true

echo "== Step 3: 建立 commit(僅修改 .gitignore 與索引) =="
git add .gitignore
git commit -m "chore: ignore Hugo generated resources in /resources/_gen"

echo "✅ 已完成:/resources/_gen/ 已被忽略,檔案仍保留在本地,但不再進入 Git 歷史"
echo "⚠️ 注意:這個 commit 只在本地,尚未推送。要上傳時再跑: git push origin main"
  • 讓建置產物不再進入版控、工作區回到乾淨。

4. 部署腳本(測試版)

建立測試版的佈署腳本deploy_test.sh並給可執行的權限chmod +x deploy_test.sh後,於所在目錄執行./deploy_test.sh

  • 會如此跑:hugo buildgit add/commitgit push --dry-run模擬推送
#!/usr/bin/env bash
# deploy_test.sh - 測試版部署腳本(不會真的推送,只做 dry-run)
# 升級版:新增檢查 ssh-agent/user.name / user.email

set -e

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # 無色

# 檢查 ssh-agent 是否已載入金鑰

if ! ssh-add -l >/dev/null 2>&1; then
  echo "❌ 尚未載入 SSH 金鑰。請執行:"
  echo "    ssh-add ~/.ssh/id_ed25519"
  exit 1
fi

# 確認有至少一把金鑰
if ssh-add -l | grep -q "The agent has no identities"; then
  echo "❌ ssh-agent 裡沒有金鑰。請先加:"
  echo "    ssh-add ~/.ssh/id_ed25519"
  exit 1
fi

echo "✅ ssh-agent 內已有金鑰,可以繼續推送。"

echo -e "${GREEN}== Step 0: 檢查 Git 身份設定 ==${NC}"
if ! git config user.name >/dev/null; then
  echo -e "${RED}❌ 錯誤:缺少 user.name${NC}"
  echo "請執行: git config --global user.name \"你的GitHub帳號\""
  exit 1
fi
if ! git config user.email >/dev/null; then
  echo -e "${RED}❌ 錯誤:缺少 user.email${NC}"
  echo "建議使用 GitHub noreply,例如:"
  echo "git config --global user.email \"12345678+juju0826@users.noreply.github.com\""
  exit 1
fi

echo -e "${GREEN}== Step 1: 進入專案目錄並執行 Hugo build ==${NC}"
hugo --cleanDestinationDir

echo -e "${GREEN}== Step 2: 檢查 Git 狀態 ==${NC}"
if [ ! -d .git ]; then
  echo -e "${RED}❌ 錯誤:不是 Git 倉庫,請先在 repo 根目錄執行。${NC}"
  exit 1
fi

branch=$(git symbolic-ref --short HEAD || echo "DETACHED")
if [ "$branch" != "main" ]; then
  echo -e "${YELLOW}⚠️ 注意:目前分支是 $branch,不是 main。${NC}"
fi

echo -e "${GREEN}== Step 3: 準備提交變更 ==${NC}"
git add .
if git diff --cached --quiet; then
  echo -e "${GREEN}✅ 沒有新變更需要提交。${NC}"
else
  msg="site updated: $(date '+%Y-%m-%d %H:%M:%S')"
  git commit -m "$msg"
fi

echo -e "${GREEN}== Step 4: 模擬推送(不會真的送出) ==${NC}"
git push --dry-run origin main || true

echo -e "${GREEN}✅ 測試部署流程完成(未實際推送)${NC}"

遇到哪些問題?怎麼解的?

換腦袋的過程沒有一次到位,因為有過與AI一起架設網站的經驗,這次一定要來回問得很詳細才好動手實際執行。從我五月接觸Chat GPT算起不到三個月,模型正巧升級成第5代。好像真的回答和提問愈精確了,之前常發生AI回覆的很有自信,結果做出來卻行不通,質問她的時候還客客氣氣地跟我繞圈子。

我遇到以下問題,AI第一時間就解決了,可見她在電腦知識方面又更強大了。

1. SSH 測試失敗

  • 原因:Permission denied (publickey)可能是因為公鑰尚未加到 GitHub、agent 未載入、或 SSH 沒指到正確的鑰。

  • 作法:

    • 顯示公鑰並加到 GitHub Settings → SSH keys
    • 啟動 ssh-agent + ssh-add ~/.ssh/id_ed25519
    • 新增 ~/.ssh/config 指定 github.com 使用這把鑰、IdentitiesOnly yes
    • 重新測試 ssh -T git@github.com → 成功。

中間有測試異常返回碼255,這代表「GitHub 沒接受我的金鑰」,最常見是:公鑰還沒加到 GitHub 帳號、或 agent/設定沒讀到正確的私鑰,解法如下:

A. 把公鑰加到 GitHub 帳號

# 1) 顯示你的公鑰內容,整段複製(包含 ssh-ed25519 開頭到最後的主機註解)
cat ~/.ssh/id_ed25519.pub

到 GitHub:右上角頭像 → Settings → SSH and GPG keys → New SSH key → 貼上剛剛複製的內容 → Add SSH key。

B. 確認金鑰已被載入(agent)

# 啟動 agent
eval "$(ssh-agent -s)"

# 加入私鑰(加了 -t 8h 代表記住 8 小時,可省略)
ssh-add -t 8h ~/.ssh/id_ed25519

# 檢查 agent 內是否有這把金鑰(會列出 ED25519 指紋)
ssh-add -l

如果 ssh-add -l 顯示 The agent has no identities.,表示沒成功加進去;再執行一次 ssh-add ~/.ssh/id_ed25519

C. 權限與 SSH 設定(避免被 SSH 忽略)

# 正確的檔案權限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

# 推薦放一份明確的 SSH 設定
cat > ~/.ssh/config <<'EOF'
Host github.com
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  AddKeysToAgent yes
EOF
chmod 600 ~/.ssh/config

D. 重新測試(先看詳細原因)

# 詳細模式可以看到它嘗試了哪把鑰
ssh -vT git@github.com

成功時會看到:

Hi <你的帳號>! You've successfully authenticated, but GitHub does not provide shell access.

2.本機預覽 OK,但 Git 顯示一大堆改動

  • 原因:public/(輸出)與 resources/_gen/(生成資源)被納入版本控制,本機重建導致大量差異。
  • 解法:將兩者加入 .gitignore,並用 git rm --cached 從索引移除,保留實體檔。
  • 寫了 cleanup.sh 一鍵處理,只 commit、不推,腳本如下:
#!/usr/bin/env bash
# cleanup.sh - 一次性清理:忽略 /public 與 /resources/_gen 並從 Git 追蹤中移除(保留實體檔)
# 注意:本腳本只建立本機 commit,不會 push。

set -e

GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # 無色

echo -e "${GREEN}== Step 0: 確認在 repo 根目錄 ==${NC}"
if [ ! -d .git ]; then
  echo -e "${RED}❌ 錯誤:不是 Git 倉庫,請先在 repo 根目錄執行。${NC}"
  exit 1
fi

echo -e "${GREEN}== Step 1: 更新 .gitignore ==${NC}"
touch .gitignore
added=0
if ! grep -qE '^/public/?$' .gitignore; then
  echo "/public/" >> .gitignore
  echo -e "${GREEN}已加入 /public/ 到 .gitignore${NC}"
  added=1
fi
if ! grep -qE '^/resources/_gen/?$' .gitignore; then
  echo "/resources/_gen/" >> .gitignore
  echo -e "${GREEN}已加入 /resources/_gen/ 到 .gitignore${NC}"
  added=1
fi
if [ $added -eq 0 ]; then
  echo -e "${YELLOW}/.gitignore 已包含必要規則,略過新增${NC}"
fi

echo -e "${GREEN}== Step 2: 從索引移除(保留實體檔) ==${NC}"
tracked_public=$(git ls-files --error-unmatch public 2>/dev/null && echo "yes" || echo "no")
if [ "$tracked_public" = "yes" ]; then
  git rm -r --cached public || true
  echo -e "${GREEN}public/ 已自索引移除(檔案仍留在磁碟)${NC}"
else
  echo -e "${YELLOW}public/ 未被 Git 追蹤,略過${NC}"
fi

tracked_gen=$(git ls-files --error-unmatch resources/_gen 2>/dev/null && echo "yes" || echo "no")
if [ "$tracked_gen" = "yes" ]; then
  git rm -r --cached resources/_gen || true
  echo -e "${GREEN}resources/_gen/ 已自索引移除(檔案仍留在磁碟)${NC}"
else
  echo -e "${YELLOW}resources/_gen/ 未被 Git 追蹤,略過${NC}"
fi

echo -e "${GREEN}== Step 3: 建立 commit(僅 .gitignore 與索引變更) ==${NC}"
git add .gitignore || true
if git diff --cached --quiet; then
  echo -e "${YELLOW}沒有需要提交的索引變更。${NC}"
else
  git commit -m "chore: ignore Hugo build outputs (/public, /resources/_gen) and remove from index"
  echo -e "${GREEN}✅ 已建立清理用 commit(尚未推送)${NC}"
fi

echo -e "${GREEN}== Step 4: 檢查狀態 ==${NC}"
git status

echo -e "${GREEN}完成:未推送任何資料。若要上傳請自行執行: git push origin main${NC}"

3. git commit 報:作者身分未知

  • 原因:新環境未設定使用者資訊,缺 user.name/email。

  • 作法:在全域或單一 repo 設定 user.name / user.email,建議用 GitHub noreply。

全域設定,之後所有 repo 都可用

把下面兩行的值改成自己的資料後貼上:

git config --global user.name "juju0826"
git config --global user.email "你的Email或GitHub noreply信箱"

如果想保護隱私,建議用 GitHub 的 noreply 信箱,在個人設定頁可看到,通常是: 123456+juju0826@users.noreply.github.comjuju0826@users.noreply.github.com)。

4. Cloudflare Pages 設定一致性

  • 建置命令與版本鎖定:

    • Build command:hugo --gc --minify
    • Output dir:public
    • 環境變數:HUGO_VERSION=0.147.2(與本機同版)
  • 這樣Github雲端與本機渲染一致。

5. 是否要忽略 /resources/_gen/ 的取捨

  • 說明:忽略幾乎沒有壞處,換來 repo 輕盈;第一次建置稍慢是正常且可接受。

上次修改於 2025-08-22