myscript
두 개의 매개변수가 필요한 스크립트가 있습니다 .
- 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
제 경우에는 디렉토리 중 하나를 선택했습니다. 자동 완성 파일로 간주되는 파일 이름은 _밑줄 문자로 시작됩니다. _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>
요약 솔루션
두 번째 시도에서는 간단한 쉘 스크립트를 만들었습니다 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
.