当我启动 bash 子 shell(通过bash
从命令提示符调用)时,所有 tab 补全都停止工作。complete
新 shell 中的命令变为空:
$ complete
[...]
complete -F _apport-collect apport-collect
complete -F _filedir_xspec vim
complete -o dirnames -o filenames -F _apport-bug ubuntu-bug
complete -F _known_hosts ftp
complete -F _longopt units
complete -F _longopt uname
complete -F _service /etc/init.d/network-manager
complete -F _longopt touch
complete -F _longopt ldd
complete -F _command then
complete -F _known_hosts rlogin
complete -F _service /etc/init.d/sddm
complete -F _service /etc/init.d/lvm2-lvmpolld
complete -F _command command
complete -F _longopt sha384sum
complete -F _known_hosts fping6
complete -F _longopt rm
complete -F _service /etc/init.d/cryptdisks
complete -F _service /etc/init.d/binfmt-support
$ bash
$ complete
$
我如何才能让 tab 自动补全功能在子 shell 中也能正常工作?我的配置文件或 bashrc 中是否缺少某些内容?
编辑:在 ubuntu 中,补全是默认存在的(不是我添加的)。/etc/bash.bashrc
提到了补全,但是该部分默认被注释掉了(不是我做的):
# enable bash completion in interactive shells
#if ! shopt -oq posix; then
# if [ -f /usr/share/bash-completion/bash_completion ]; then
# . /usr/share/bash-completion/bash_completion
# elif [ -f /etc/bash_completion ]; then
# . /etc/bash_completion
# fi
#fi
/etc/profile
执行中的所有脚本/etc/profile.d
,其中包含加载完成的脚本:
# shellcheck shell=sh disable=SC1091,SC2039,SC2166
# Check for interactive bash and that we haven't already been sourced.
if [ "x${BASH_VERSION-}" != x -a "x${PS1-}" != x -a "x${BASH_COMPLETION_VERSINFO-}" = x ]; then
# Check for recent enough version of bash.
if [ "${BASH_VERSINFO[0]}" -gt 4 ] || \
[ "${BASH_VERSINFO[0]}" -eq 4 -a "${BASH_VERSINFO[1]}" -ge 1 ]; then
[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion" ] && \
. "${XDG_CONFIG_HOME:-$HOME/.config}/bash_completion"
if shopt -q progcomp && [ -r /usr/share/bash-completion/bash_completion ]; then
# Source completion code.
. /usr/share/bash-completion/bash_completion
fi
fi
fi
两个 bash 会话似乎都是用相同的参数开始的:
$ complete
...
complete -F _service /etc/init.d/cryptdisks
complete -F _service /etc/init.d/binfmt-support
$ echo $-
himBHs
$ bash
$ complete
$ echo $-
himBHs
我的bash
命令没有任何别名:
$ type bash
bash is /usr/bin/bash
答案1
看起来默认补全是由/etc/profile
(进而执行/etc/profile.d/bash_completion.sh
)加载的。然而,在非登录 shell 中,/etc/profile
不会执行,因此不会加载补全。
如果我启动登录 bash 子shell,则会加载补全内容:
$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Login shell
$ complete | wc -l
214
$ bash
$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Not login shell
$ complete | wc -l
0
$ exit
exit
$ bash --login
$ shopt -q login_shell && echo 'Login shell' || echo 'Not login shell'
Login shell
$ complete | wc -l
214
所以基本上,我必须明确地在非登录 shell 中加载补全,因为它们默认不会加载(至少在我的设置上不会)。