eld*_*soa 21 command-line bash auto-completion
我正在尝试irb
使用以下命令从文件中进入具有特定环境变量的会话:
$ env $(cat env.sh) irb
Run Code Online (Sandbox Code Playgroud)
但是当我Tab
在输入env.
完成后尝试按下时,出现以下错误:
$ env $(cat env.-bash: unexpected EOF while looking for matching `)'
-bash: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
另一个有趣的事情是,如果我以 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
Run Code Online (Sandbox Code Playgroud)
任何人都可以向我解释为什么会发生这种情况,如果是这样,当我不是 root 用户时如何修复它?
Mal*_*ppa 36
您在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
make own 时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
which sources /usr/share/bash-completion/bash_completion
.
为什么会发生这个错误?
尝试执行此命令:
$ eval 'quoted=$(cat' env.
bash: unexpected EOF while looking for matching `)'
bash: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
看起来很熟悉?;-) 事实上,当你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
Run Code Online (Sandbox Code Playgroud)
给定这些参数,该函数_quote_readline_by_ref
执行eval
上面提到的其他事情。喜欢的可以去看看。当你输入时env $(cat env.
Tab,函数在幕后被调用的正是这些参数。所以这就是发生的事情。
这个eval
hack应该解决另一个问题,但我猜它在这个过程中引入了另一个错误。
我如何解决它?
事实证明,这个错误已经被报告了。阅读该错误报告后,我看到了三种修复方法:
修补它:在该错误报告中的一条评论中,有人建议替换该行
[[ ${!2} == \$* ]] && eval $2=${!2}
Run Code Online (Sandbox Code Playgroud)
按行在_quote_readline_by_ref
文件中/usr/share/bash-completion/bash_completion
的函数内
[[ ${!2} == \$\'* ]] && eval $2=${!2}
Run Code Online (Sandbox Code Playgroud)
我建议不要这样做。撰写该评论的人似乎不是bash-completion 的开发人员。此修补程序只会导致语句的左操作数计算为 false,从而防止这种eval
情况发生。但是,如果不了解该函数应该做什么以及在什么上下文中调用它,则不清楚这是否会破坏其他一些预期功能。
获取最新版本:正如该错误报告中所述,git head 中不存在此错误(其中该功能_quote_readline_by_ref
已被简化)。您可以简单地从 Git 克隆当前版本:
git clone https://salsa.debian.org/debian/bash-completion.git
Run Code Online (Sandbox Code Playgroud)
...然后将最新版本的bash_completion
脚本复制到/usr/share/bash-completion
(无需紧急备份旧版本,除非它让您感觉更安全 - 如果您遇到一些问题,sudo apt-get install --reinstall bash-completion
应该恢复您所做的任何更改。)这就是我的方式如果您急于解决此问题,建议您这样做。:-)
请注意,这些解决方案都不会在命令替换中完成 bash 完成:正如在同一个错误报告中提到的,这在 Bash 4.3 中被破坏了。