我曾经complete -W 'firstdatabase databasetwo etc' mysql
保存数据库列表,以便我可以使用命令自动完成它们mysql
。
然而,在很多情况下我会输入mysql db < /tmp/script.sql
.在看到第一个>
或后,如何让 bash 恢复到传统的自动完成(文件名)<
?
更新:我下载了一个 Ubuntu 安装程序,它附带了bash 自动完成预安装包。虽然简单地在我们的服务器上安装相同的包对我来说不是一个选择,但我仍然可以通过检查complete -p
和的输出来了解其实现declare
。 (alias -p
也有一些很酷的东西)
在我们的服务器上,我使用了complete -d cd
.我发现它遇到了同样的问题,在<
或之后>
,complete -d
功能仍然存在。然而,bash 自动完成有一个更复杂的方法可以解决这个问题。了解他们如何解决它cd
(以及许多其他命令)可能会展示如何解决我遇到的相同问题mysql
。
因此,这是他们的实现cd
:他们使用complete -o nospace -F _cd cd
,它基本上调用_cd
自动完成查询的函数。这是他们使用的函数:
_cd ()
{
local cur prev words cword;
_init_completion || return;
local IFS='
' i j k;
compopt -o filenames;
if [[ -z "${CDPATH:-}" || "$cur" == ?(.)?(.)/* ]]; then
_filedir -d;
return 0;
fi;
local -r mark_dirs=$(_rl_enabled mark-directories && echo y);
local -r mark_symdirs=$(_rl_enabled mark-symlinked-directories && echo y);
for i in ${CDPATH//:/'
'};
do
k="${#COMPREPLY[@]}";
for j in $( compgen -d $i/$cur );
do
if [[ ( -n $mark_symdirs && -h $j || -n $mark_dirs && ! -h $j ) && ! -d ${j#$i/} ]]; then
j+="/";
fi;
COMPREPLY[k++]=${j#$i/};
done;
done;
_filedir -d;
if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
i=${COMPREPLY[0]};
if [[ "$i" == "$cur" && $i != "*/" ]]; then
COMPREPLY[0]="${i}/";
fi;
fi;
return 0
}
complete -o nospace -F _cd cd
在最新版本的 上运行上述代码可以bash
得到所需的结果cd
。现在如何将其转换为mysql
? (或者我通常用的东西complete -W
?)
答案1
神奇之处在于_init_completion
定义在bash_completion
bash-completion 包的文件。
没有简单的出路。如果您想在 bash 中实现合理的奇特补全,请安装 bash-completion 包。然后定义一个函数:
. /etc/bash_completion
_my_mysql () {
local cur prev words cword
_init_completion || return
COMPREPLY=($(compgen -W 'firstdatabase databasetwo etc' "$cur"))
}
complete -F _my_mysql mysql