把 dmenu 和 LLM 凑一起:AI 生成 Linux 桌面小脚本的实战指南

发布时间:2026/10/13 12:01:20

把 dmenu 和 LLM 凑一起:AI 生成 Linux 桌面小脚本的实战指南 把 dmenu 和 LLM 凑到一起是我最近几天干得最随意、但也最划算的一件事。标题里的 slops你们可以理解成 scripts 的口语变体当然也带着点自嘲这些脚本确实带着“半成品”式的随性因为它们不是我一句一句手敲出来的而是让大语言模型按我的需求生成初版我再审、再改、再补边界。dmenu 是老牌的 Linux 动态菜单工具配合窗口管理器做快速启动、顺手小工具都非常合适而 LLM 生成 shell 脚本的能力放在这种“列一个菜单、选一项、执行一个命令”的重复模式上意外地契合。这篇文章我就拿这套脚本库当样本聊聊 dmenu 为什么值得折腾、LLM 生成的 shell 脚本有哪些坑、以及我是怎么把一堆“AI 初稿”收拾成能天天用的工具。适合玩过 Linux 桌面、想把手头操作再省几步的朋友。没有太高门槛有一点 shell 基础就能跟上哪怕你没写过 dmenu 脚本看完也能自己上手造一个。1. 为什么是 dmenu为什么是 LLM1.1 dmenu 这个“笨工具”为什么还值得玩dmenu 的本质特别简单从标准输入读入一堆文本行显示成一个可过滤的菜单用户用键盘输入关键字缩小范围方向键选择回车后把选中的那一行打印到标准输出。整个过程一句话就能说完但它几乎覆盖了“从一组选项里快速挑一个”的全部场景。你可能会问现在不是有 rofi、fzf 这些更花哨的工具吗我也用过 rofi它的主题、插件、自定义布局确实很能打但 dmenu 有一个不可替代的优势依赖少、行为可预测、在任何脚本里都能直接调用。它不是一个需要常驻的图形程序就是一个普通二进制几个参数一传就出结果。对写脚本的人来说这种“管道中间件”式的设计反而最顺手。我平时在窗口管理器里做快速启动用 dmenu_run但真正高频用的是自己脚本里直接调 dmenu输入待办、挑剪贴板、翻书签、切窗口全都是一行 dmenu 加上前后管道的事。另一个被低估的点是它的键盘流交互。鼠标都不需要碰输入几个字符回车完事。这个交互模式特别适合一天要重复几十次的场景。dmenu 还有一些实用参数比如-i忽略大小写、-l控制显示行数、-p设置提示文字配合这些参数写出来的小工具使用体验非常接近一个原生应用。1.2 “slops”背后的定位LLM 生成脚本是脚手架不是成品标题里我用了 slops其实就是 scripts 的口语说法但也坦白承认这些脚本的初稿质量差不多是“能用但别细看”。LLM 擅长的不是从零解决复杂架构问题而是把一段自然语言描述翻译成结构正确、命名合理的代码骨架。这个特点放在 dmenu 脚本上刚好合适dmenu 脚本大多短小、模式固定、拼的就是参数和流程组合这正是生成模型最拿手的。但我也见过不少人犯一个错误把 LLM 输出的脚本当最终产物直接扔到 PATH 里用。第一次跑可能没问题等换了台机器、改了路径、遇到含特殊字符的输入问题就全冒出来了。所以我坚持一个定位LLM 在我这里的角色是“结对编程的合作者”它出初稿我管边界。理解到这个层面你就能明白为什么标题里叫 slops 反而好笑因为我自己很清楚这些脚本真正的价值是在我审过、改过、跑过之后才出现的。2. 这套 dmenu 脚本库的组成与总体设计2.1 目录结构与安装方式脚本库我没有用太复杂的组织方式就放在~/bin下原因是大多数 Linux 桌面环境默认会把~/bin加入 PATH脚本放进去之后可以直接用文件名调用不需要再写全路径。为了让 dmenu 相关脚本彼此共享配色和函数我单独抽了一个公共文件libdm.sh其他脚本通过source加载它。~/bin/ ├── dm-todo # 快速添加待办 ├── dm-clip # 剪贴板历史 ├── dm-bookmarks # 书签搜索打开 ├── dm-window # 窗口切换 ├── dm-power # 关机 / 重启 / 锁屏 └── libdm.sh # 公共函数与配色安装方式很简单把脚本放进~/bin然后chmod x然后在窗口管理器里绑定快捷键。不需要什么安装器也不往系统目录塞东西这符合 dmenu 本身的极简气质。换机器的时候把这个目录拷过去就行最多再装一下依赖命令。2.2 脚本清单与各自解决的痛点我挑脚本时遵循一条原则每次操作如果能省下超过五秒就值得写一个 dmenu 脚本。下面这几个都是高频操作。脚本核心功能依赖解决什么痛点dm-todo输入一条待办带日期追加到 Markdown 文件dmenu, date打开编辑器、移动光标、写日期太麻烦dm-clip保存剪贴板历史再次选择并复制dmenu, xclip复制内容后想找回上一条全靠剪贴板历史dm-bookmarks从本地书签 TSV 中按标题搜索并打开dmenu, xdg-open浏览器书签栏太多找起来费劲dm-window列出当前窗口标题选择后聚焦dmenu, wmctrl鼠标一个个点窗口太慢dm-power锁屏 / 退出 / 重启 / 关机菜单dmenu, systemctl, loginctl避免手敲命令误操作概率也低每个脚本的核心逻辑其实都是同一个模式准备数据送给 dmenu拿到输出之后做一件事。这种统一性让维护成本非常低也让 LLM 特别容易理解你的需求因为每次生成新脚本时我可以直接拿一个现有脚本当范例给它参考。2.3 公共函数与统一交互公共文件libdm.sh里我放了两个东西一个是 dmenu 参数模板一个是报错函数。# libdm.sh DM_FONT${DM_FONT:-monospace-11} DM_COLORS(-nb #1e1e2e -nf #cdd6f4 -sb #89b4fa -sf #11111b) dm_prompt() { local prompt$1 dmenu -i -p $prompt -fn $DM_FONT ${DM_COLORS[]} $ } die() { echo dm: $* 2 exit 1 }为什么要这样设计因为所有脚本都要用同一套字体和配色把参数集中到一处改主题时只动一个文件。dm_prompt里的$还可以让单个脚本传入额外参数比如限制行数-l 15这样公共函数不会限制脚本自己的灵活性。3. 从需求到交付LLM 生成 dmenu 脚本的完整过程3.1 Prompt 怎么给才不容易跑偏让 LLM 生成脚本失败率最高的环节其实不是代码能力而是需求描述。我给过一个“模板化”的 prompt效果比自由发挥好很多分享出来供你们参考你是一个熟练的 Linux shell 脚本开发者。请帮我写一个 bash 脚本路径会放在 ~/bin 下用于通过 dmenu 实现 XXX 功能。 需求细节 1. 使用 dmenu 显示菜单/读取输入用户按 ESC 取消时脚本静默退出。 2. 使用 set -euo pipefail。 3. 依赖的系统命令如 wmctrl、xclip、xdg-open不存在时给出中文提示后退出不产生堆栈报错。 4. 数据文件位置放在 ${XDG_CACHE_HOME:-$HOME/.cache} 或 $HOME 下的固定路径不要写死 /tmp。 5. 代码注释用中文说明每个函数的作用。 6. 如果某项需求在技术上无法实现直接告诉我不要编造命令。每条要求都是有原因的。第 1、2 条解决的是脚本健壮性用户 ESC 退出的场景太常见如果没有处理空字符串会往下执行轻则写一条空记录重则执行一个空命令。set -euo pipefail能让脚本在变量未初始化、管道中断时立刻发现问题。第 3 条解决的是不同机器环境差异换一台机器没有对应命令脚本至少要给出明确提示而不是甩一段 bash 报错。第 4 条把数据放在缓存或家目录避免临时文件丢失。第 5 条为了让后续好维护——LLM 生成的英文注释我经常看不下去。这个 prompt 的核心逻辑是把你对工程质量的要求转化为显式约束让 LLM 在生成时就遵守而不是生成后再靠人肉补。3.2 第一次生成的代码长什么样以dm-todo为例LLM 第一次给出来的脚本大概是这样的#!/bin/bash # dm-todo - 快速添加待办 set -euo pipefail item$(dmenu -p TODO: -fn monospace-11) echo - [ ] $item $HOME/todo.md五行的确很短功能也基本成立弹出一个输入框把文字追加到todo.md。但你细看会发现至少三个问题。第一用户按 ESC 或者输入一个空字符串时脚本照样往文件里追加内容于是你可能得到一行没有内容的- [ ]。第二$HOME/todo.md如果不存在会创建文件但如果是$HOME/notes/todo.md这种带目录的路径目录不存在直接报错脚本就死在 echo 这行。第三没有日期信息事后整理待办时光靠记忆判断“这条是什么时候记的”很不方便。这类问题非常典型LLM 善于生成“主路径”也就是输入、处理、输出的主干但不善于考虑“用户中途取消”“目标目录不存在”“数据格式需要更丰富”这些分支场景。所以我对初稿的态度是先看主逻辑对不对再逐条补边界。3.3 人工修正三件事取消路径、目录初始化、数据格式针对dm-todo的问题我把它改成了下面这个版本改动集中在三处。#!/bin/bash # dm-todo - 快速添加带日期的待办事项 set -euo pipefail TODO_FILE${TODO_FILE:-$HOME/todo.md} # 取消或输入内容为空白时静默退出 item$(dmenu -p TODO: -fn monospace-11 -i) || exit 0 item$(echo $item | sed s/^[[:space:]]*//; s/[[:space:]]*$//) [[ -z $item ]] exit 0 # 确保目标目录存在再写入带日期的条目 mkdir -p $(dirname $TODO_FILE) printf -- - [ ] %s %s\n $(date %Y-%m-%d %H:%M) $item $TODO_FILE第一处是|| exit 0dmenu 在用户按 ESC 退出时返回非零退出码这句确保了取消操作不会写入任何内容。第二处是去除首尾空格后判断空字符串避免用户不小心只敲了空格就回车。第三处是mkdir -p和printf --前者保证目录存在后者保证待办内容开头是-时不会被 printf 当成选项。这类修改我建议你不要光看结果要想清楚为什么。改完之后的效果不只是一个待办脚本更可靠了更重要的是我得到了一套“可复制的修改模式”以后每次让 LLM 生成新脚本我都会自动检查这三件事——用户取消、依赖存在、数据格式。检查一次省掉后面很多次返工。4. 实操落地把脚本接进日常桌面工作流4.1 窗口管理器快捷键绑定脚本写好后下一步是把它绑定到快捷键上。我这套环境用的窗口管理器支持自定义键位配置方式和大多数 X 环境类似。以 i3 风格为例你可以在配置里写bindsym $modt exec --no-startup-id dm-todo bindsym $modp exec --no-startup-id dm-clip pick bindsym $modb exec --no-startup-id dm-bookmarks bindsym $modw exec --no-startup-id dm-window bindsym $mode exec --no-startup-id dm-power这里有个细节exec --no-startup-id很重要。它告诉窗口管理器不要等待启动通知否则 dmenu 这种快速弹出的窗口有时会出现焦点不对、甚至不显示的问题。我一开始偷懒没加这个参数结果好多脚本偶尔失灵还以为是脚本本身的问题后来发现是窗口管理器在等启动通知应用已经结束了它还在等。如果你用的是 dwm 这类从源代码配置的窗口管理器那一套也是一样的思路在config.h里增加一个按键绑定指向对应脚本。不明说也不用担心核心就是让 dmenu 脚本在按下快捷键后立刻获得焦点所以我在绑定快捷键后都会习惯性加一句“按一下看窗口是否直接弹出来并且能直接输入”。4.2 让 dmenu 好用的三个关键参数外观不是 dmenu 的重点但顺手程度影响很大。我常用三个参数组合这里展开说一下。-i让过滤忽略大小写。默认情况下dmenu 的过滤区分大小写输入abc匹配不到ABC这对于英文书签、窗口标题来说很别扭。加上-i之后匹配宽松得多几乎不会出现“明明有这个选项却搜不到”的挫败感。-l控制列表行数。当选项太多时比如剪贴板历史有一百多行如果不限制行数dmenu 会变成一个塞满整个屏幕的巨大菜单。我给dm-clip固定-l 15让菜单只显示 15 行配合方向键上下滚动视觉更轻选择速度也更快。-fn指定字体。如果你有中文菜单项比如待办内容是中文而字体配置里没有中文字体dmenu 会显示一堆方块。我选择的是一个等宽字体保证中英文混排时对齐不混乱。具体字体取决于你的系统里装了什么可以用fc-list查一下再填入。这三个参数不是越多越好dmenu 本身追求极简配色我也只是配了一套深色底、亮色高亮保证长时间盯屏幕不刺眼就停手了。4.3 数据文件与隐私边界dmenu 脚本最大的隐患不是技术而是数据落盘后的隐私边界。最典型的是剪贴板历史一旦你开始记录剪贴板内容就相当于把复制过的密码、银行卡号、私聊消息全部写进了明文文件。我的处理方式有两条。第一数据文件放在${XDG_CACHE_HOME:-$HOME/.cache}下并且权限只让当前用户可读写umask 077第二剪贴板历史脚本里加一个clear参数执行后删除历史文件。定期清理和数据自毁能力必须存在否则这类工具用久了就成了隐私黑洞。书签数据同理虽然它不如剪贴板敏感但也要注意不要让脚本偷偷把数据发送到任何外部网络地址。还有一个容易被忽略的点LLM 生成的脚本里有时会自作主张地加一些不相关的网络请求。我在审查代码时有一条硬性规则所有纯本地操作的 dmenu 脚本禁止任何网络访问。筛选标签、剪贴板、系统操作根本不需要联网。这一条规则在 prompt 里也写明了但还是会在人工审查时再确认一遍。5. 踩坑实录与排查速查5.1 LLM 生成脚本里最典型的几种“幻觉”和 LLM 打交道多了我整理了一份高频问题清单基本覆盖了它写 shell 脚本时最常见的错误。第一用了当前系统根本不存在的命令或 flag。它可能基于训练数据里的通用 Linux 环境写出了grep -P但你的环境用的是别的 grep 实现压根不认识-P或者写出了某个工具的旧版参数新版已经废弃。这类问题只有实测才能暴露所以脚本写完一定要立刻跑一遍。第二变量和文件路径没有按你的实际环境处理。比如它可能写死了/home/user/todo.md但换一台机器用户名不同脚本就失效。我一般会在 prompt 里明确要求使用$HOME或环境变量但偶尔它还会写半个绝对路径出来。第三对“用户取消”的处理过于乐观。很多初稿根本没有|| exit 0这类保护或者只是简单判断变量是否为空没考虑到用户可能只输入空格。上面dm-todo的例子就是典型。第四会出现“用大炮打蚊子”的味道。明明一个 shell 脚本就能搞定的事LLM 可能给你生成一个 Python 脚本还要 import 一堆库。所以我的 prompt 里会明确要求“使用 bash 脚本不要使用 Python”至少能省掉一层解释器的依赖。5.2 快速定位问题的一套流程dmenu 脚本出问题时别急着找 AI 要答案先自己走一遍排查流程。我推荐的顺序是这样的。第一步先手动执行脚本本身。在终端里直接输脚本名如果你发现 dmenu 根本没弹出来多半是 DISPLAY 环境变量问题常见于在 tmux 或定时任务里运行如果 dmenu 弹出来了但选择后没反应问题多半出在管道后面。第二步用静态数据测试。比如把cat data.txt | dmenu这半条命令单独跑确认 dmenu 能正常显示和输出。不要一上来就跑完整脚本这样能快速定位问题在前半段还是后半段。第三步开启调试输出。在脚本开头加上set -x所有变量展开和命令执行都会被打印出来。我看到很多朋友不爱用这个觉得输出刷屏但在复杂参数场景下它是最快的定位方式。定位完再删掉即可。第四步检查执行权限和文件格式。LLM 生成的脚本有时行尾是 CRLF这在 Linux 下直接执行会报bad interpreter。chmod x这种低级问题也很常见。我一般用file命令确认一下格式再用bash -n做语法检查。5.3 常见问题速查表症状可能原因处理方法dmenu 窗口完全不显示DISPLAY 未设置或用了--no-startup-id未生效手动运行脚本检查echo $DISPLAY在 tmux 里需要先设置 DISPLAYdmenu 显示了但选择后没反应管道后的命令没有正确执行或输出没有接管道单独执行 dmenu 后半段命令确认输出内容检查xargs/while read用法中文显示成方块字体未包含中文字形用fc-list查可用字体在-fn中指定中文字体脚本退出但报错信息不明显缺少错误处理检查是否有die函数看set -x输出最后一条命令每次执行结果都一样像缓存数据文件没更新或权限不对查看数据文件是否写入成功检查umask在窗口管理器快捷键下无效快捷键配置语法错误或未重新加载配置重新加载窗口管理器配置先手动执行脚本确认可用脚本切到别的机器后报命令不存在环境差异查看脚本依赖用依赖检查函数给出提示并安装缺失命令这张表我平时就贴在脚本目录的 README 里每次新装机器踩到同样的坑扫一眼就知道怎么处理。6. 让 LLM 写脚本这件事的最终体会6.1 LLM 是结对编程的下游不是替代品把这套流程跑熟之后我对“用 LLM 写代码”的认知发生了改变。它不是替代品更像是有一个经验尚可但不太细心的同事坐在旁边你告诉它怎么做它给你一版代码剩下的活还是你的你得解释环境、修正边界、补充错误处理最后为结果负责。最明显的例子是dm-clip。我让 LLM 生成初稿它很快就写出一个能用的版本从剪贴板取内容存文件、再用 dmenu 选出来重新复制。但真实使用中遇到的问题比如历史文件越来越长、重复内容反复出现、换行符被吞掉之类的LLM 在没有看到具体报错时很难凭空猜出来。我要求它加一个去重逻辑它加上了我要求它只保留最近两百条它也执行了。整个过程里我只管给方向和验收它管查漏补缺。这种工作模式如果处理得当效率确实比纯手写高很多但前提是你得是一个合格的“验收者”而不是一个只会复制粘贴的人。6.2 维护这套“AI 脚本库”的现实建议最后给几条维护层面的建议都是我在实际使用中总结出来的。第一所有脚本坚持单一职责。一个脚本就干一件事加待办就只加待办剪贴板就只管剪贴板。LLM 有时候会“自由发挥”把两个功能揉在一个脚本里这种情况下我会要求拆开。脚本越短越容易审查越难出大问题。第二公共参数抽离到libdm.sh。字体、颜色、dmenu 参数一旦要调整只需要改一个文件。如果没有这层抽象你会发现自己在一个脚本里改了配色回头忘了改另外一个桌面上出现两种风格的 dmenu 菜单很别扭。第三把 prompt 模板沉淀下来。我现在新建脚本时会把已有的 prompt 拿出来改一下功能描述其他工程约束几乎一字不变。这相当于把你的质量标准固化成模板每次生成的初稿质量都稳定在及格线以上省去大量重复沟通。第四为脚本建一个简单 README。不需要写长文只要列清楚每个脚本的依赖、参数、数据文件路径。这台机器上你可能记得所有细节三个月后换台新机器你就需要这份文档了。README 也可以直接丢给 LLM让它照着已有脚本风格生成新脚本效果出奇地好。我现在的习惯已经变成先在 README 里写下新脚本的一句话需求再把它连同libdm.sh的说明一起发给 LLM拿到初稿后跑一遍、改掉边界问题、加进~/bin完事。dmenu 仍然是那个极简的老工具但有了这套 AI 辅助流程之后它的上限一下子高了不少。如果你手头也有类似的小工具需要写不妨照着这个路子试一遍你会回来感谢当初没一头扎进图形界面开发里的自己。
延伸阅读

