您在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
并尝试根据以下命令完成命令这些文件名。
为什么它不是作为根发生的?
因为当您习惯于sudo su
制作自己时root
,bash完成库不是源代码。如果你曾经sudo -i
做过自己,这会有所不同root
。我敢打赌,然后您会看到错误,不是吗?例如,参见'sudo su-'vs'sudo -i'vs'sudo / bin / bash'-什么时候使用哪个重要,或者根本不重要?如果您不熟悉这些差异。
在我的情况下,作为普通用户,启动Bash shell时会获取该库的资源,因为~/.bashrc
source的/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
hack 应该可以解决另一个问题,但是我猜它在此过程中引入了另一个bug。
我如何解决它?
事实证明,此错误已被报告。阅读该错误报告后,我看到了三种修复方法:
修补问题:在该错误报告的其中一项评论中,有人建议替换该行
[[ ${!2} == \$* ]] && eval $2=${!2}
在_quote_readline_by_ref
文件中/usr/share/bash-completion/bash_completion
的功能内按行
[[ ${!2} == \$\'* ]] && eval $2=${!2}
我建议不要这样做。发表该评论的人似乎不是bash-completion的开发者。此修复程序将仅使语句的左操作数求值为假,从而防止eval
情况发生。但是,如果不了解该功能应该做什么以及在什么上下文中被调用,则尚不清楚这是否不会破坏其他预期功能。
获取最新版本:正如该错误报告中所提到的,此错误不在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中已被打破。
- 坐下来等一下:迟早会有一个新版本发布(它甚至可以在命令替换中修复bash完成),并且您将在将来的某些Ubuntu版本中获得它。那就是我要的;-)