<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Escaping on CAO ZUOHUA</title><link>https://caozuohua.github.io/tags/escaping/</link><description>Recent content in Escaping on CAO ZUOHUA</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://caozuohua.github.io/tags/escaping/index.xml" rel="self" type="application/rss+xml"/><item><title>Shell 转义歧义解析：当 LLM 遇上双重解析地狱</title><link>https://caozuohua.github.io/posts/2026-07-06-shell-escaping-ambiguity/</link><pubDate>Mon, 06 Jul 2026 00:00:00 +0000</pubDate><guid>https://caozuohua.github.io/posts/2026-07-06-shell-escaping-ambiguity/</guid><description>&lt;p&gt;你有没有过这种经历：让 Agent 帮你写一段小脚本，生成的内容看起来语法完美，一跑就炸？报错信息通常是一串让你怀疑人生的 &lt;code&gt;&amp;amp;&lt;/code&gt;、&lt;code&gt;$&lt;/code&gt;、反引号乱码，然后你盯着那几行代码看了十分钟——最后发现，模型把 bash 的反斜杠转义 &lt;code&gt;\&amp;quot;&lt;/code&gt; 写在了 PowerShell 命令里。&lt;/p&gt;
&lt;p&gt;这个问题我称之为 &lt;strong&gt;Shell 转义歧义&lt;/strong&gt;，在 LLM + 终端自动化这个交叉点上表现得尤其明显。本质是：LLM 生成的是一个扁平字符串，而 shell 执行的是多层嵌套的语义解析，任何一层出了偏差，最终执行的命令就和你预期完全不一样。&lt;/p&gt;
&lt;h2 id="一双重解析模型以为的-vs-shell-实际执行的"&gt;一、双重解析：模型以为的 vs shell 实际执行的&lt;/h2&gt;
&lt;p&gt;LLM 采用自回归方式逐 token 生成，它&amp;quot;以为&amp;quot;自己写的是结构化的命令。但实际上，如果这个字符串被 &lt;code&gt;shell=True&lt;/code&gt;（Python subprocess）或者 &lt;code&gt;Invoke-Expression&lt;/code&gt;（PowerShell）执行，就等于经历了 &lt;strong&gt;两次独立的解析&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;第一层&lt;/strong&gt;：LLM 生成字符串时的&amp;quot;心智解析&amp;quot;——它以为引号配对是对的&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;第二层&lt;/strong&gt;：shell 自己再做一次 tokenize / word-splitting&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两层之间没有任何契约式的保证。模型输出一个字符串，shell 拿过去按自己的规则重新分词，然后交给操作系统执行。任何一层的歧义，都会导致最终行为和预期背离。&lt;/p&gt;
&lt;p&gt;而且这种错误往往是 &lt;strong&gt;延迟发现的&lt;/strong&gt;：代码写入时没报错，运行时才炸。模型只能&amp;quot;事后诸葛亮&amp;quot;式地不断打补丁修改脚本，一个命令可能要循环三四次才终于跑通。&lt;/p&gt;
&lt;h2 id="二为什么-powershell-比-bash-更容易踩坑"&gt;二、为什么 PowerShell 比 bash 更容易踩坑&lt;/h2&gt;
&lt;p&gt;Shell 本来就不简单，但 PowerShell 在这个问题上尤其难搞。有几层原因：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. 转义符混淆&lt;/strong&gt;
PowerShell 的转义符是反引号 &lt;code&gt;`&lt;/code&gt;，不是 &lt;code&gt;\&lt;/code&gt;。但模型的训练数据里 bash 语法占绝对多数，它经常无意识地混用 bash 习惯——比如用 &lt;code&gt;\&amp;quot;&lt;/code&gt; 来表示引号转义，这在 PowerShell 里会被原样当作普通反斜杠处理，导致完全不同的解析结果。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. 语义差异大&lt;/strong&gt;
PowerShell 对 &lt;code&gt;$&lt;/code&gt;、&lt;code&gt;@()&lt;/code&gt;、&lt;code&gt;&amp;amp;&lt;/code&gt;、&lt;code&gt;|&lt;/code&gt; 有一套完全不同于 bash 的语义：变量插值、数组字面量、调用操作符、管道。模型很容易犯&amp;quot;语法迁移错误&amp;quot;，把 bash 的逻辑套用到 PowerShell 上。&lt;/p&gt;</description></item></channel></rss>