装了 dsh-TUI 之后最需要先弄清的一件事是:它替换的多半是终端界面这一层,而不是 Harness 的会话执行层。任务怎么被调度、会话进程由谁托管、配置从哪个路径读,这些通常仍归 Harness;而按键映射、输入行编辑、输出渲染、状态栏这类终端内的交互,才可能被 dsh-TUI 接过去。判断方法是把同一件事用两种启动方式各跑一次,对照命令、回显、日志首行和进程表,而不是凭插件名字猜。两次运行的会话进程、配置读取路径、退出行为都一致时,原有命令和配置一般不用改;只要有一处不一致,就说明它确实动了那一层,需要逐项确认。
dsh-TUI 大概率只接管终端界面层,原 Harness 命令与配置通常可以沿用,但这是“通常”,要用同一任务两次运行的命令、回显、日志首行和退出后的进程快照来验证。插件复用旧配置路径则无需迁移,若读的是新路径,需显式指向或做软链接;退出后若仍有会话进程存活,说明生命周期归 Harness,脚本收尾要自己补结束逻辑。
同一条任务分别用原命令和 dsh-TUI 跑一遍
目的只有一个:把“输出与交互”这一段的变化,和“会话与任务”这一段的变化分开。先固定变量——同一工作目录、同一任务描述、同一配置来源、同一终端尺寸。下面两条命令分别执行,harness 换成你本机实际的可执行名,参数用你平时那条最简的。
# 第一次:原命令
harness run `--task` '列出当前目录结构' 2>&1 | tee /tmp/raw.log
# 第二次:经 dsh-TUI 启动
dsh-tui -- harness run `--task` '列出当前目录结构' 2>&1 | tee /tmp/tui.log如果 dsh-tui 不接受 -- 透传,先看 dsh-tui `--help` 里它自己声明的入口形式,按它给的方式传同一串参数;不同版本的入口写法不一致时,以本机 help 输出为准。两次跑完后对照:
- 一致点:任务输出正文、报错文案、生成的文件、读取到的配置路径、会话进程的可执行名。这些一致,说明会话层没被换掉。
- 差异点:提示符、按键响应、行编辑、颜色与边框、进度渲染、退出快捷键。这些差异基本都落在界面层。
对照时用 diff /tmp/raw.log /tmp/tui.log 看纯文本差异,再把差异行标成“格式类”和“内容类”。出现内容类差异(任务结果本身不同)时,不要急着归因于插件,先确认两次的配置与工作目录是否真的一致。
查配置是从哪个路径读进来的
判断复用与否,不看说明,看进程实际打开的文件。启动后先拿到会话进程号,再读它打开的描述符:
pgrep -af harness
ls -l /proc/<pid>/fd | grep -Ei 'conf|config|toml|yaml|json'
tr '\0' '\n' < /proc/<pid>/environ | grep -i -E 'config|home|xdg'如果 strace 可用,也可以在启动阶段只抓打开动作:strace -f -e trace=openat -o /tmp/open.log dsh-tui ...,然后在 /tmp/open.log 里筛出配置文件行,注意区分哪些是 dsh-TUI 自己打开的、哪些是它拉起 harness 之后由 harness 打开的,父进程号能分开这两者。
接着做一次可观察项修改:挑一个改了马上能看出效果的开关(例如是否彩色输出、日志详略、默认工作目录),只改一个,重启后看行为是否跟着变。行为跟着变,说明这个路径确实被读取;行为没变,说明 dsh-TUI 走的是另一个路径,或者有更高优先级的环境变量把它覆盖了。同一时刻只改一项,否则分不清是哪一项生效。不要凭字段名猜默认值,用你本机文件里实际写的内容做对照。
观察会话启动时第一行日志由谁打印
会话生命周期归谁,看第一行日志的发出者。抓取时给每行带上时间:
dsh-tui -- harness run ... 2>&1 | awk '{ print strftime("%H:%M:%S"), $0 }' | tee /tmp/start.log同时另开一个终端,在启动前后各记一次进程快照:
ps -eo pid,ppid,lstart,cmd | grep -Ei 'dsh|harness'判断依据是时间顺序和父子关系:如果 /tmp/start.log 的首行来自 Harness 自己的初始化信息,且 dsh-tui 进程在进程表里是 harness 的父进程或兄弟进程,那么会话由 Harness 建立、dsh-TUI 只做了包装;如果首行是 dsh-TUI 打印的会话创建信息,且 harness 是它 fork 出来的子进程,那么启动这一段至少归插件。进程的 PPID 与启动时间(lstart)比日志文案更可靠,因为文案可能被插件改写。两者结论不一致时以进程表为准,再看 dsh-TUI 的启动参数里是否把会话交给了外部进程。
退出插件后检查残留进程
退出要按插件声明的正常方式做(通常是快捷键或连续两次 Ctrl+C),然后比对退出前后的进程快照:
pgrep -af harness > /tmp/before.txt
# 在 dsh-TUI 内正常退出
pgrep -af harness > /tmp/after.txt
diff /tmp/before.txt /tmp/after.txt结论按三种写法落笔即可:一是两次快照的 PID 集合相同,说明会话进程在 dsh-TUI 退出后仍然存活,生命周期归 Harness,收尾脚本里要自己补结束逻辑;二是退出后对应 PID 消失,说明由 dsh-TUI 一并结束;三是同一 PID 仍在,但状态列变成僵尸或挂着不响应,这通常说明子进程没被正确回收,需要结合 ps -o pid,ppid,stat,cmd -p <pid> 确认父进程是否还在。退出前后都记录完整命令行,避免把同名进程认成同一个。若你在脚本里批量启动多个 dsh-TUI,残留进程数会随启动次数累积,建议把上面的快照命令放进收尾步骤,而不是只在排查时手动跑一次。