Bash:允许在命令参数中使用括号(即防止“意外标记 '('”)

Ban*_*ach 2 bash quoting

我经常使用一个命令行程序,我提供的参数包含括号。为简单起见,假设我正在写

echo 'bar(1,3)'

我想省略引号。但是,如果我这样做,我会得到syntax errror near unexpected token '('. 我想这与子外壳有关。如果这是唯一的方法,我愿意禁用它们。(尽管如果它不在命令的开头,则无法启动子shell,因此据我所知,它们没有理由禁止参数中的括号)

Sté*_*las 5

()是语法中的特殊标记字符,bash用于许多运算符,包括:

  • (...) 子壳结构
  • func() compound-command 功能定义
  • $(...) 命令替换
  • <(...),>(...)进程替换
  • ((...)) 算术评估结构
  • $((...)) 算术展开
  • a=(...),a+=(...)数组赋值运算符
  • @(...), +(...), *(...), ?(...)glob 运算符(使用 extglob)
  • [[ (a && b) || (c && d) ]] 分组条件表达式运算符
  • [[ ... =~ ...(...)... ]] 正则表达式运算符。

echo a=(b)是语法错误,但不是export a=(b).

echo a)是一个语法错误,除非(在上述结构之一的前几行部分中有一个开头。

虽然可以编写一个 readline 钩子,在需要的地方添加引号()以避免语法错误,但这将是相当大的努力,因为这意味着要对 shell 语法进行完整的解析。

更好的方法可能是使用引用当前单词的快捷方式,当您意识到它包含 shell 特有的字符时为时已晚。

zsh(假设emacs模式):

bindkey -s '\e#' '\C@\eb\Cx\Cx\e"'
Run Code Online (Sandbox Code Playgroud)

若要Alt+#引用当前的

或近似bash(也假设emacs模式):

bind "\"\e#\": \"'\e \eb'\C-X\C-X\""
Run Code Online (Sandbox Code Playgroud)

  • 我同意你更好的方法。感谢您的 bash 更新。如果其他人需要这个但像我一样启用了 vi 模式,我将其修改为`bind "\"\e#\": \"'\eF a'"`。这会在当前参数周围加上引号,如定义的光标直到它前面最近的空格字符。 (2认同)