You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于dialog的Calibre书籍添加Bash脚本问题求助

Calibre书籍批量添加脚本问题排查与修复

以下是针对你的Bash脚本问题的逐一解决方案:


问题1:首次选择M进入form_data正常,其他子菜单后再选M失效

原因

form_data函数中修改了全局的IFS(内部字段分隔符)为$'\n'但未恢复原值,导致后续dialog的输出解析异常。

修复代码

function form_data() { 
    local auth="" serie="" tag="" ind="1"
    # 保存原始IFS
    local OLD_IFS="$IFS"
    IFS=$'\n'

    echo "form data" 
    exec 3>&1
    VALUES=($(dialog --clear --ok-label "Submit" \
          --backtitle "Calibre" \
          --title "Manager" \
          --form "Add a book" \
        15 50 0 \
        "Author's name:" 1 1    "$auth"     1 20 30 0 \
        "Serie's name:"    2 1  "$serie"    2 20 30 0 \
        "Tag:"    3 1   "$tag"      3 20 30 0 \
        "Serie's index (int):"     4 1  "$ind"  4 20 30 0 \
        2>&1 1>&3))
    
    exec 3>&-
    # 恢复原始IFS
    IFS="$OLD_IFS"
    # 直接返回,由主循环重新显示菜单
}

问题2:case语句启动报错,改用if语句

原因

大概率是case语法不规范(变量未加引号、分支格式错误),以下是正确的case写法:

function main_menu(){
    local MENU=$(dialog --clear --title "Calibre" \
        --backtitle "Add Books" \
        --menu "What to do ?" \
        0 0 0 "C" "Choose a book or a folder" "M" "Enter metadata infos" "L" "Add selected Book(s)" "D" "Change default Directory for books" "E" "Exit" \
        2>&1 >/dev/tty)
        
    # 处理用户按下Cancel的情况(MENU为空)
    if [ -z "$MENU" ]; then
        return
    fi

    case "$MENU" in
        "C")
            select=$(file_selector "$mnt")
            ;;
        "M")
            form_data
            ;;
        "L")
            if [ -d "$select" ]; then
                add_folder "$select"
            elif [ -f "$select" ]; then
                # 修复原代码中$file的错误,应为$select
                if [[ "$select" == *.cbz || "$select" == *.pdf ]]; then
                    add_book "$select"
                else
                    error "Books should have extensions .cbz or .pdf"
                fi
            else
                error "No file or folder selected"
            fi
            ;;
        "D")
            NEWDIR=$(file_selector "$mnt")
            # 将新目录赋值给mnt,确保下次生效
            mnt="$NEWDIR"
            ;;
        "E")
            exit 0
            ;;
    esac
}

额外说明

  • 所有变量引用加双引号,避免空格导致的参数拆分问题
  • 增加用户按Cancel时的处理逻辑

问题3:error信息对话框无法正常工作

原因

  • $1未加双引号,错误信息含空格时会被拆分,导致dialog参数错误
  • 递归调用main_menu会导致函数栈嵌套过深,建议用主循环替代

修复代码

function error() {
    dialog --clear --title "Error" --msgbox "$1" 10 50
    # dialog会等待用户点击OK,无需sleep
    # 直接返回,由主循环重新显示菜单
}

# 主脚本入口用循环代替递归
while true; do
    main_menu
done

问题4:form_data提交后调用main_menu是否正确

结论

递归调用main_menu是错误的,会导致函数栈不断累积最终溢出。正确做法:

  1. 主脚本用while true循环反复调用main_menu
  2. 所有子函数(form_data、add_folder等)执行完成后直接返回,由主循环重新显示主菜单

调整后的主脚本结构

#!/bin/bash

# 初始化全局变量
mnt="/path/to/default/directory"
select=""
VALUES=()

# 此处放置所有函数定义...

# 主循环
while true; do
    main_menu
done

问题5:实现dialog进度条

方案1:自定义进度条(适用于calibredb无进度输出的情况)

自己计算文件数量,逐个添加并更新进度:

function add_folder() { 
    local folder="$1"
    # 仅筛选cbz/pdf文件
    local book_list=($(find "$folder" -maxdepth 1 -type f \( -name "*.cbz" -o -name "*.pdf" \)))
    local total=${#book_list[@]}
    local current=0

    # 初始化进度条
    dialog --clear --title "Adding Books" --gauge "Starting..." 10 60 0

    for book in "${book_list[@]}"; do
        current=$((current+1))
        local progress=$((current*100/total))
        # 更新进度条内容
        echo "$progress" | dialog --clear --title "Adding Books" --gauge "Adding: $(basename "$book")" 10 60 0
        # 执行添加命令,屏蔽输出避免干扰进度条
        calibredb add -a "${VALUES[0]}" -s "${VALUES[1]}" -T "${VALUES[2]}" -S "$current" "$book" --with-library /home/gregory/books >/dev/null 2>&1
    done

    # 完成后提示
    dialog --clear --title "Done" --msgbox "Successfully added $total books" 10 50
}

方案2:使用进度框(适用于calibredb有详细输出的情况)

如果calibredb add有日志输出,直接将输出传给dialog:

function add_folder() {
    local folder="$1"
    calibredb add -a "${VALUES[0]}" -s "${VALUES[1]}" -T "${VALUES[2]}" --with-library /home/gregory/books "$folder" 2>&1 | dialog --clear --title "Adding Books" --progressbox 20 60
    dialog --clear --title "Done" --msgbox "Add operation completed" 10 50
}

原代码额外修复

  • 原循环变量i未初始化,数组索引从0开始,直接用数组遍历更可靠
  • 增加文件类型过滤,避免无效文件被添加

内容的提问来源于stack exchange,提问作者rhadamanthe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 20:25:53