跟思兼學用Klipper(35) mergerfs 助力 Klipper 上位機熱插拔自動擴容與脫機打印
跟思兼學用Klipper(35) mergerfs 助力 Klipper 上位機熱插拔自動擴容與脫機打印
前言
原創文章,轉載引用務必注明鏈接,水平有限,如有疏漏,歡迎指正交流。
文章如有更新請訪問 DFRobot 社區及 cnblogs 博客園,前者內容較全,后者排版及閱讀體驗更佳。
一晃才發現小半年沒有發表新文章了,仿佛還在上個月。
這是一篇借助豆包,基于我的大綱與測試結果自動生成并經過我修改的文章,不知道效果如何。其實我本地很多存貨,苦于沒有時間精力整理成文,借助 AI 可能會是一個很好的方法。同時部分程序代碼使用 AI 進行輔助,至于感受會在文末總結。
在 3D 打印的領域里,Klipper 固件憑借出色的性能,深受廣大愛好者青睞。早期基于電視盒子打造的 Klipper 上位機,常見配置是 1G 內存+ 8G eMMC 存儲。隨著模型復雜度增加,上傳的模型切片文件越來越大、數量越來越多,再加上延時攝影臨時抓取的大量圖片以及渲染生成的視頻,這點存儲空間就顯得捉襟見肘了。
之前我寫過文章,包括跟著思兼學習Klipper(10)使能Klipper從U盤讀取Gcode并打印 以及 跟著思兼學習Klipper(23) 玩一玩必趣 BTT Pi 上位機,分別介紹熱插拔自動掛載 U 盤或 SD 卡實現脫機打印,以及利用Alist+Rclone+網盤給上位機擴容。今天我們要更進一步,探索新的更完善的擴容方案。
軟件環境:
- DietPi for x86_64 Legacy (based on Debian Bookworm)
- mergerfs v2.40.2
硬件環境:
- KlipperBoxPro 上位機
- 4GB microSD 和 64GB U盤,以下簡稱移動存儲
本文涉及的內容:
- mergerfs 實現上位機熱插拔移動存儲實現脫機打印和自動擴容
- udev 規則故障排查
- AI 輔助文章寫作的感受
- AI 輔助編程的感受
一、現狀與目的
更完善的熱插拔脫機打印
- 也就是馬琳(Marlin)時代,在電腦上將切好的模型文件拷貝到 SD 卡或 U 盤后,插到打印機上進行打印。
- 隨著 Klipper 的出現,網絡打印流程更加方便。且特殊情況可以通過上位機創建熱點來實現局域網打印。
- 由于 Klipper 不支持自動掛載磁盤,所以要額外的設置/程序實現自動掛載移動存儲到 $HOME/printer_data/gcodes 目錄下,從而被 Klipper 訪問
- 考慮到 U 盤穩定性欠佳,接口松動可能導致打印失敗,目前一種策略是在識別到移動存儲插入后,會把其中的 gcode 文件復制一份到宿主機 gcodes 文件夾


