dialog是终端文本界面菜单工具,非GUI但支持颜色、阴影、对齐;--menu需指定height/width/menu-height三参数,tag-item成对且不可含空格,2>/file重定向捕获选择,ESC返回255。

能,但“精美”是相对的——dialog 生成的是带颜色、阴影、对齐和结构的文本界面菜单,不是 GUI 窗口,也不依赖 X11。它在纯终端(如 SSH、tty1)里就能跑出远超 select 的交互体验。
dialog --menu 最简可用写法
直接运行这行命令就能弹出一个可操作菜单:
dialog --title "部署选项" --menu "请选择服务:" 12 40 5 \ 1 "MySQL" \ 2 "Nginx" \ 3 "PHP" \ 4 "Redis" \ 5 "退出" 2>/tmp/choice
关键点:
-
--menu后必须跟height、width、menu-height(可视项数),少一个就报错dialog: unknown option - 每对
tag item必须成对出现,比如"1" "MySQL",不能漏引号或错位 -
2>/tmp/choice是必须的:用户选中后,tag(如1)会输出到 stderr,重定向进文件才能捕获 - 选完按回车,对话框消失,脚本继续执行;按
ESC退出返回状态码 255
让菜单看起来“不寒酸”的 4 个实操技巧
默认灰白菜单确实朴素。加这几项就能明显提升质感:
- 加
--colors+\Z序列控制颜色,例如"\Z1MySQL\Zn"让 MySQL 变红色(\Z1是红,\Zn恢复默认) - 加
--shadow给菜单底部加一层阴影,视觉上更“浮起” - 加
--backtitle "v2.3.1"在顶部显示小字版本信息,比光秃秃的--title更专业 - 用
--default-item "2"预选中第二项(比如默认进 Nginx),减少用户按键次数
组合起来像这样:
dialog --colors --shadow --backtitle "Server Setup v2.3.1" \
--title "? 服务管理" \
--default-item "2" \
--menu "请选择要操作的服务:" 14 45 6 \
1 "\Z3MySQL\Zn" \
2 "\Z2Nginx\Zn" \
3 "\Z6PHP\Zn" \
4 "\Z4Redis\Zn" \
5 "\Z7Memcached\Zn" \
6 "\Zr退出\Zn" 2>/tmp/choice
常见失败原因:为什么菜单一闪就没了或报错
实际写脚本时最常卡在这几个地方:
- 忘记
2>file重定向 → 脚本卡住不动,或报Can't open /dev/tty - 高度
height设太小(比如5),而菜单项超过 5 行 → 直接崩溃,提示Dialog error: height too small - 在非交互式环境(如 cron 或
nohup)里调用 → dialog 无法访问终端,报TERM environment variable not set,必须加export TERM=xterm前置 - 中文标签没设 locale → 出现乱码或错位,确保脚本开头有
export LANG=zh_CN.UTF-8
menu 和 checklist/radiolist 的核心区别在哪
别一上来就硬套 --menu,先看需求本质:
- 用
--menu:适合“单选且跳转”,比如主菜单 → 进子菜单 → 执行动作。每个tag是逻辑入口,不是数据本身 - 用
--radiolist:适合“单选且取值”,比如选“安装路径”:"1" "/opt/app" "on",用户选完直接拿到路径字符串 - 用
--checklist:适合“多选批量操作”,比如勾选多个服务重启:"mysql" "MySQL Server" "on",输出是多行tag - 注意:
--menu不支持on/off状态,--radiolist和--checklist才需要显式声明初始状态
真正容易被忽略的是:menu 的 tag 必须是唯一、无空格的标识符(如 nginx_start),别用中文或带空格的字符串当 tag —— 后续 case 分支匹配会失效。


















