假设我有两个bash函数:
dock() { sudo docker $@ ;}
和
dock-ip() { sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
如何使用第二个功能进行bash自动完成?
使用第一个,就像添加:
一样简单_completion_loader docker; complete -F _docker dock
这不适用于第二个。 Docker的自动完成源位于Debian Stretch上的/usr/share/bash-completion/completions/docker
。我有更多功能,例如dock-run
,dock-exec
等,因此我不想为每个功能编写自定义完成功能。
此外,complete -F _docker_container_inspect dock-ip
仅部分有效; tab 仅列出容器,而不是完成部分字符串。
研究:
How do I autocomplete nested, multi-level subcommands?< - 需要自定义功能
https://superuser.com/questions/436314/how-can-i-get-bash-to-perform-tab-completion-for-my-aliases< - 仅限顶级命令自动
答案 0 :(得分:3)
结合一小时的bash完成经验,我拆开了docker完成脚本(/usr/share/bash-completion/completions/docker
)和bash_completion.sh
脚本来提供一个包装函数:
# Usage:
# docker_alias_completion_wrapper <completion function> <alias/function name>
#
# Example:
# dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
# docker_alias_completion_wrapper __docker_complete_containers_running dock-ip
function docker_alias_completion_wrapper {
local completion_function="$1";
local alias_name="$2";
local func=$(cat <<EOT
# Generate a new completion function name
function _$alias_name() {
# Start off like _docker()
local previous_extglob_setting=\$(shopt -p extglob);
shopt -s extglob;
# Populate \$cur, \$prev, \$words, \$cword
_get_comp_words_by_ref -n : cur prev words cword;
# Declare and execute
declare -F $completion_function >/dev/null && $completion_function;
eval "\$previous_extglob_setting";
return 0;
};
EOT
);
eval "$func";
# Register the alias completion function
complete -F _$alias_name $alias_name
}
export -f docker_alias_completion_wrapper
然后我创建了我的别名/函数:
# Get container IP
dock-ip() { docker inspect --format '{{ .NetworkSettings.IPAddress }}' $@ ;}
docker_alias_completion_wrapper __docker_complete_containers_running dock-ip
# Execute interactive container
dock-exec() { docker exec -i -t --privileged $@ ;}
docker_alias_completion_wrapper __docker_complete_containers_all dock-exec
...
请务必调用配置文件别名脚本顶部的_completion_loader docker;
以加载主Docker完成脚本。我邀请更多熟练的bash程序员来改进这个答案。