Bash Tab 补全:'-bash:寻找匹配的 `) 时出现意外的 EOF' -bash:语法错误:文件意外结束

Bash Tab 补全:'-bash:寻找匹配的 `) 时出现意外的 EOF' -bash:语法错误:文件意外结束

irb我正在尝试使用以下命令从文件中进入具有特定环境变量的会话:

$ env $(cat env.sh) irb

但是当我输入完成Tab后尝试按下时,出现以下错误:env.

$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file

另一件有趣的事情是,如果我以 root 身份登录,则不会发生此错误。

以下是 的输出find ~ -uid 0

$ find ~ -uid 0
/home/(redacted)/.rpmdb
/home/(redacted)/.rpmdb/Group
/home/(redacted)/.rpmdb/Conflictname
/home/(redacted)/.rpmdb/Installtid
/home/(redacted)/.rpmdb/Sha1header
/home/(redacted)/.rpmdb/Providename
/home/(redacted)/.rpmdb/__db.002
/home/(redacted)/.rpmdb/Requirename
/home/(redacted)/.rpmdb/Sigmd5
/home/(redacted)/.rpmdb/__db.001
/home/(redacted)/.rpmdb/Obsoletename
/home/(redacted)/.rpmdb/.dbenv.lock
/home/(redacted)/.rpmdb/Name
/home/(redacted)/.rpmdb/Basenames
/home/(redacted)/.rpmdb/Triggername
/home/(redacted)/.rpmdb/Packages
/home/(redacted)/.rpmdb/Dirnames
/home/(redacted)/.rpmdb/__db.003

有人能向我解释为什么会发生这种情况吗?如果是这样,当我不是 root 用户时,我该如何解决这个问题?

答案1

你发现了一个错误Bash 补全Ubuntu 使用的库。

这是什么意思?

Ubuntu 使用 bash 补全库来使 bash 补全变得智能。此库位于/usr/share/bash-completion/bash_completion

本质上,这个库声明了一些聪明的函数,它们知道典型的命令以及如何完成它们。每当您按下 时Tab,这个库中的函数就会被调用并尝试完成您当前的命令行。例如,如果您输入apt-get iTab它将完成apt-get install。如果您不 source 该库,您只能使用标准的、原始的 bash 完成 - 例如,如果您输入apt-get iTab而不 source 它,bash 将简单地在当前目录中查找以 开头的文件i并尝试根据这些文件名完成您的命令。

为什么它不能以 root 身份发生?

因为当你使用sudo sumake yourself时,bash 完成库不会被引用。如果你使用make yourself root,情况会有所不同。我敢打赌你会看到这个错误,不是吗?例如sudo -iroot'sudo su -' 与 'sudo -i' 与 'sudo /bin/bash' - 什么时候使用哪个重要,或者根本不重要吗?如果您不熟悉其中的区别。

就我而言,作为普通用户,当我启动 Bash shell 时,该库就会被获取,因为~/.bashrc来源/etc/bash_completion是哪些来源/usr/share/bash-completion/bash_completion

如果我使用sudo -i以 身份登录root,则库将获取来源,因为/etc/profile来源/etc/profile.d/bash_completion.sh是 哪些来源/usr/share/bash-completion/bash_completion

为什么会发生这个错误?

尝试执行这个命令:

$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file

看起来很熟悉?;-) 事实上,这正是您在描述的上下文中遇到时幕后发生的事情Tab。更准确地说,错误是在_quote_readline_by_ref声明的函数中/usr/share/bash-completion/bash_completion。如果您获取该文件,则应该可以使用该函数。接下来尝试以下操作:

$ _quote_readline_by_ref '$(cat env.' quoted
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file

给定这些参数,该函数_quote_readline_by_ref将执行上述操作eval。您可以查看一下。当您输入 时env $(cat env.Tab,该函数会在后台使用那些参数被调用。这就是发生的事情。

这次eval黑客攻击本来应该修复另一个问题,但我猜测它在过程中引入了另一个错误。

我如何解决它?

事实证明这个错误已经报告读完那个错误报告后,我发现了三种修复方法:

  1. 修补:在该错误报告的一条评论中,有人建议将以下行替换为

    [[ ${!2} == \$* ]] && eval $2=${!2}
    

    _quote_readline_by_ref在文件中的/usr/share/bash-completion/bash_completion函数内

    [[ ${!2} == \$\'* ]] && eval $2=${!2}
    

    我建议不要这样做。写这条评论的人并没有出现成为 bash-completion 的开发者。此修补程序将导致语句的左操作数计算结果为 false,从而防止这种情况eval发生。但是,如果不了解该函数应该做什么以及在什么上下文中调用它,就不清楚这是否可能破坏其他预期功能。

  2. 获取最新版本:正如该错误报告中所述,此错误在 git head 中不存在(除其他更改外,该功能_quote_readline_by_ref已简化)。您可以简单地从 Git 克隆当前修订版:

    git clone https://salsa.debian.org/debian/bash-completion.git
    

    ...然后将bash_completion脚本的最新版本复制到/usr/share/bash-completion(没有必要紧急备份旧版本,除非它让您感觉更安全 - 如果您遇到一些问题,sudo apt-get install --reinstall bash-completion应该恢复您所做的任何更改。)如果您急于解决这个问题,这是我推荐的方法。:-)

请注意,这些解决方案都无法使命令替换中的 bash 完成功能正常工作:正如同一个错误报告中所提到的,这在 Bash 4.3 中被破坏了。

  1. 坐下来等待:迟早会发布新版本(甚至可能修复命令替换中的 bash 补全),您将在未来的某个 Ubuntu 版本中获得它。这就是我想要的 ;-)

相关内容