長期掛載作為系統擴容磁盤
- 除了熱插拔脫機打印功能之外,我認為更重要的是針對小存儲上位機如電視盒子/ WiFi 棒子的擴容功能
- 把諸如 Gcodes 和延時攝影視頻,或者其他文件存儲到移動存儲設備上,從而避免主磁盤空間滿了
- 通過給移動存儲創建特定標簽,從而只把指定設備掛載為擴容盤。此處為
KBOX_EXT_SD/KBOX_EXT_U1
二、目前方案的缺點
這次的方案既支持脫機打印,又支持自動擴容。相比直接用 udev + mount 或者 fstab 掛載,優勢明顯:
規避系統啟動風險:fstab 掛載一旦配置有誤,比如設備路徑寫錯、文件系統類型指定錯誤,極有可能導致系統啟動失敗。而 mergerfs 掛載能有效避免這類問題,確保系統順利啟動。
靈活存儲運用:既能實現移動存儲設備即插即打印,方便快捷地開啟打印任務;又能常規插在上位機上作為擴容存儲設備,不管是存放更大的 swapfile 來優化系統運行,還是存儲延時攝影素材、大量的 gcode 文件,都不在話下。
解決目錄顯示問題:普通 mount 操作遇到同名目錄時,會隱藏原目錄,導致里面的文件無法訪問。mergerfs 則不會出現這種狀況,所有文件和目錄都能正常顯示,方便用戶管理文件。
便捷切片軟件上傳:以往切片軟件上傳文件,常掛載到 gcodes 子目錄,之后還得手動移動文件到合適位置。現在新方案支持切片軟件直接上傳到用于擴容的移動存儲目錄,大大簡化了流程,提高了工作效率。
降低板載存儲損耗:板載 eMMC 存儲更換不便,且頻繁讀寫易磨損。新方案把數據存儲任務轉移到可熱插拔的移動存儲設備,如 sd 卡。sd 卡用完可輕松更換,有效減少 eMMC 的磨損,延長其使用壽命。
接下來,我們來看看具體實現步驟。
三、結構設計

