我添加了一个新的别名scp_using_rsync
,它使用rsync通过SSH复制文件并使用某些选项。我想将scp的bash完成链接到此别名。
当我添加这一行时它会起作用:
complete -o bashdefault -o default -o nospace -F _scp scp_using_rsync 2>/dev/null || complete -o default -o nospace -F _scp scp_using_rsync
唯一的问题是,我注意到_scp
在我的bash环境中定义,只有在我尝试使用ssh / scp在该shell中至少执行一次tab-completion之后。因此,如果我在新shell中直接运行scp_using_rsync
,我会收到_scp
未找到的错误。
在为ssh或scp命令尝试制表符完成之前和之后,新shell中typeset -F
的输出清楚地表明在第一次尝试制表完成后会定义以下函数:
$ diff ~/.scratch/file1 ~/.scratch/file2
224a225,227
> declare -f _scp
> declare -f _scp_local_files
> declare -f _scp_remote_files
226a230
> declare -f _sftp
230a235,240
> declare -f _ssh
> declare -f _ssh_ciphers
> declare -f _ssh_macs
> declare -f _ssh_options
> declare -f _ssh_suboption
> declare -f _ssh_suboption_check
这些功能似乎在我系统的/usr/share/bash-completion/completions/ssh
中定义。
这是我的两个相互关联的问题:
scp_using_rsync
的bash-completion与scp的bash完成相关联?答案 0 :(得分:6)
Bash 4.1
为-D
,complete
和compgen
添加了新的compopt
选项:
用于定义“默认”完成的新的complete / compgen / compopt -D选项: 要在没有完成的命令上调用的完成 定义即可。如果此函数返回 124 ,则可编程完成 再次尝试,允许用户动态构建一组完成 通过具有默认完成功能来尝试完成 每次调用时都安装各个完成函数。
有一个来自bash的manual:
的例子_completion_loader()
{
. "/etc/bash_completion.d/$1.sh" >/dev/null 2>&1 && return 124
}
complete -D -F _completion_loader
答案 1 :(得分:3)
我在应用whjm的答案时遇到了问题。正如Tuxdude注意到的那样,我的发行版中已经定义了一个函数_completion_loader
(Ubuntu 14.04)。该功能定义如下:
_completion_loader ()
{
local compfile=./completions;
[[ $BASH_SOURCE == */* ]] && compfile="${BASH_SOURCE%/*}/completions";
compfile+="/${1##*/}";
[[ -f "$compfile" ]] && . "$compfile" &> /dev/null && return 124;
complete -F _minimal "$1" && return 124
}
我想在一个地方保持完成的维护,所以我在/usr/share/bash-completion/completions/
添加了一个文件,其中包含我想要添加完成的命令的名称。对于您的情况,您可以添加一个名为scp_using_rsync
的文件,其中包含以下内容:
cfile="${compfile%/*}/scp"
cmd="${1##*/}"
. "$cfile"
complete -F _scp $cmd
这将获取定义scp
的完成的文件,包括_scp
函数,然后为命令添加完成。我觉得这是一种更直接,更一致的方式(当然,要做到这一点,你必须为所有用户改变这种行为。)
答案 2 :(得分:0)
一些完成功能是动态加载的。您可以手动加载它们,以便它们可以使用别名。例如,您可以将其添加到~/.bashrc
中,以便使用别名进行补全。
_completion_loader docker