更多相关文章

2026/10/13 12:01:20

Python实战ZooKeeper:从连接、监听、分布式锁到避坑指南

1. 为什么分布式系统里总绕不开 ZooKeeper第一次接触 ZooKeeper 的人,十有八九是被"分布式协调"这四个字劝退的。听起来像是某种高深的架构黑魔法,实际上你可以把它理解成一个高可用的分布式文件系统加通知机制——它对外暴露的接口非常像操作…

2026/10/13 12:01:20

Token优化实践:JWT瘦身、双Token机制与Redis黑名单

之前做微服务接口认证时,一直被 Token 的体积和过期策略折磨。JWT 越写越长、刷新逻辑绕来绕去、退出登录之后 Token 还能用……这些问题网上资料很多但都比较零散。本文整理了一份完整的 Token 优化实践手册,覆盖 JWT 原理、字段瘦身、双 Token 机制、R…

2026/10/13 13:06:38

SpringBoot猫咖管理系统:从选题到部署的毕设全攻略

带了几届毕业生之后,每年到了三四月份总有人来问我同一句话:毕设到底选什么题目既好写又能过。今年问得最多的是Java方向,而且越来越多的人把目光放到SpringBoot系的项目上。如果你也在物色一个贴近生活、业务完整度够、答辩时还有东西可讲的…

