别名导致错误:意外标记附近的语法错误`('

WM *_* MW 4 bash alias

我正在尝试运行以下 bash 并收到错误:bash: syntax error near unexpected token `('.

.bashrc:

alias "ota"='/cygdrive/d/Program Files (x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py' 
Run Code Online (Sandbox Code Playgroud)

我试图运行以下命令:

ota --help
Run Code Online (Sandbox Code Playgroud)

mkl*_*nt0 5

tl;博士

  • 您不仅需要引用别名命令的定义需要引用它在生成的命令行中的原样使用

  • 你的情况,最简单的解决方法是使用一个外部的组合'...'使用引号 "..."引用(存在其他的解决方案;请注意,使用"..."的内引用这意味着,如果你的定义包含变量引用,他们会被别名扩大时使用):

alias ota='"/cygdrive/d/Program Files (x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py"'
Run Code Online (Sandbox Code Playgroud)

定义别名时两个引用(转义)上下文会起作用

  • 定义别名时引用。

  • 引用在一个别名的命令的上下文中所用英寸


别名定义中的引用允许您定义别名ota而不会出现语法错误:

您将别名定义ota为以下文字
/cygdrive/d/Program Files (x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py
即RHS 上字符串的文字内容,由于使用了'...'(single-quoting)。


然而,当你在 command 中使用这个别名时ota --help,它的定义变成了命令行的一个文字的、不加引号的部分,并且 Bash 尝试执行以下损坏的命令:

/cygdrive/d/Program Files (x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py --help
Run Code Online (Sandbox Code Playgroud)

基于通常的shell 扩展,这个命令的处理如下:

  • /cygdrive/d/Program被解释为要执行的命令(第一个空格之前的所有内容),因为单词拆分将命令行上未加引号的标记按空格拆分为单词。

  • 因此,Files,(x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py--help成为该命令的参数, BUT: (and ),当使用不加引号时,就像它们在这里一样,是外壳的控制运算符:它们用于创建外壳,但作为参数的一部分这样做在语法上是无效的,这就是您看到的原因syntax error near unexpected token `('
    (在未找到命令的运行时错误/cygdrive/d/Program有机会出现之前)。

上面说明了正确引用别名定义的嵌入部分的必要性,如顶部所示。
可以在下面找到替代解决方案。


引用替代方案:

# Using *outer double quotes with inner double quotes* would work here too,
# although if the definition contained variable references / command or 
# arithmetic substitutions, they'd be expanded at *definition* time.
alias ota="'...'"

# Using an *ANSI C-quoted string ($'...')* inside of which you can use
# \' to escape embedded single quotes (but you need to be aware of
# the meaning of other \-based escape sequences).
alias ota=$'\'...\''

# Using *character-individual quoting*, with \ preceding each shell 
# metacharacter (as in @sorontar's answer).
alias ota='/cygdrive/d/Program Files\ \(x86\)...'
Run Code Online (Sandbox Code Playgroud)

使用功能来代替:

@ ruakh指出,使用 函数而不是别名可以完全绕过两层引用问题:

function ota() { 
 '/cygdrive/d/Program Files (x86)/Arduino/hardware/esp8266com/esp8266/tools/espota.py' "$@"
}
Run Code Online (Sandbox Code Playgroud)


小智 0

您需要对命令中的某些字符进行反斜杠转义。特别是,您需要转义文件名中的空格,以防止 shell 将文件名拆分为多个部分。您还需要转义(),它们是 shell 的元字符:

alias "nano"='/cygdrive/c/Program\ Files\ \(x86\)/Notepad++/notepad++.exe' 
alias "ota"='/cygdrive/d/Program\ Files\ \(x86\)/Arduino/hardware/esp8266com/esp8266/tools/espota.py' 
Run Code Online (Sandbox Code Playgroud)