Use Gum in Nushell Script for Better UIUX

Charm 团队推出了一系列 CLI/TUI 工具,其中就包括 OpenCode 的前身crush: Glamourous agentic coding for all 💘

本文要介绍的 Gum 是 Charmbracelet 推出的另一个 CLI 工具,让你在 Shell 脚本中轻松添加交互式组件——选择菜单、文本输入、确认弹窗、加载动画等,不用手写 TUI 逻辑。

Install

brew install gum
scoop install charm-gum
# Archpacman -S gum

Common GOTCHAs

在 Bash/Zsh 等 UNIX-Compatible Shell 里用 gum 很简单,官方仓库也提供了示例,本文不再赘述。

Nushell 定义了一套不同的语法,在使用 gum 时与 Bash 有些许不同。

Text 📝

Nushell 中外部命令的输出可以直接赋值给变量,基本不会踩坑:

let choice = ^gum choose "feat" "fix" "docs" "chore" --header "Choose a language"print $choice
Note

当外部命令与 Nushell built-in command/alias重名时可以用 ^ 来明确调用外部程序。
加不加都行,但建议加上

关于多选

需要注意的就是多选。输出结果是多行文本,gum 的多行文本并不会被自动转成 list,需要自己处理类型

# 多选(--no-limit  --limit N)let langs = (gum choose --no-limit "Rust" "Go" "TypeScript" "Python")let lang_list = ($langs | lines)

同样,Nushell 的 list 不能直接 pipe 给 gum,需要先转成多行文本:

#  正确:先 join 成换行分隔的文本let items = ["apple", "banana", "cherry"]let pick = ($items | str join "\n" | gum filter)

不然就会得到如下输出:

$ let pick = ($items | gum filter)> Filter... ╭───┬────────╮   0  apple     1  banana    2  cherry   ╰───┴────────╯

Exit Code ☑️

在 Shell 中,命令的退出码 0 表示成功,非 0 表示失败;gum 的 confirm 子命令便是利用退出码反映用户的选择结果。

基于退出码,Bash 可以实现两种典型逻辑:

  • 当 Command 1 成功 → 执行 Command 2
  • 当 Command 1 失败 → 执行 Command 2

下面是对应的写法

# 先执行 command1#         # 若退出码为 0(成功)#         # 则继续执行 command2command1 && command2# 等价的 if 写法command1if [ $? -eq 0 ]; then  command2fi
# 先执行 command1#         # 若退出码  0(失败)#         # 则继续执行 command2command1 || command2# 等价的 if 写法command1if [ $? -ne 0 ]; then  command2fi

而在 Nushell 中,&& / || 这种 Bash 的「基于退出码的短路执行」并不存在。但 Nushell 同样提供了退出码,你可以用普通的 if 判断命令是否成功。

最直接的写法是读取 $env.LAST_EXIT_CODE

gum confirm;if $env.LAST_EXIT_CODE == 0 {     print "Deleting..."}

你也可以使用 () 操作符,Nushell 会依次执行 () 内的语句并返回最终的结果

因此可以把 gum confirm$env.LAST_EXIT_CODE == 0 包裹成一个 block,让代码变得更紧凑

if (^gum confirm; $env.LAST_EXIT_CODE == 0) {    print "Deleting..."}

也可为其封装一个函数:

def confirm [msg: string] {    ^gum confirm $msg    $env.LAST_EXIT_CODE == 0}if confirm "Delete file?" {    print "Deleting..."}

Cheatsheet

终端输出美化

gum style --foreground 212 --border-foreground 212 --border double --padding "1 2" --margin "1" "Hello from Nushell"╔══════════════════════╗                        Hello from Nushell                        ╚══════════════════════╝

常用参数:

  • --foreground / --background: 文字/背景颜色(数字或十六进制)
  • --border / --border-foreground: 边框样式(single, double, rounded 等)和颜色
  • --padding / --margin: 内边距/外边距(格式:"上下 左右""上 左右 下"
  • --align: 文本对齐(left, center, right
# 带时间戳的结构化日志gum log --time rfc822 --structured --level debug "Creating file..." name file.txt# 10 Mar 26 22:55 CST DEBUG Creating file... name=file.txt# 不同日志级别gum log --level error "Something went wrong"gum log --level info "Deployment complete"

--time 支持的格式:rfc822, unix, date, date-time, datetime 等。

# Markdown 渲染gum format -- "# Gum Formats" "- Markdown" "- Code" "- Template" "- Emoji"Gum Formats Markdown Code Template Emoji# 语法高亮cat main.go | gum format -t code# Emoji 解析echo 'I :heart: Bubble Gum :candy:' | gum format -t emoji
# 水平拼接gum join "A" "B" "C"# 垂直拼接gum join --vertical "A" "B" "C"# 配合 style 构建复杂布局let I = (gum style --padding "1 5" --border double --border-foreground 212 "I")let LOVE = (gum style --padding "1 4" --border double --border-foreground 57 "LOVE")gum join --vertical $I $LOVE

Spin

# 基本用法gum spin --spinner dot --title "正在安装依赖..." -- bun install# 显示命令输出gum spin --spinner dot --title "正在安装依赖..." --show-output -- bun installbun install v1.3.10 (30e609e0)Checked 274 installs across 321 packages (no changes) [14.00ms]

可用 spinner:line, dot, minidot, jump, pulse, points, globe, moon, monkey, meter, hamburger

Gum 美化

gum 的各子命令支持通过环境变量设置默认样式,避免每次调用都写一堆参数。喜欢 Catppuccin 的可以参考下面的步骤:

  1. 执行
    wget https://raw.githubusercontent.com/holo96/catppuccin-gum/refs/heads/main/gum-catppuccin.sh -O ~/.config/gum/theme.sh
  2. 在脚本中 source theme.sh
#!/usr/bin/env bash[ -f ~/.config/gum/theme.sh ] && source ~/.config/gum/theme.sh# ...

写在最后

一开始写这篇post的时候,感觉不如直接用 Bash 得了

但相信NuShell确实是更好的选择,跨平台matters

Use Gum in Nushell Script for Better UIUX

https://vluv.space/nushell_gum/

Author

GnixAij

Posted

2026-03-10

Updated

2026-03-10

License