파일을 선택하고 특정 내용을 인쇄할 수 있는 스크립트를 작성 중입니다. 예를 들어,
san#./script.sh
Expected Usage : ./script.sh --file1 --dns
(여기서 file1을 확인하고 dns 이름을 검색해서 인쇄합니다. 기본적으로 하나의 매개변수 아래에 하위 매개변수가 있습니다)
다음과 같은 개별 매개변수/옵션을 시도했습니다.
options=$@
arguments=($options)
index=0;
for argument in $options
do
index=`expr $index + 1`;
case $argument in
-a | --fun1 ) run_function1 ;;
-b | --fun2 ) run_function2 ;;
-c | --fun3 ) run_function3 ;;
esac
done
exit;
[ ${1} ] || helpinfo
누구든지 이중 매개변수(하위 옵션)를 제안할 수 있나요?
의도된 대상 옵션:
./script.sh
OPTIONS : ./script.sh -h
./script --fun1 stackoverflow
microsoft
Google
--fun2 Yahoo
기본적으로 각 함수는 파일을 봅니다. getopt나 getopts를 살펴봤지만 긴 옵션이 없습니다(--long은 불가능하고 대신 -l만 사용할 수 있습니다). 하지만 다시 하위 매개변수에 대해서는 확실하지 않습니다. 이 문제를 해결하는 데 도움을 줄 수 있는 사람이 있나요? getopt
또는 을 (를) 사용하고 싶지 않습니다 getopts
.
답변1
이것은 제가 여기에 제공한 첫 번째 버전보다 더 사용자 친화적인 버전입니다. 특히 동등한 긴 옵션과 짧은 옵션에 대한 코드 중복을 방지합니다. 짧은 옵션( -q
), 긴 옵션( --quiet
), 인수가 있는 옵션, 누적 짧은 옵션( -qlfinput
대신 -q -l -f input
), 고유하게 축약된 긴 옵션( --qui
대신 --quiet
), 옵션 엔딩 등 원하는 모든 옵션을 처리해야 합니다 --
.
대부분의 코드는 수정되었습니다. 표시된 부분만 수정하면 됩니다.
#!/bin/bash
# Update USAGE (USAGE1, USAGE2, USAGE3 may remain unchanged):
USAGE='Usage: prog [-q|--quiet] [-l|--list] [-f file|--file file] [-Q arg|--query arg] args'
USAGE1='
Ambiguously abbreviated long option:'
USAGE2='
No such option:'
USAGE3='
Missing argument for'
# List all long options here (including leading --):
LONGOPTS=(--quiet --list --file --query)
# List all short options that take an option argument here
# (without separator, without leading -):
SHORTARGOPTS=fQ
while [[ $# -ne 0 ]] ; do
# This part remains unchanged
case $1 in
--) shift ; break ;; ### no more options
-) break ;; ### no more options
-*) ARG=$1 ; shift ;;
*) break ;; ### no more options
esac
# This part remains unchanged
case $ARG in
--*)
FOUND=0
for I in "${LONGOPTS[@]}" ; do
case $I in
"$ARG") FOUND=1 ; OPT=$I ; break ;;
"$ARG"*) (( FOUND++ )) ; OPT=$I ;;
esac
done
case $FOUND in
0) echo "$USAGE$USAGE2 $ARG" 1>&2 ; exit 1 ;;
1) ;;
*) echo "$USAGE$USAGE1 $ARG" 1>&2 ; exit 1 ;;
esac ;;
-["$SHORTARGOPTS"]?*)
OPT=${ARG:0:2}
set dummy "${ARG:2}" "$@"
shift ;;
-?-*)
echo "$USAGE" 1>&2 ; exit 1 ;;
-??*)
OPT=${ARG:0:2}
set dummy -"${ARG:2}" "$@"
shift ;;
-?)
OPT=$ARG ;;
*)
echo "OOPS, this can't happen" 1>&2 ; exit 1 ;;
esac
# Give both short and long form here.
# Note: If the option takes an option argument, it it found in $1.
# Copy the argument somewhere and shift afterwards!
case $OPT in
-q|--quiet) QUIETMODE=yes ;;
-l|--list) LISTMODE=yes ;;
-f|--file) [[ $# -eq 0 ]] && { echo "$USAGE$USAGE3 $OPT" 1>&2 ; exit 1 ; }
FILE=$1 ; shift ;;
-Q|--query) [[ $# -eq 0 ]] && { echo "$USAGE$USAGE3 $OPT" 1>&2 ; exit 1 ; }
QUERYARG=$1 ; shift ;;
*) echo "$USAGE$USAGE2 $OPT" 1>&2 ; exit 1 ;;
esac
done
# Remaining arguments are now in "$@":
echo "QUIETMODE = $QUIETMODE"
echo "LISTMODE = $LISTMODE"
echo "FILE = $FILE"
echo "QUERYARG = $QUERYARG"
echo "REMAINING ARGUMENTS:" "$@"
답변2
인용하다. 항상 인용됩니다. 의심스러운 경우. 의심의 여지가 없을 때;인용하다.
예: 귀하의 테스트 $1
,(으로 인해 도달하지 못함 exit
)./myscript "file name with spaces"
, 예를 들어 호출하면 스크립트가 중단됩니다 .
매개변수 루프의 경우 다음과 같이 시작할 수 있습니다.
#!/bin/bash
prnt_help()
{
printf "Usage: %s [OPTION]\n" $(basename "$1")
}
# A simple function only to visualize what gets passed and one of many
# ways to deal with it.
do_list()
{
printf "do_list:\n"
printf "OPT: %s\n" "$@"
printf "My list:\n"
while [[ -n "$1" && "${1:0:1}" != "-" ]]; do
printf "Processing %s\n" "$1"
shift
done
}
main()
{
while [[ -n "$1" ]];do
# This test is not needed, but include it if you find use for it.
if [[ "${1:0:1}" != "-" ]]; then
shift
continue
fi
# Check option and pass rest of arguments to matching function
printf "Checking option %s\n" "$1"
case "$1" in
"-l"|"--list") shift; do_list "$@";;
"-h"|"--help") prnt_help "$0";;
"--") printf "Rest is not options even if starts with -\n"
break;;
esac
shift
done
# If you use "--" to separate out e.g. filenames starting with -
# then process them here.
}
main "$@"
답변3
내장getopts
짧은 옵션만 구문 분석되지만(ksh93 제외) getopts가 긴 옵션을 처리하도록 스크립트 몇 줄을 추가할 수 있습니다.
이것은 다음에서 발견된 코드의 일부입니다.http://www.uxora.com/unix/shell-script/22-handle-long-options-with-getopts
#== set short options ==#
SCRIPT_OPTS=':fbF:B:-:h'
#== set long options associated with short one ==#
typeset -A ARRAY_OPTS
ARRAY_OPTS=(
[foo]=f
[bar]=b
[foobar]=F
[barfoo]=B
[help]=h
[man]=h
)
#== parse options ==#
while getopts ${SCRIPT_OPTS} OPTION ; do
#== translate long options to short ==#
if [[ "x$OPTION" == "x-" ]]; then
LONG_OPTION=$OPTARG
LONG_OPTARG=$(echo $LONG_OPTION | grep "=" | cut -d'=' -f2)
LONG_OPTIND=-1
[[ "x$LONG_OPTARG" = "x" ]] && LONG_OPTIND=$OPTIND || LONG_OPTION=$(echo $OPTARG | cut -d'=' -f1)
[[ $LONG_OPTIND -ne -1 ]] && eval LONG_OPTARG="\$$LONG_OPTIND"
OPTION=${ARRAY_OPTS[$LONG_OPTION]}
[[ "x$OPTION" = "x" ]] && OPTION="?" OPTARG="-$LONG_OPTION"
if [[ $( echo "${SCRIPT_OPTS}" | grep -c "${OPTION}:" ) -eq 1 ]]; then
if [[ "x${LONG_OPTARG}" = "x" ]] || [[ "${LONG_OPTARG}" = -* ]]; then
OPTION=":" OPTARG="-$LONG_OPTION"
else
OPTARG="$LONG_OPTARG";
if [[ $LONG_OPTIND -ne -1 ]]; then
[[ $OPTIND -le $Optnum ]] && OPTIND=$(( $OPTIND+1 ))
shift $OPTIND
OPTIND=1
fi
fi
fi
fi
#== discard option argument start with hyphen ==#
if [[ "x${OPTION}" != "x:" ]] && [[ "x${OPTION}" != "x?" ]] && [[ "${OPTARG}" = -* ]]; then
OPTARG="$OPTION" OPTION=":"
fi
#== manage options ==#
case "$OPTION" in
f ) foo=1 bar=0 ;;
b ) foo=0 bar=1 ;;
B ) barfoo=${OPTARG} ;;
F ) foobar=1 && foobar_name=${OPTARG} ;;
h ) usagefull && exit 0 ;;
: ) echo "${SCRIPT_NAME}: -$OPTARG: option requires an argument" >&2 && usage >&2 && exit 99 ;;
? ) echo "${SCRIPT_NAME}: -$OPTARG: unknown option" >&2 && usage >&2 && exit 99 ;;
esac
done
shift $((${OPTIND} - 1))
다음은 테스트입니다.
# Short options test
$ ./foobar_any_getopts.sh -bF "Hello world" -B 6 file1 file2
foo=0 bar=1
barfoo=6
foobar=1 foobar_name=Hello world
files=file1 file2
# Long and short options test
$ ./foobar_any_getopts.sh --bar -F Hello --barfoo 6 file1 file2
foo=0 bar=1
barfoo=6
foobar=1 foobar_name=Hello
files=file1 file2
그렇지 않으면최근 Korn Shell에서는ksh93은 getopts
긴 옵션을 자연스럽게 구문 분석하고 유사한 매뉴얼 페이지를 표시할 수도 있습니다. (바라보다http://www.uxora.com/unix/shell-script/20-getopts-with-man-page-and-long-options).