编写 bash 函数时出现意外标记“(”附近的语法错误

编写 bash 函数时出现意外标记“(”附近的语法错误

我有

testapi() { docker-compose -f /home/me/projects/api/docker-compose.yml run -e "API_BRANCH=${1-master}" --rm api_test ;}

它会导致错误:

$ src
bash: /home/me/.bash_profile: line 56: syntax error near unexpected token `('
bash: /home/me/.bash_profile: line 56: `testapi() { docker-compose -f /home/me/projects/api/docker-compose.yml run -e "API_BRANCH=${1-master}" --rm api_test ;}'

运行产生帮助信息:

$ testapi
Run a one-off command on a service.

For example:

    $ docker-compose run web python manage.py shell

任何帮助表示感谢,谢谢

答案1

您已定义与函数同名的别名。别名被扩展(因为配置文件源自别名起作用的交互式 shell),这导致函数定义无效。

答案2

我有点不好意思地承认,我曾多次担心必须修改多年来的 Bash 脚本,因为functionBash 5.x.something 中的语法发生了变化。不是这里的情况。

接受的答案解释得很准确,但我必须亲眼看到才能相信。这是一个人为的(无操作)示例:

alias ls='ls -F'

ls() { command ls "$@"; }
# result: bash: syntax error near unexpected token `('

ls () command ls "$@"; }
# same: bash: syntax error near unexpected token `('

shell 将其视为:

ls -F() command ls "$@"; }
# result: bash: syntax error near unexpected token `('

任何这些不会出错,因为别名只有在第一的在命令行上:

function ls { command ls "$@"; }
function ls() { command ls "$@"; }
function ls () { command ls "$@"; }

根据一些简单的测试,似乎这种行为是仅有的当使用第一种形式(无function关键字)并且函数名称已作为 shell 别名存在时触发。如果它是现有功能,没问题,只需重新定义该函数。如果它是现有可执行文件的名称磁盘文件在搜索路径中,这也是允许的,但需要注意的是,您需要使用command如上所述的方法以防止无限递归。

奇怪的是,我以前从未注意到这种行为,因为看起来如果解析器看到 ,它应该继续运行<alias><optional whitespace><open paren>,而不扩展<alias>。也许它会在 Bash 6.0 中修复,谁知道呢!

相关内容