我正在尝试bash_completion
为我的脚本创建规则rmpxe
。该脚本将<hostname>
其作为唯一参数。然后它将此主机名解析为<ip_address>
并删除相应的 symlink /srv/tftp/pxelinux.cfg/<ip_address>
。
<ip_address>
符号链接中的 ip 地址/srv/tftp/pxelinux.cfg/<ip_address>
是十六进制格式,但我用 C ( getnameinfo
)编写了一个简单的程序,将这个十六进制 ip 地址解析为主机名。
因此,我可以使用我的程序getnameinfo
从十六进制 IP 获取主机名:
$ getnameinfo 0A6F010B
server1.mydomain.com
Run Code Online (Sandbox Code Playgroud)
例如,以下命令将删除符号链接 /srv/tftp/pxelinux.cfg/0A6F010B
$ rmpxe server1.mydomain.com
Run Code Online (Sandbox Code Playgroud)
现在我的bash_completion
问题:我创建了以下代码,它工作正常,除了完成主机名(如我的脚本所期望的)之外,它完成了十六进制 IP 地址(即我目录中的符号链接文件/srv/tftp/pxelinux.cfg/
)。我需要以某种方式集成到此代码中,在参数自动完成之前,它将首先解析为主机名。
_rmpxe()
{
local word
COMPREPLY=()
if [ 1 -eq "$COMP_CWORD" ]; then
pushd /srv/tftp/pxelinux.cfg &>/dev/null || return 1
word="${COMP_WORDS[COMP_CWORD]}"
COMPREPLY=($(compgen -f "$word"))
popd &>/dev/null
fi
}
complete -F _rmpxe rmpxe
Run Code Online (Sandbox Code Playgroud)
换句话说,目前我的 bash 完成工作是这样的:
$ ls /srv/tftp/pxelinux.cfg
0A6F010B 0A6F010C 0A6F010D 0A6F010E
$ rmpxe <tab>
0A6F010B 0A6F010C 0A6F010D 0A6F010E
Run Code Online (Sandbox Code Playgroud)
而,我需要它像这样工作:
$ rmpxe <tab>
server1.mydomain.com server2.mydomain.com server3.mydomain.com
Run Code Online (Sandbox Code Playgroud)
因为您使用了compgen -f
,含义compgen
将列出当前路径下的所有文件和目录。在你的情况下,这意味着0A6F010B 0A6F010C 0A6F010D 0A6F010E
.
要获取主机名,您可以循环遍历当前路径,将每个 IP 提供给以getnameinfo
获取与该 IP 对应的主机名,将其保存到数组中,然后将此数组用作带有compgen -W
.
我在我的环境中做了一个简单的测试。我创建了一个文件/etc/bash_completion.d/cuonglm
:
_rmpxe() {
local word
COMPREPLY=()
if [ 1 -eq "$COMP_CWORD" ]; then
pushd /home/cuonglm/test &>/dev/null || return 1
word="${COMP_WORDS[COMP_CWORD]}"
HOST_ARR=()
for i in *; do
HOST_ARR+=($(/home/cuonglm/getnameinfo "$i"))
done
COMPREPLY=($(compgen -W "$(printf "%s " "${HOST_ARR[@]}")" -- "$word"))
popd &>/dev/null
fi
}
complete -F _rmpxe cuonglm
Run Code Online (Sandbox Code Playgroud)
我使用了你的完整功能并做了一些修改:
HOST_ARR
来保存主机名。pushd
之前感谢),将每个文件名输入getnameinfo
程序。compgen -W
compgen 创建一个单词列表来完成。这是结果:
$ cuonglm <Tab>
$ cuonglm server<Tab>
server1.example.com server2.example.com
Run Code Online (Sandbox Code Playgroud)
因为两个主机名具有相同的部分server
,所以 bash 将首先自动完成这部分。如果有其他主机名Server.example
:
$ cuonglm <Tab>
Server.example server1.example.com server2.example.com
Run Code Online (Sandbox Code Playgroud)