展开后的 X 加一个追加的 LF,作为十六进制字节 580a 交给标准输入。

Here-string 提供文本并追加换行

Bash 的 here-string 会把一个词展开后的值送给命令的标准输入,并在末尾追加一个换行符。当变量里已经有少量文本,而目标程序从标准输入读取时,这种写法很方便。它省掉了额外的打印命令,但并不保证输入与变量逐字节相同,也不承诺内部一定使用内存、管道或文件。判断是否适用,应看接收方需要什么输入,而不是只比较命令行长度。 Bash 先构造展开后的字符串并无条件追加换行,然后接收方按自己的规则解析。重定向本身不创建子 shell,也不承诺内部存储方式。 接收命令读取之前先完成展开 三个小于号之后的词可以包含变量展开、算术展开和命令替换,因此不一定是字面常量。单引号保留源码中的字面文本,双引号则允许通常的变量和命令展开。通过变量展开得到的字符串,即使包含美元符号和括号,也不会仅因出现在 here-string 中就被再次作为 shell 命令执行。源码中明确写出的替换语法与变量保存的数据必须区分。 当前 Bash 不会对 here-string 的词执行分词或文件名展开,而是把结果作为一个字符串交付。这里引用变量仍能清楚表达意图,但不能把这种重定向上下文和普通命令参数位置混为一谈。后者使用未引用变量时仍可能按空白拆分,或把星号变成文件名。因此,某个值通过 here-string 正常到达,并不能证明在别处省略引号也安全。 ...

二月 15, 2027 · 1 分钟 · XB Field Notes
输入 --status 先命中精确的 case 分支,并在 ;; 结束,不再进入宽泛的 --* 分支。

case 只执行与模式匹配的那一支

Case 语句把一个值依次与一组 shell 模式比较,适合命令分发、有限答案选择或文件名后缀分类。每个分支明确自己处理哪些输入,多个模式也可以共享同一个动作。分支顺序和默认行为都是接口的一部分:输入同时属于多个类别时谁先处理,完全不属于已知类别时是否报错,都需要明确规定。不能只看到成功输入能跑通,就认为整个分发器已经可靠。 使用普通 ;; 时,case 运行首个匹配分支。匹配成功不代表动作成功;模式只分类字符串,不查询文件。 模式匹配整个值 Case 使用的是 shell 模式,不是正则表达式。星号匹配任意长度字符串,问号匹配一个字符,方括号描述字符集合或范围。因此,[0-9]* 表示一个数字后面可以跟任意内容,并不表示整串都是数字。若要验证非空十进制文本,可以先拒绝空字符串,以及包含任意非数字字符的字符串,而不必把输入放进算术求值环境。 start|up|run) 这样的多个模式可以共用动作。*.log) 等后缀规则则只是在分类字符串,并不会打开文件或搜索目录。因此,匹配成功不能证明对应文件存在。与普通文件名展开不同,字符串匹配中的斜杠和开头的点也没有相同的特殊排除作用。分类、文件存在性和文件类型是不同判断,真正操作文件前仍应根据需求单独验证。 Bash 会对被测试的词执行文档规定的展开,但不会像普通命令参数那样对它分词或执行文件名展开。因此,这个位置的未引用空变量不会删掉语法上的词,进而把 case 变成语法错误。引用被测试值仍然是清楚的书写习惯。若开启 nounset,则要另外处理未提供的位置参数,或先验证参数数量;引号本身不能让未设置参数变得可用。 实际执行某个分支后,case 返回该分支最后执行命令的状态。因此,匹配成功与动作成功是两件事。下面的实验也让一个已经选中的分支返回六,并检查失败继续向外传播,避免把“找到了正确分支”误报成“分支里的操作已经成功”。 坏掉的样子 使用通常的双分号结束符时,首个匹配分支执行后,case 就结束。精确值应放在宽泛类别前,兜底星号通常放在最后,否则通用选项分支会吞掉后面的精确状态命令。语法检查只能证明结构可解析,不能证明顺序符合业务优先级。应该构造同时匹配两个规则的输入,并断言实际执行哪个动作,才能发现被遮蔽的分支。 如果没有任何模式匹配,case 不执行动作,却仍然返回零。因此,没有默认分支不等于会自动报错。命令分发器若要求拒绝未知命令,就必须在默认分支明确报告并返回失败;可选分类逻辑则可能有意允许不匹配。这个策略来自调用契约,不能假设 case 自带完整输入校验,更不能依赖自动退出选项补足业务含义。 ...

一月 30, 2027 · 2 分钟 · XB Field Notes
正常显式退出,以及主动退出的 INT 或 TERM 处理器,汇入统一的 EXIT 清理步骤。红色 KILL 路径在清理之前被终止横杠截断。

Shell 的 trap 把信号转成一次清理动作

trap 让 Shell 为某个信号或自身事件安排动作,适合删除临时文件、协调退出,但不会让中断变成原子操作,也无法保证任何终止方式都能完成清理。在 Bash 中,trap 是内建命令,EXIT 是 Shell 事件,而不是操作系统信号。可靠的设计需要明确处理哪些出口,并保留执行为什么结束的证据,不能仅凭注册了一次处理器就断言资源一定会被回收。 这是明确的退出清理策略,不能保证删除成功或立即关停。先保存最初的状态,并单独诊断清理结果。等待同步前台命令与通过 wait 等待异步命令的陷阱时机不同。本轮没有重新运行原文示例。 信号处理与退出清理分开 trap 'cleanup' INT TERM 会替换这些信号的默认动作。如果处理器只是返回,Shell 可能继续执行;安装处理器并不天然等于启动关停。一种明确的 Bash 写法是在信号处理器中主动退出,再让统一的退出处理器负责清理。正常执行到末尾、显式调用退出命令,也会经过这个出口,从而减少各业务分支之间重复的资源回收逻辑。 ...

一月 12, 2027 · 2 分钟 · XB Field Notes