Bash选项卡完成:’-bash:寻找匹配时出现意外EOF’)’ – bash:语法错误:意外结束文件
我正在尝试使用此命令从文件中使用特定环境变量进入irb
会话:
$ env $(cat env.sh) irb
但是当我输入env.
后尝试按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用户时,我该如何解决?
您在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 -i
以root
身份登录,那么该库将被获取,因为/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 已经被报道过了 。 在阅读该错误报告后,我看到了三种解决方法:
-
补丁:在该错误报告中的一条评论中,有人建议更换该行
[[ ${!2} == \$* ]] && eval $2=${!2}
在函数
_quote_readline_by_ref
中的文件/usr/share/bash-completion/bash_completion
的行[[ ${!2} == \$\'* ]] && eval $2=${!2}
我建议不要这样做。 撰写该评论的人似乎并不是bash-completion的开发者 。 此修补程序将简单地导致语句的左操作数计算为false,从而防止
eval
发生。 然而,如果不了解该函数应该做什么以及在什么情况下调用它,则不清楚这是否会潜在地破坏其他一些预期的function。 -
获取最新版本:正如该错误报告中所述,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中已经破解。
- 坐下来等待:迟早会发布一个新版本(甚至可能会修复命令替换中的bash完成),你会得到一些未来的Ubuntu版本。 这就是我想要的;-)