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


18

我正在尝试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用户时如何解决?


您如何以root用户身份登录?
muru

@muru我使用登录到root sudo su
eldosoa 2015年

请编辑您的问题以添加的输出find ~ -uid 0
muru 2015年

@muru完成。在我的问题中添加了输出。
eldosoa 2015年

抱歉,但不是root!我的意思是作为您的普通用户,所以~/home/something
muru 2015年

Answers:


33

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

这是什么意思?

Ubuntu使用bash完成库使bash完成变得智能。这个图书馆住在/usr/share/bash-completion/bash_completion

本质上,此库声明了一些巧妙的函数,这些函数了解典型命令以及如何完成这些命令。每当您Tab按时,都会调用该库中的函数并尝试完成当前的命令行。因此,例如,如果您键入内容apt-get iTab,它将完成该操作apt-get install。如果您不提供该库,则仅具有标准的原始bash补全-例如,如果您键入时apt-get iTab未提供该补全,bash只会在当前目录中查找以开头的文件,i并尝试根据以下命令完成命令这些文件名。

为什么它不是作为根发生的?

因为当您习惯于sudo su制作自己时root,bash完成库不是源代码。如果你曾经sudo -i做过自己,这会有所不同root。我敢打赌,然后您会看到错误,不是吗?例如,参见'sudo su-'vs'sudo -i'vs'sudo / bin / bash'-什么时候使用哪个重要,或者根本不重要?如果您不熟悉这些差异。

在我的情况下,作为普通用户,启动Bash shell时会获取该库的资源,因为~/.bashrcsource的/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。

我如何解决它?

事实证明,此错误已被报告。阅读该错误报告后,我看到了三种修复方法:

  1. 修补问题:在该错误报告的其中一项评论中,有人建议替换该行

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

    _quote_readline_by_ref文件中/usr/share/bash-completion/bash_completion的功能内按行

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

    我建议不要这样做。发表该评论的人似乎不是bash-completion的开发者。此修复程序将仅使语句的左操作数求值为假,从而防止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版本中获得它。那就是我要的;-)

1
@ con-f-use是的,就是这样!Git repo也与bash-completion 的主要站点相关联,这就是为什么我在答案中未与之链接的原因。
Malte Skoruppa 2015年

2
@ con-f-use您的评论使我对该错误进行了更多研究。事实证明,它不是过去的错误,而且过去从未如此。相反,它实际上是由针对上游版本的Ubuntu补丁引入的错误。到目前为止,似乎没有人将这个错误缩小到特定补丁范围。因此,我已在相应的Ubuntu错误报告中报告了我的发现:bugs.launchpad.net/ubuntu/+source/bash-completion/+bug/1312243
Malte Skoruppa 2015年

2
做得好Malte。
巴里·凯利

1
感谢您的解释。在撰写本文时,git head版本已删除了该错误根据需要自动完成。编辑:实际上,没关系,事实并非如此。
user3391564 '16

1
@MaxvonHippel我说,当你使用sudo su成为root,它没有源库,但它在使用Get来源sudo -i,而不是,这是预期的方式来获得一个交互式会话根。关于您的问题:由于任何bash shell都会读取~/.bashrc并最终获得该库的资源,并且没有“取消源”文件的方法,因此我看不到完全简单的方法。这可能是一个hack:使库的获取取决于某些环境变量的条件,例如NOCOMPL在您的环境变量中定义~/.bashrc...
Malte Skoruppa
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.