3.1 移動存儲初始化
主要目的是選擇合適的文件系統,對掃描到的移動存儲設備格式化,設置分區標簽為 KBOX_EXT_SD/KBOX_EXT_U1 等,方便后續正確掛載,并忽視其他存儲設備。
3.1.1 文件系統選擇
因為使用 microSD 或 U 盤這種閃存設備,且只存儲簡單文件無高級特性需求,考慮到 Windows/Linux 系統兼容性,存儲壽命等因素,這里推薦如果需要 Windows 下也可以訪問,推薦 exFAT 文件系統,否則可以嘗試 f2fs 文件系統。其他如 ext4、btrfs 等也可以選擇。
3.1.2 上位機安裝必備軟件包
# 安裝 exFAT 或 f2fs 文件系統支持包
sudo apt install exfatprogs f2fs-tools util-linux attr bc
3.1.3 移動存儲設備初始化腳本
使用步驟:
- 將待格式化的磁盤插入上位機
- 在上位機 ssh 終端中輸入
sudo bash prepare_storage.sh對設備進行初始化,根據提示選擇正確的設備,如果不確定,可以在插拔移動存儲前后,在終端輸入 lsblk,對比后確認。
主要功能:
- 自動掃描并列出所有可用磁盤,排除根目錄所在磁盤,避免誤格式化
- 顯示掃描到的移動存儲,供用戶選擇【注意:磁盤會被清空,請務必選擇正確的磁盤】
- 允許用戶選擇 exFAT 還是 f2fs 文件系統。
- 根據設備是 SD 卡還是 U 盤設置不同的分區標簽
- 在新分區上創建 gcodes 和其他目錄
#!/bin/bash
# '''
# Author: sjqlwy sjqlwy@yeah.net
# Date: 2025年4月13日
# Description:初始化存儲設備用于系統擴容以及脫機打印
# '''
# 獲取根目錄所在設備
root_device=$(df / | tail -1 | awk '{print $1}' | sed 's/[0-9]*$//')
# 掃描可用的 SD 卡和 U 盤
devices=()
sizes=()
for device in /sys/block/*; do
device_name=$(basename $device)
if [[ $device_name == "mmcblk"* || $device_name == "sd"* ]]; then
device_path="/dev/$device_name"
if [ "$device_path" != "$root_device" ]; then
devices+=("$device_path")
size=$(blockdev --getsize64 "$device_path")
# 將大小轉換為GB并保留1位小數
size_gb=$(printf "%.1f" $(echo "scale=1; $size / 1024 / 1024 / 1024" | bc))
sizes+=("$size_gb GB")
fi
fi
done
# 顯示可用設備供用戶選擇
if [ ${#devices[@]} -eq 0 ]; then
echo "未找到可用的 SD 卡或 U 盤。"
exit 1
fi
echo "可用的設備有:"
for i in "${!devices[@]}"; do
echo "$((i + 1)). ${devices[$i]} (${sizes[$i]})"
done
# 獲取用戶選擇
read -p "請輸入你要選擇的設備編號 (1 - ${#devices[@]}): " choice
if ! [[ $choice =~ ^[0-9]+$ ]] || [ $choice -lt 1 ] || [ $choice -gt ${#devices[@]} ]; then
echo "無效的選擇。"
exit 1
fi
selected_device=${devices[$((choice - 1))]}
# 卸載設備上的所有分區
for partition in $(lsblk -n -o NAME $selected_device | grep -E '^[^[:space:]]+[0-9]+$'); do
umount "/dev/$partition" 2>/dev/null
done
# 刪除原有分區表
parted -s "$selected_device" mklabel gpt
if [ $? -ne 0 ]; then
echo "刪除原有分區表失敗,請檢查設備狀態。"
exit 1
fi
# 創建新分區
parted -s "$selected_device" mkpart primary 0% 100%
if [ $? -ne 0 ]; then
echo "創建新分區失敗,請檢查設備狀態。"
exit 1
fi
# 等待內核識別新分區
sleep 2
# 通知內核重新讀取分區表
partprobe "$selected_device"
# 獲取新分區的設備路徑
if [[ $selected_device == *"mmcblk"* ]]; then
new_partition="${selected_device}p1"
else
new_partition="${selected_device}1"
fi
# 檢查新分區是否存在
if [ ! -b "$new_partition" ]; then
echo "新分區 $new_partition 未被識別,請檢查設備狀態。"
exit 1
fi
# 生成合適的 LABEL
if [[ $selected_device == *"mmcblk"* ]]; then
label="KBOX_EXT_SD"
else
existing_labels=$(lsblk -o LABEL | grep '^KBOX_EXT_U')
max_num=0
for existing_label in $existing_labels; do
num=$(echo $existing_label | grep -oE '[0-9]+$' | sed 's/^0*//')
if [ -n "$num" ] && [ $num -gt $max_num ]; then
max_num=$num
fi
done
new_num=$((max_num + 1))
label="KBOX_EXT_U${new_num}"
fi
# 讓用戶選擇文件系統格式
echo "請選擇文件系統格式:"
echo "1. exfat(雙系統訪問,推薦)"
echo "2. f2fs"
read -p "請輸入對應的數字 (1 - 2): " fs_choice
if [ "$fs_choice" != "1" ] && [ "$fs_choice" != "2" ]; then
echo "無效的選擇,請輸入 1 或 2。"
exit 1
fi
if [ "$fs_choice" == "1" ]; then
fs_type="exfat"
mkfs.exfat -n "$label" "$new_partition"
# 給 exfat 分區添加 msftdata 標簽
partition_number=$(echo "$new_partition" | grep -oE '[0-9]+$')
parted -s "$selected_device" set "$partition_number" msftdata on
else
fs_type="f2fs"
mkfs.f2fs -l "$label" "$new_partition"
fi
if [ $? -ne 0 ]; then
echo "格式化新分區為 $fs_type 格式失敗,請檢查設備狀態。"
exit 1
fi
# 修改 mount_point 為和 label 相同的格式
mount_point="/mnt/$label"
mkdir -p "$mount_point"
mount "$new_partition" "$mount_point"
if [ $? -ne 0 ]; then
echo "掛載新分區 $new_partition 失敗,請檢查設備狀態。"
exit 1
fi
# 獲取當前 sudo 執行用戶
user=$(logname)
# 創建目錄
mkdir -p "$mount_point/gcodes"
mkdir -p "$mount_point/timelapse"
# 根據文件系統格式決定是否修改目錄所有者
if [ "$fs_type" == "f2fs" ]; then
chown -R "$user" "$mount_point/gcodes" "$mount_point/timelapse"
fi
# 卸載新分區
umount "$mount_point"
if [ $? -ne 0 ]; then
echo "卸載新分區 $new_partition 失敗,請手動卸載。"
fi
echo "設備 $selected_device 已成功刪除原有分區,創建了 $fs_type 分區,標簽為 $label,并創建了 gcodes 和 timelapse 目錄。"
注意:
- 必須排除根目錄所在磁盤避免誤選擇
- 增加顯示磁盤大小避免誤選擇
- 一般 mSD 槽只有一個,U 盤可以有多個,所以預留了相關處理
- exFAT 分區需要添加 msftdata 標簽,否則在 Windows 下是隱藏分區不可見
- 創建 f2fs 分區后,需要將 gcodes 目錄所有者轉到當前非 root 賬戶來獲得讀寫權限
- 由于 exFAT 不支持復雜權限管理,所以無法修改目錄所有者,采用 mount 掛載的時候指定 UID GID 來實現。
- 對于 exFAT 這種非 POSIX 標準文件系統,df -i 顯示 inode 數為 0
- 注意 exFAT 的標簽長度有限制,所以這里設置為
KBOX_EXT_Ux而不是KBOX_EXT_USBx - 考慮到脫機打印,需要在 Windows 和 Linux 下都能訪問移動存儲,這里推薦 exFAT 文件系統
- 如果僅做擴容盤使用,可以選擇 f2fs 文件系統
- 關于文件系統的兼容性問題,可以移步 https://trapexit.github.io/mergerfs/faq/compatibility_and_integration/
至此我們獲得了一個標簽為 KBOX_EXT_* 的移動存儲,并可以在 Windows 下訪問 (exFAT)。
3.2 上位機設置
3.2.1 安裝必要軟件包:
# 安裝 mergerfs,此處使用了鏡像源,且下載 Klipper Pro 系列上位機所使用的 x86_64(amd64) 架構軟件包
wget https://cors.isteed.cc/https://github.com/trapexit/mergerfs/releases/download/2.40.2/mergerfs_2.40.2.debian-bookworm_amd64.deb
sudo dpkg -i mergerfs*.deb
# 創建目錄 local_gcodes 用于存放從原 ~/printer_data/gcodes 目錄遷移來的模型切片文件
cd && mkdir ~/printer_data/local_gcodes
mv ~/printer_data/gcodes/* ~/printer_data/local_gcodes/
注意:
- 由于系統自帶的版本老舊(2.33.5),我們總是推薦從其項目主頁下載手動安裝最新版,以獲得最新的特性與更好的兼容性。
- mount 后
~/printer_data/local_gcodes目錄中的文件不可見,所以我們提前移出
3.2.2 創建 udev 規則實現自動掛載
既往使用直接將移動存儲設備掛載到 ~/printer_data/local_gcodes 子目錄下,存在諸多不便,所以本次使用 /mnt/目錄下,然后使用 mergerfs 整合到虛擬目錄。udev 規則如同智能管家,能識別標簽為 KBOX_EXT_SD/USBx 設備插入,并按規則自動掛載到指定的 /mnt/[LABEL] 目錄。在 /etc/udev/rules.d/ 目錄創建新規則文件,文件名可自定義,建議遵循規范便于管理,如創建名為 99-kboxext-mount.rules 的文件(數字表示優先級,越小越高,這里用 99)。
mkdir -p $HOME/kbox_scripts/
# 創建一個腳本,查找根目錄所在磁盤用于排除,且輸出符合 udev 規則。key:vaule
tee $HOME/kbox_scripts/get_rootfs.sh > /dev/null << 'EOF'
#!/bin/bash
device=$(/bin/findmnt -n -o SOURCE /)
echo "root_device=$device"
EOF
# 創建自動掛載規則,我們仍然參考 homeassistant 的腳本
# 注意這里使用 pi 用戶
sudo tee /etc/udev/rules.d/99-kboxext-mount.rules > /dev/null << 'EOF'
# Get the root device
IMPORT{program}="/bin/bash /home/pi/kbox_scripts/get_rootfs.sh"
ENV{root_device}="%E{root_device}"
# Import the partition info into the environment variables
IMPORT{program}="/usr/sbin/blkid -o udev -p %N"
# Exit if partition is not a filesystem
ENV{ID_FS_USAGE}!="filesystem", GOTO="abort_rule"
# Exit if the label doesn't start with KBOX_EXT_
ENV{ID_FS_LABEL}!="KBOX_EXT_*", GOTO="abort_rule"
# Exit if it's the root device
ENV{DEVNAME}=="%E{root_device}", GOTO="abort_rule"
# Determine the mount point using the label
ENV{mount_point}="/mnt/%E{ID_FS_LABEL}"
# General mount options
ACTION=="add", ENV{mount_options}="relatime,sync,uid=pi,gid=pi"
# Filesystem-specific mount options
# ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="{mount_options},utf8,gid=100,umask=002"
ACTION=="add", ENV{ID_FS_TYPE}=="f2fs", ENV{mount_options}="$env{mount_options}"
ACTION=="add", ENV{ID_FS_TYPE}=="exfat", ENV{mount_options}="$env{mount_options},utf8"
# Create the mount point directory if it doesn't exist and mount the device
ACTION=="add", RUN{program}+="/usr/bin/mkdir -p %E{mount_point}", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=no --collect -o %E{mount_options} $devnode %E{mount_point}"
# Umount the device on 'remove' action (a.k.a unplug or eject the USB drive)
ACTION=="remove", RUN{program}+="/usr/bin/systemd-umount %E{mount_point}"
# Exit
LABEL="abort_rule"
EOF
# 增加可執行權限,并設置生效
# sudo chmod +x /etc/udev/rules.d/99-kboxext-mount.rules
sudo udevadm control --reload-rules
sudo udevadm trigger
# sudo systemctl restart udev
注意:
- 這里統一使用 pi 賬戶掛載,使得上傳 gcode 時有正確的讀寫權限
- 這里創建一個獨立的腳本,用于獲得符合 udev 規則的輸出變量
- 如何寫 udev 規則,之前有文章介紹過
- 不同系統 udev 規則文件位置和格式可能有差異,需根據實際操作系統版本和 udev 版本調整,遇到問題可查閱官方文檔或在技術論壇求助。
sudo udevadm test $(udevadm info -q path -n /dev/mmcblk0p1)是一個 很重要的故障排查命令
至此,我們可以實現插入移動存儲設備后,系統自動掛載到 /mnt/KBOX_EXT_* 目錄下。

- 預處理移動設備
- 在moonraker之前啟動mergerfs掛載, systemd service
- 識別到KBOX_EXT_開頭的設備則自動掛載到/mnt udev
3.2.3 創建 mergerfs 服務實現靈活擴容
創建 mergerfs 服務系統來實現系統啟動時自動創建虛擬目錄,且在 moonraker 服務之前啟動,以便能正確讀取 gcodes 目錄。
參考 mergerfs 官網并做了一些修改。
cat << _EOF_ > /tmp/mergerfs-klipper.service
[Unit]
Description = MergerFS Service for Klipper Hot-Swap Expansion
After = local-fs.target
Before = moonraker.service
[Service]
Type=simple
KillMode=none
ExecStart=$(which mergerfs) \
-f \
-o cache.files=auto-full \
-o category.create=epff \
-o func.getattr=newest \
-o dropcacheonclose=true \
/mnt/KBOX_EXT_SD/gcodes=RW,100M:/mnt/KBOX_EXT_U1/gcodes=RW,100M:$HOME/local_gcodes=RW,200M \
$HOME/printer_data/gcodes
ExecStop=$(which fusermount) -uz $HOME/printer_data/gcodes
Restart=on-failure
[Install]
WantedBy = multi-user.target
_EOF_
sudo mv /tmp/mergerfs-klipper.service /lib/systemd/system/mergerfs-klipper.service
sudo systemctl enable --now mergerfs-klipper.service
注意:
local-fs.target的核心用途是確保在系統啟動期間,所有本地文件系統(像根文件系統、/home、/var等分區)都能正確掛載。在達到這個目標狀態之后,系統才會繼續啟動其他依賴于本地文件系統的服務。- 注意需要
-f參數 - 注意這里的選項,為了保證文件完整性,啟用了緩存
- mergerfs 使用多種策略和選項控制優先寫入哪個目錄,這里選擇的策略為
epff,即如果存在目標文件夾則優先寫入,否則按由左至右首次發現的可用目錄寫入。 - mergerfs 默認只會向剩余可用空間大于 4G 的目錄寫入文件,由于我測試用的 mSD 卡是 4G 的(由于 1000/1024 實際不足4G,所以總不會寫入),需要增加額外參數
- 即使不存在可移動存儲,mergerfs 仍然可可以正確掛載
- local_gcodes 位于板載存儲,總是可用,但是至少留有 200MB
四、拓展內容
4.1 寫入策略問題
存儲設備寫入策略復雜,優先寫入哪個設備由策略、RW/RO/NC 掛載、保留的最少空間等因素決定。我們希望有 sd 卡插入時優先寫入 sd 卡,但默認最小保留空間為 4G,若磁盤所在文件系統可用空間少于 4G,系統就不會往該磁盤寫入數據。我測試時用的 4G sd 卡,格式化后可用空間不足 4G,導致系統一直不往 sd 卡寫入,這個問題排查了很久。另外,寫入策略還有先發現先寫入的特點,即先掛載的節點優先寫入。解決辦法一是更換容量更大的 sd 卡,確保格式化后可用空間大于 4G;二是深入了解系統存儲管理機制,根據實際情況調整寫入策略相關設置。例如,可通過修改 mergerfs 的配置文件,調整最小保留空間等參數,但這需要一定的技術基礎,操作前建議備份相關配置文件,以防設置錯誤導致系統異常。
4.2 通過 runtime 接口調試
mergerfs 的日志信息相當于沒有,需要參考官方文檔:https://trapexit.github.io/mergerfs/runtime_interfaces/ 使用運行時接口
sudo apt-get install attr
sudo mergerfs -f -o cache.files=off,func.getattr=newest,dropcacheonclose=false,category.create=all /mnt/KBOX_EXT/gcodes:/home/pi/local_gcodes=RO /home/pi/printer_data/gcodes
getfattr -n user.mergerfs.category.create /home/pi/printer_data/gcodes/.mergerfs
# 創建文件
sudo mergerfs -f -o cache.files=off,func.getattr=newest,dropcacheonclose=false,category.create=all /mnt/KBOX_EXT/gcodes=RW:/home/pi/local_gcodes=RO /home/pi/printer_data/gcodes
touch /home/pi/printer_data/gcodes/new-file
getfattr -n user.mergerfs.allpaths /home/pi/printer_data/gcodes/new-file
# 報錯 read-only fs
# 顯示所有值
getfattr -d /home/pi/printer_data/gcodes/.mergerfs
4.3 關于cache.files
4.4 支持參數化掛載多個目錄
目前僅以 gcodes 目錄演示,計劃增加 timelaspe 目錄,以及其他可能目錄。
4.5 UDEV 規則故障排查
當 udev 規則未生效時,可以按照以下步驟進行排查:
4.5.1 規則文件語法檢查
- 檢查規則文件路徑:確保規則文件存放在
/etc/udev/rules.d/目錄下,且文件名以.rules結尾,通常文件名以數字開頭(如80-kboxext-mount.rules),數字表示規則執行的優先級。 - 檢查語法錯誤:
udev規則文件使用特定的語法,任何語法錯誤都可能導致規則不生效。可以使用udevadm test命令來測試規則文件的語法。例如,對于規則文件80-kboxext-mount.rules,可以使用以下命令:
sudo udevadm test $(udevadm info -q path -n /dev/mmcblk0p1)
將 /dev/mmcblk0p1 替換為你要測試的實際設備。如果規則文件存在語法錯誤,該命令會輸出相應的錯誤信息。
4.5.2 設備屬性檢查
- 重新加載規則:有時候規則文件修改后,
udev可能沒有及時加載新規則。可以使用以下命令重新加載規則:
sudo udevadm control --reload-rules
- 觸發規則:重新加載規則后,需要觸發規則以使其生效。可以使用
udevadm trigger命令觸發設備的添加或移除事件。例如,對于設備/dev/mmcblk0p1,可以使用以下命令觸發添加事件:
sudo udevadm trigger --verbose --action=add --sysname-match=/dev/mmcblk0p1
sudo udevadm info -q path -n /dev/mmcblk0p1
sudo udevadm info -q env -n /dev/mmcblk0p1
4.5.3 設備屬性檢查
- 查看設備屬性:使用
udevadm info命令查看設備的屬性,確保規則中使用的屬性(如ID_FS_LABEL、ID_FS_TYPE等)與實際設備的屬性一致。例如,查看/dev/mmcblk0p1的設備屬性:
udevadm info --attribute-walk --name=/dev/mmcblk0p1
該命令會輸出設備的詳細屬性信息,檢查規則中使用的屬性是否正確。
- 檢查設備路徑和類型:確保規則中對設備路徑和類型的過濾條件符合實際設備。例如,如果規則中使用了
KERNEL或ENV{ID_PATH}進行過濾,需要檢查設備的內核名稱和路徑是否滿足條件。
4.5.4 權限和依賴檢查
- 檢查外部腳本權限:如果規則中使用了外部腳本(如
RUN指令調用的腳本),確保腳本具有可執行權限。可以使用chmod命令添加執行權限,例如:
chmod +x /path/to/your/script.sh
- 檢查依賴項:確保規則中使用的命令和工具(如
blkid、systemd-mount等)已經正確安裝,并且在udev運行環境中可用。
4.5.5 日志和調試信息查看
- 查看系統日志:
udev的相關信息通常會記錄在系統日志中,可以使用journalctl命令查看系統日志,查找與udev相關的錯誤信息。例如:
sudo journalctl -u systemd-udevd.service
- 添加調試信息:在規則文件中添加調試信息,使用
RUN指令將調試信息輸出到日志文件中。例如,在規則中添加以下內容:
ACTION=="add", RUN{program}+="/bin/echo 'Device added: %E{DEVNAME}' >> /var/log/udev_debug.log"
這樣,當設備添加事件觸發時,會將設備名稱記錄到 /var/log/udev_debug.log 文件中,方便查看調試信息。
通過以上步驟,應該能夠逐步排查出 udev 規則未生效的原因。
最終效果
經過一系列設置和優化,我們的方案基本達成預期目標。現在,既能從電腦拷貝切好的 gcode 文件,插卡就能直接打印,大大提高了打印效率;又實現了持久化擴容,有足夠空間存放模型切片文件、延時攝影素材等。熱插拔功能讓使用存儲設備更加便捷,有效解決了早期 Klipper 上位機存儲不足的問題,為 3D 打印工作提供了更穩定、高效的存儲解決方案。希望大家通過這篇文章,都能順利實現 Klipper 上位機的熱插拔自動擴容,享受更流暢的 3D 打印體驗。如果在實踐過程中遇到問題,歡迎隨時交流探討。
關于 AI 輔助寫作
多了一些廢話,還是需要人工參與大量校正
關于 AI 輔助編程
需要作者懂一些基礎編程知識,否則生成的代碼不可用都不知道如何 DEBUG
還需要我繼續學習如何更好地使用 AI 工具。

浙公網安備 33010602011771號