myscript
2つのパラメータを必要とするスクリプトがあります。
- CPU名
- 目次
私がするたびにzshの完成をどのように書くのですか?
mysript <TAB>
私のホストのリスト(つまり、完了したのと同じ)で行われssh
、実行するとき
mysript host1 <TAB>
これは/home/martin/test/
?のディレクトリで行われます。
答え1
この興味深い質問に感謝します。私のスクリプトでも同じことをしたいと思います。これ文書あいまいでわかりにくいです。スクリプトで実際のオプションなしで作業する方法を学んだことはありません。これは、実際のオプションを使用して目標を達成する最初の試みでした。
まず、オプションを使用するシェルスクリプトを作成しましたmyscript.sh
。
#!/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
私の場合は、ディレクトリの1つを選択しました。オートコンプリートファイルと見なされるファイル名は、_アンダースコア文字で始まります。_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>
要約ソリューション
2番目の試みでは、単純なシェルスクリプトを作成しました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
。