2026/10/13 13:06:38

CFF_Explorer:二进制CFF表解析与逆向排查实战

简介:CFF_Explorer 是一款面向程序员、逆向工程师与安全研究人员的 Windows 文件格式分析工具,尤其擅长解析 PE 可执行文件,可查看并编辑文件头、节区、资源、导入导出表及代码签名等关键结构,适用于软件调试、恶意软件分析与格式…

2026/10/13 13:06:38

Flink CDC 3.0 实战:MySQL 到 Doris 实时同步与断点续传

简介:这份资源是尚硅谷研究院编写的Flink CDC 3.0技术文档,面向有一定Flink基础、从事大数据处理与实时数据同步的研发工程师,帮助读者掌握变更数据捕获原理并落地MySQL到Doris的Streaming ETL链路。文档从CDC概念切入,对比基于查…

2026/10/13 13:01:37

腾讯开源 Octop:一条命令跑起来的多人 AI 助手

最近在 GitHub 趋势里反复刷到一个名字:Octop。 一开始我以为又是哪个个人开发者的玩具项目,点进去一看,仓库挂在 TencentCloud 组织下,是腾讯云开源的一个自托管 AI 助手。今天(10 月 9 日)晚上我看的时候…

2026/10/13 5:19:27

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/13 0:04:41

基于Triton部署YOLO目标检测:从训练脚本到线上服务

简介:这份资源面向希望将目标检测模型落地到生产环境的深度学习开发者与算法工程师,聚焦于用 Triton Inference Server 部署 YOLOv9 的完整实战方案,解决从训练权重到线上推理服务之间的工程化难题。压缩包共 16 个文件,约 886KB&…

2026/10/13 0:04:41

手把手教你云端部署Qwen-Image-2.1:从GPU选型到在线文生图服务

Qwen-Image-2.1 这个开源的图像生成模型,最近在内容创作和 AI 应用圈子里热度相当高。它属于通义 Qwen 系列里的视觉生成分支,让我眼前一亮的是它对中文长文本的理解能力——以前用那些老方案生成带中文文字的图,十个里九个是“乱码印刷体”&…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