前言
gum 是一个命令行工具, 它可以方便地为脚本提供TUI 交互能力。 本文以扩展 IRedis 为例,展示了 gum 的使用方法。
问题
IRedis 是一个非常好用的 redis 命令行客户端, 它提供很多方便实用的功能(语法高亮,自动完成等)
要连接到指定数据源 , 只要执行以下命令:
iredis --url 'redis://usr:passwd@foo-bar.com:6379?db=0'
但工作中经常需要连接不同的数据源,每次都需要输入不同的地址很麻烦。得记住每个数据库的地址和密码。 如果不能为数据源设置别名,命令行历史也无助于缓解心智负担。
iredis --url 'redis://usr:passwd@server-1.com:6379/0'
iredis --url 'redis://usr:passwd@server-2.com:6379/2'
iredis --url 'redis://:auth@server-3.com:6379'
...
好在IRedis 支持把数据源保存到指定配置文件中( .iredisrc
) 中,可以为数据指定别名, 其格式如下:
[alias_dsn]
dev=redis://localhost:6379/4
staging=redis://username:password@staging-redis.example.com:6379/1
有了 .iredisrc
文件之后, 就可以用 dsn 来连接不同的数据库了
iredis --dsn dev
iredis -d staging
虽然这样有助于降低心智负担,但还是有点不方便: 如果忘记了dsn 的准确名字, 还是无法快速完成连接。
如果能有从 iredisrc 读取数据源列表供用户选择, 无疑可以提高效率并降低心智负担。要达成这个目标, 可以分两个步骤:
解析别名
用 gum 提供列表选择并调用iredis
解决方案
先说解析别名
要解析.iredisrc
这个 ini 格式的文件, 最简单的办法是使用python 脚本:
import configparser
import os
config = configparser.ConfigParser()
config.read(os.path.expanduser('~/.iredisrc')) # read ini file
for key, _ in config.items('alias_dsn'):
print(key) # print all key in alias_dsn
上述脚本解析ini 文件,并打印出 alias_dsn 下的所有别名。
执行此脚本即可打印所有别名:
> python3 iredis.py
dev
staging
用gum提供选择能力
这时 gum
就可以出场了。结合前面写好的python脚本, 先读取别名列表, 用 gum filter
作选择, 然后用iredis打开选取的dsn
#!/usr/bin/env sh
DSN=$(python3 iredis.py | gum filter) # choose alias
iredis -d $DSN
最终效果如下:
更多思考
其实这个模式可以应用到所有类似场景。
例如,usql 这个数据库 cli 几乎支持所有RDBMS, 在日常使用中也存在同样的问题。 而 usql
又不像 iredis
, 它不支持在配置文件中保存数据源。
这时需要以某种形式来表达别名与数据源的对应关系, 然后传递给gum 进行选择。 遗憾的是 gum 目前不支持传入map 进行选择(虽然很久以前就有用户提出过这个需求, 但被开发团队拒绝掉了)。
不过我们可以用其中提到的思路,用shell 来达成目标:
#!/usr/bin/env sh
# define db alias map
DBMAP=$(cat <<END
dev => pg://user:pass@localhost/dbname?sslmode=disable
staging => mysql:/var/run/mysqld/mysqld.sock
prod => sqlserver://user:pass@remote-host.com/dbname
END)
# choose alias
ALIAS=$(echo "$DBMAP" | awk -F ' => ' '{print $1}' | gum filter)
# grep dsn
DSN=$(echo "$DBMAP" | grep "$ALIAS =>" | awk -F ' => ' '{print $2}')
# open db
usql $DSN
这样,我们就拥行了一个可以连接任何RDBMS的统一cli 客户端,如需连接其它数据库,只需要在脚本中增加一行即可
结论
有了 gum 的帮助, 我们可以方便地为任何 cli 程序增加 TUI 交互能力,增加其易用性。本文只是展示了 gum 的多项强大功能中的一项, 如有兴趣, 可以到 gum 官网了解更多。