Bash选项卡完成:’-bash:寻找匹配时出现意外EOF’)’ – bash:语法错误:意外结束文件

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

 $ env $(cat env.sh) irb 

但是当我输入env.后尝试按Tabenv. 为了完成它,我得到以下错误:

 $ 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用户时,我该如何解决?

您在Ubuntu使用的Bash Completion库中发现了一个错误。

这是什么意思?

Ubuntu使用bash完成库来使bash完成智能化。 该库位于/usr/share/bash-completion/bash_completion

本质上,这个库声明了一些聪明的函数,这些函数了解典型命令以及如何完成它们。 无论何时按Tab键 ,都会调用此库中的函数并尝试完成当前的命令行。 因此,例如,如果您键入apt-get i Tab ,它将完成apt-get install 。 如果您没有获取该库,那么您只有标准的原始bash完成 – 例如,如果您键入apt-get i Tab而没有获取它,bash将只查找当前目录中以i开头并尝试的文件根据这些文件名完成命令。

为什么不以root身份发生?

因为当你使用sudo su来使自己成为root ,不会获取bash完成库。 如果你使用sudo -i来使自己成为root这将会有所不同。 我打赌你看到了那个虫子,不是吗? 例如,参见’sudo su – ‘vs’sudo -i’vs’sudo / bin / bash’ – 什么时候使用它,或者它是否重要? 如果你不熟悉这些差异。

在我的例子中,作为普通用户,当我启动Bash shell时,库会被获取,因为~/.bashrc/etc/bash_completion来源/usr/share/bash-completion/bash_completion

如果我使用sudo -iroot身份登录,那么该库将被获取,因为/etc/profile sources /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后幕后发生的事情。 更确切地说,该错误位于/usr/share/bash-completion/bash_completion声明的函数/usr/share/bash-completion/bash_completion 。 如果您获取该文件,则应该具有该function。 接下来试试这个:

 $ _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除其他外_quote_readline_by_ref执行上面提到的eval 。 如果你愿意,你可以看看。 当你输入env $(cat env. ,幕后的函数被完全用那些参数调用时。那就是发生了什么。

这个eval hack 应该修复另一个问题 ,但我想它在这个过程中引入了另一个bug。

我如何解决它?

事实certificate,这个bug 已经被报道过了 。 在阅读该错误报告后,我看到了三种解决方法:

  1. 补丁:在该错误报告中的一条评论中,有人建议更换该行

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

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

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

    我建议不要这样做。 撰写该评论的人似乎并不是bash-completion的开发者 。 此修补程序将简单地导致语句的左操作数计算为false,从而防止eval发生。 然而,如果不了解该函数应该做什么以及在什么情况下调用它,则不清楚这是否会潜在地破坏其他一些预期的function。

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

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

    …然后将最新版本的bash_completion脚本复制到/usr/share/bash-completion (不需要备份旧版本,除非它让你觉得更安全 – 如果你遇到一些问题, sudo apt-get install --reinstall bash-completion应该还原你所做的任何修改。)如果你急于解决这个问题,这就是我推荐的方式。 🙂

请注意,这些解决方案都不会在命令替换中完成bash完成工作:如同一个错误报告中所述,这在Bash 4.3中已经破解。

  1. 坐下来等待:迟早会发布一个新版本(甚至可能会修复命令替换中的bash完成),你会得到一些未来的Ubuntu版本。 这就是我想要的;-)