Documentation
¶
Overview ¶
Package shellx 提供 POSIX shell 的参数转义与分词原语。
Quote 把任意字符串转义成**一个** shell word;QuoteArgv 把一组参数转义成 一条命令行;Split 是它们的逆运算——把一条命令行拆回 argv(未闭合引号、 尾随转义报错,不做尽力解析)。三者都是纯函数,不做策略判断——是否该拒绝 某个输入由调用方决定(换行、路径越界这类各有各的规则,见 pathx 与本包的文档)。
为什么需要它:把外部输入拼进 shell 命令时,不转义就等于把命令交给对方。 "a.txt; rm -rf /" 是**两条命令**而不是一个文件名;含空格的路径会被拆成 两个参数,于是文件被写到另一个地方——后者更隐蔽,因为命令看起来"成功"了。
转义方式用 POSIX 单引号:单引号内 shell 不做任何解释,所以唯一需要照顾的 是引号本身——关掉、转义、重新打开('\”)。这比反斜杠转义稳:反斜杠在 单引号内是字面量,双引号内又有一堆自己的规则,只有单引号是"里面什么都不 特殊"的。
空字符串是一个容易漏的边界:空参数仍然是一个参数,丢掉它会让 "cmd ” arg" 变成 "cmd arg",参数整体错位。所以 Quote("") 返回 "”"。
用法:
shellx.Quote("/tmp/a b.txt") // "'/tmp/a b.txt'"
shellx.Quote("it's") // "'it'\\''s'"
shellx.QuoteArgv("rm", "-f", p) // "rm '-f' '/tmp/x'" —— 逐个转义,程序名自己按需
与 pathx 的关系是两个不同的问题:pathx 问「这个路径合法吗」(越界即拒绝), shellx 问「这个字符串怎么写进命令行才不会被 shell 解释」。两者互补, 路径类输入通常两道都要过。
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrUnclosedQuote 表示命令行里有未闭合的引号('abc 或 "abc)。 // Split 不做尽力解析:尽力解析会把两段判成一段,前缀判据因此被绕过。 ErrUnclosedQuote = errors.New("shellx: unclosed quote in command line") // ErrTrailingEscape 表示命令行以悬挂反斜杠结尾(abc\)。 ErrTrailingEscape = errors.New("shellx: trailing escape in command line") )
Functions ¶
func Quote ¶
Quote quotes a string so that a POSIX shell passes it through as exactly one word, whatever it contains.
The result is always a single-quoted word. Nothing inside single quotes is special to the shell, so the only character that needs care is the quote itself: it is closed, escaped and reopened ("'\”"), which keeps the surrounding word intact.
An empty string becomes "”". An empty argument is still an argument, and dropping it would silently shift the whole command line: "cmd ” arg" must not become "cmd arg".
Quote does not decide what to do with a newline or a path that climbs out of its root -- it only escapes. Those are policy questions, and the caller is the one that knows them.
func QuoteArgv ¶
QuoteArgv renders a command line from a list of arguments: every argument is quoted, and the results are joined with a single space.
The empty argument list renders as the empty string.
func Split ¶ added in v0.37.4
Split 把一条命令行拆成 shell 词(argv),是 Quote/QuoteArgv 的逆运算:
Split(QuoteArgv(args...)) 必须逐项还原 args(含空参数、含引号/空格/ $ 等特殊字符——这条往返判据由用例钉住,Quote 的口径一改 Split 必须跟)。
口径(POSIX shell 词法,只拆词、不展开):
- 单引号内一切原样(含反斜杠)——与 Quote 的单引号转义互逆;
- 双引号内反斜杠仅在后跟 " \ $ ` 或换行时是转义(POSIX:\<char> 出该 char,\<newline> 是行拼接、整体消失),其余情况(\x 非 escape 时) 反斜杠与字符一并字面保留;
- 未加引号的 ; | & 作为**独立 token** 返回,相邻同类合并成 && / ||—— 分隔符不与词粘连、也不丢弃:是否按「多条子命令」处理是判据侧的 严格度,不由语法层决定(#243);
- 未闭合引号、尾随转义 → 返回 error,不做尽力解析;
- 空参数保留:” 还原为空参数——丢弃它会让后续参数整体错位 (Quote("") = "”" 的逆);
- 词内引号段与裸段粘连成一个词(a'b'c → abc,与 shell 一致);
- 不做变量展开、命令替换、glob——与 Quote 的「只转义、不判策略」同一 立场:展开会让判定看到与执行时点不同的文本。
空白分隔符为空格/制表/换行/回车(CR 按空白处理:从配置/工单粘贴的 CRLF 命令行,行尾 \r 不粘进最后一个 token)。空串与纯空白输入返回空切片。
Types ¶
This section is empty.