我有一个带有myscript
两个参数的脚本:
我该如何编写自己的zsh补全,以便每次执行时
mysript <TAB>
它从我的主机列表中完成(即与之相同ssh
),并且当我完成时
mysript host1 <TAB>
它从目录中完成/home/martin/test/
吗?
谢谢您提出有趣的问题。我想在我的脚本中做同样的事情。该文档很密集,不太容易理解。我还没有学会在脚本中没有实际选项的情况下工作。这是我用实际选项实现目标的第一次尝试。
首先,我创建了一个myscript.sh
使用选项的名为shell脚本。
#!/usr/bin/env sh
self=$(basename "$0")
hflag=0 # Boolean: hflag is not yet detected
dflag=0 # Boolean: dflag is not yet detected
function usage() {
echo "Usage: $self [ -h <hostname> | -d <directory> ]"
}
# If no options were given, exit with message and code.
if (($# == 0)); then
usage
exit 1
fi
# Process options and option arguments.
while getopts ":h:d:" option; do
case "${option}" in
h ) hflag=1 # The h option was used.
host=${OPTARG} # The argument to the h option.
;;
d ) dflag=1 # The d option was used.
dir=${OPTARG} # The argument to the d option.
;;
\?) # An invalid option was detected.
usage
exit 1
;;
: ) # An option was given without an option argument.
echo "Invalid option: $OPTARG requires an argument" 1>&2
exit 1
;;
esac
done
# One of hflag or dflag was missing.
if [ $hflag -eq 0 ] || [ $dflag -eq 0 ]; then
usage
exit 1
fi
# Do something with $host and $dir.
# This is where the actions of your current script should be placed.
# Here, I am just printing them.
echo "$host"
echo "$dir"
# Unset variables used in the script.
unset self
unset hflag
unset dflag
接下来,我确定了在哪里zsh
寻找自动完成文件。
print -rl -- $fpath
/usr/local/share/zsh/site-functions
在我的情况下,我选择了其中一个目录。被视为自动完成文件的文件名以下划线_字符开头。我_myscript
在目录中创建了文件。后面的部分#compdef
是上面的实际脚本名称。
#compdef myscript.sh
_myscript() {
_arguments '-h[host]:hosts:_hosts' '-d[directory]:directories:_directories'
}
_myscript "$@"
然后执行compinit
以获取_myscript
文件提供的新的自动完成定义。结果是,我现在可以使用制表符补全在-h
选项之后指定主机,在选项之后指定目录,-d
同时在脚本本身中的选项和选项参数解析中仍保持一定的理智。选项卡补全甚至在调用之前就显示可用的选项myscript.sh
,并使选项顺序无关紧要。
用法如下所示。
myscript.sh -h <TAB> -d ~/test/<TAB>
第二次尝试,我创建了一个简单的shell脚本zscript.sh
。
#!/usr/bin/env sh
echo "$1"
echo "$2"
然后我创建了一个文件/usr/local/share/zsh/site-functions/_zscript
。
#compdef zscript.sh
_zscript() {
_arguments '1: :->hostname' '2: :->directory'
case $state in
hostname)
_hosts
;;
directory)
_directories -W $HOME/test/
;;
esac
}
我执行了compinit
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句