Bash에서 작은 스크립트를 다시 학습하고 있는데 getopt
두 번째 매개변수는 case
.
#! /bin/bash
LONG_OPTION_LIST=(
"arg-a"
"arg-b:"
"arg-c:"
)
SORT_OPTION_LIST=(
"a"
"b:"
"c:"
)
# Read the parameters
opts=$(getopt -q \
--longoptions "$(printf "%s," "${LONG_OPTION_LIST[@]}")" \
--name "$(basename "$0")" \
--options "$(printf "%s" "${SORT_OPTION_LIST[@]}")" \
-- "$@"
)
eval set -- "$opts"
echo "##$1##"
echo "##$2##"
echo "##$3##"
echo "##$4##"
echo "##$5##"
echo "#########"
argA=0
# It it is same a queue (process the head) because $1 and $2
for arg
do
echo $1
echo $2
echo "--------"
case "$arg" in
--arg-a | -a)
argA=1
shift 1
;;
--arg-b | -b)
argB=$2
shift 2
;;
--arg-c | -c)
argC=$2
shift 2
;;
*)
echo "###$1###"
echo "break"
echo "_________"
break
;;
esac
done
echo "argA $argA"
echo "argB $argB"
echo "argC $argC"
몇 가지 추가 예:
user@pc:/tmp$ ./test.bash -a
##-a##
##--##
####
####
####
#########
-a
--
--------
--
--------
###--###
break
_________
argA 1
argB
argC
user@pc:/tmp$ ./test.bash -b 111
##-b##
##111##
##--##
####
####
#########
-b
111
--------
--
--------
###--###
break
_________
argA 0
argB 111
argC
user@pc:/tmp$ ./test.bash -a -b 111
##-a##
##-b##
##111##
##--##
####
#########
-a
-b
--------
-b
111
--------
--
--------
###--###
break
_________
argA 1
argB 111
argC
user@pc:/tmp$ ./test.bash -b 111 -a
##-b##
##111##
##-a##
##--##
####
#########
-b
111
--------
-a
--
--------
###-a###
break
_________
argA 0
argB 111
argC
답변1
for arg do ... shift 1
여기서의 시프트는 원하는 대로 작동하지 않을 것이라고 생각합니다. 루프가 반복할 단어는 루프의 시작 부분에 설정되며 그 단어의 시프트는 영향을 미치지 않습니다. 예를 들어
$ set -- aa bb cc;
$ for x; do echo $x; shift; done
aa
bb
cc
"$@"
그러나 각 요소에 대해 한 번씩 이동하므로 루프 후에는 비어 있게 됩니다.
getopt
루프를 사용하는 대부분의 예에서는 및 를 while true
살펴보고 수동으로 이동하고 종결자가 나타나면 루프를 종료합니다 (util-linux getopt는 항상 종결자를 추가하지만 옵션이 아닌지 수동으로 확인할 수도 있습니다).$1
$2
--
예를 들어 참조하십시오.
답변2
이 값은 변환할 필요가 없습니다. 자동으로 완료됩니다. shift 2
다음 옵션은 실제로 숨겨져 있습니다.
사례를 작성하는 표준 방법은 다음과 같습니다.
for arg
do
echo $1
echo $2
echo "--------"
case "$arg" in
--arg-a | -a)
argA=1
;;
--arg-b | -b)
argB=$2
;;
--arg-c | -c)
argC=$2
;;
esac
shift
done
사건 이후의 단일 교대를 주목하십시오.
또한 이 경우 *를 입력하면 안 됩니다. 어떤 옵션에도 반응합니다. 예상치 못한 옵션에 대한 맞춤형 대응이 필요한 경우 다음을 수행하는 것이 가장 좋습니다.
opts=$(getopt ... )
[ $? -eq 0 ] || {
echo "Known options are..."
exit 1
}
답변3
for
@ikkachu가 말했듯이 오류가 사용 중입니다 while
. 감사합니다.
여기에 사용되는 작은 스크립트가 있습니다 getopt
:
#! /bin/bash
#~ get_opt.example.sh
#~ Copyright (C) 2022 Miguel de Dios Matias
#~ This program is free software: you can redistribute it and/or modify
#~ it under the terms of the GNU General Public License as published by
#~ the Free Software Foundation, either version 3 of the License, or
#~ (at your option) any later version.
#~ This program is distributed in the hope that it will be useful,
#~ but WITHOUT ANY WARRANTY; without even the implied warranty of
#~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#~ GNU General Public License for more details.
#~ You should have received a copy of the GNU General Public License
#~ along with this program. If not, see <http://www.gnu.org/licenses/>.
: '
Examples the calls:
$ ./getopt.example.bash --arg-b 111 -a 2222 3333
argA 1
argB 111
argC
argD 0
unamedOptions 2222 3333
'
function help() {
echo "$0 [(--arg-a | -a)] [(--arg-b | -b) <data_b>] [(--arg-c | -c <data_c>)] [-d] [(--help | -h)]"
}
LONG_OPTION_LIST=(
"arg-a"
"arg-b:"
"arg-c:"
"help"
)
SORT_OPTION_LIST=(
"a"
"b:"
"c:"
"d"
"h"
)
# Read the parameters
opts=$(getopt -q \
--longoptions "$(printf "%s," "${LONG_OPTION_LIST[@]}")" \
--name "$(basename "$0")" \
--options "$(printf "%s" "${SORT_OPTION_LIST[@]}")" \
-- "$@"
)
eval set -- "$opts"
argA=0
argD=0
unamedOptions=()
# It it is same a queue (process the head) because $1 and $2
while true
do
case "$1" in
--arg-a | -a)
argA=1
;;
--arg-b | -b)
argB=$2
shift 1
;;
--arg-c | -c)
argC=$2
shift 1
;;
-d)
argD=1
;;
--help | -h)
help
exit 0
;;
--)
# End options now the unamed options
;;
*)
unamedOptions+=("$1")
;;
esac
shift 1
if [ $# -eq 0 ]
then
break
fi
done
echo "argA $argA"
echo "argB $argB"
echo "argC $argC"
echo "argD $argD"
echo "unamedOptions ${unamedOptions[@]}"