대본을 준비 중이에요 getopt
. 도움말 섹션을 추가하고 싶습니다. 따라서 함수를 사용 --help
하거나 -h
실행해야 하는 경우(설명만 인쇄) 반환합니다.
샘플 코드:
log_type='unset'
state='unset'
date='unset'
help='unset'
mode="$1"
usage()
{
echo "Usage: LogRotator [ -t | --log_type - Allowed values: [access error] ]
[ -s | --state - Allowed values: [archive or backup] ]
[ -d | --date 1-10-2020]
[ -h | --help]
Modes:
1) list - list the files
2) restore - restore the files"
exit 2
}
ARGUMENT_LIST=(
"log-type"
"state"
"date"
)
# read arguments
opts=$(getopt \
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")",help \
--name "$(basename "$0")" \
--options "" \
-- "$@"
)
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
usage
fi
eval set --$opts
while [[ $# -gt 0 ]]; do
case "$1" in
-t | --log-type)
log_type=$2
shift 2
;;
-s | --state)
state=$2
shift 2
;;
-d | --date)
date=$2
shift 2
;;
-h | --help)
help=1
shift
;;
*)
break
;;
esac
done
if [[ "$help" == 1 ]]
then
usage
fi
위 스크립트는 잘 작동하지만 using 함수를 확인하고 호출하기 위해 별도의 섹션을 추가했는데 이것이 좋은 방법인지는 잘 모르겠습니다.
-
또한 또 다른 문제는 단일 플래그(예: -h -t)를 허용하지 않는다는 것입니다.
나는 -o tsdh
성공하지 않고 추가하려고 시도했습니다.
예상 출력:
./script -h
Usage: LogRotator [ -t | --log_type - Allowed values: [access error] ]
[ -s | --state - Allowed values: [archive or backup] ]
[ -d | --date 1-10-2020]
Modes:
1) list - list the files
2) restore - restore the files
답변1
나는 이것을 코드 리뷰로 작성했습니다:
첫째, Shebang을 지정하지 않았습니다. Shebang이 없으면 스크립트는 에 의해 작성됩니다 sh
. 귀하의 코드는 문법적이지 않습니다 sh
. 가장 유사한 구문을 가진 쉘은 입니다 . 그러나 zsh
인용되지 않은 경우 $opts
ksh93 및 bash에서도 작동합니다 . 나는 zsh
그것을 작성하는 더 좋은 방법이 있을 것이기 때문에 bash용으로 설계되었다고 생각합니다 .
그래서 여기 있습니다:
#! /bin/bash -
또는:
#! /usr/bin/env bash
지원이 bash
불가능합니다 /bin
.
log_type='unset' state='unset' date='unset' help='unset'
여기서 특정 문자열을 기본값으로 사용하면 사용자가 옵션을 지정하지 않았는데 값이 로 되어 있는 상황을 없앨 수는 없습니다 unset
.
여기서는 그냥 하고 싶어요
unset -v log_type state date help
부울 값의 경우 help=false
.
mode="$1"
여기에서 첫 번째 인수를 저장 $mode
하지만 존재하는지 확인하지 않거나 인수 목록에서 제거합니다. 즉, getopt
인수도 받게 됩니다!
아마도:
case $1 in
(list | restore) mode=$1; shift;;
(*) usage;;
esac
(함수 선언 후 usage
).
usage() { echo "Usage: LogRotator [ -t | --log_type - Allowed values: [access error] ] [ -s | --state - Allowed values: [archive or backup] ]
이러한 [ -t
합계는 [ -s
스크립트의 소스 코드에서 정렬되지만 들여쓰기로 인해 출력에는 표시되지 않습니다. 또한 here 와 같이 스크립트 이름을 하드코딩 LogRotator
하지만 basename
나중에 사용합니다. $0
또한 사용법 메시지는 stderr로 전송되어야 합니다.
PROGNAME=${0##*/}
usage() {
cat << EOF >&2
Usage: $PROGNAME ...
EOF
[ -d | --date 1-10-2020]
이것은 1-10-2020
아마도 최악의 날짜 형식일 것입니다. 첫째, 모호합니다. 대부분의 사람들은 이를 10월 1일로 이해하지만 북미 일부 지역에서는 1월 10일로 이해합니다. 또한 이러한 문자열을 시간순으로 정렬하는 것은 어휘순으로 정렬하는 것과 다릅니다(필드 순서를 변경한 후에도 해당 부분이 0으로 채워지지 않기 때문에).
날짜는 국제 형식을 갖습니다. 2020-10-01은 대부분의 인력 및 유틸리티 회사에서 인정하는 표준이 될 것이며, 연대순과 어휘순으로 동일하게 정렬됩니다.
[...]
ARGUMENT_LIST=( "log-type" "state" "date" )
모든 대문자 변수를 유지하는 것이 좋습니다환경변하기 쉬운.
# read arguments opts=$(getopt \ --longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")",help \
:,
여기서는 모든 요소에 추가하여 $ARGUMENT_LIST
얻을 수 있습니다 log-type:,state:,date:,,help
.
--name "$(basename "$0")" \
"$(basename -- "$0"}"
아니면 여기 여야 합니다 ${0##*/}
. 이것이 "$PROGNAME"
우리가 앞서 정의한 것입니다.
--options "" \
이는 단일 문자 옵션에 대한 것이므로 여기에서 지정해야 합니다.
--options hs:d:t:
-- "$@" ) VALID_ARGUMENTS=$? if [ "$VALID_ARGUMENTS" != "0" ]; then
if
명령이 성공했는지 확인하십시오. 그것이 바로 그 일입니다.
그래서 그냥:
if
! opts=$(
...
)
then
usage
fi
그렇지 않으면:
opts=$(...) || usage
여기.
usage fi eval set --$opts
따옴표가 없는 인수 확장은 분할+glob을 호출하는데, 이는 여기서는 의미가 없습니다. 또한 --
여기서는 나머지 항목과 분리 해야 합니다 . 이것이 set -- <contents-of-$opts>
쉘 코드로 평가되기를 원하는 것입니다.
eval "set -- $opts"
while [[ $# -gt 0 ]]; do case "$1" in -t | --log-type) log_type=$2
사용된 경우 사용자에게 경고하려면 여기에 허용된 설정과 비교하여 제공된 값을 확인해야 합니다 -t blah -t error
. 또한 마지막으로 지정된 유형만 고려된다는 점을 사용자에게 경고할 수도 있습니다.
shift 2 ;; -s | --state) state=$2 shift 2 ;; -d | --date) date=$2
들여쓰기에 주의하세요. 일관된 들여쓰기는 코드를 더 읽기 쉽게 만들고 일부 오류를 방지하는 데 도움이 됩니다.
shift 2 ;; -h | --help) help=1 shift ;; *) break
옵션이 끝나는 위치를 알려주기 위해 하나가 추가되었기 shift; break
때문에 여기에 있어야 합니다 .getopt
--
;; esac done
이 시점에서 더 많은 매개변수를 사용할 수 있는지 확인하고 예상과 다르면 오류를 보고할 수 있습니다.
[ "$#" -eq 0 ] || usage
if [[ "$help" == 1 ]] then usage fi
help=false
/를 사용했다면 help=true
다음과 같습니다.
if "$help"; then
usage
fi
답변2
에 짧은 옵션을 추가하여 스크립트를 수정했습니다 getopt
. :
각 옵션 뒤에는 opt
옵션에 인수가 필요하다는 의미가 있습니다.
#!/bin/bash
log_type='unset'
state='unset'
date='unset'
help='unset'
mode="$1"
usage()
{
echo "Usage: LogRotator [ -t | --log_type - Allowed values: [access error] ]
[ -s | --state - Allowed values: [archive or backup] ]
[ -d | --date 1-10-2020]
[ -h | --help]
Modes:
1) list - list the files
2) restore - restore the files"
exit 2
}
ARGUMENT_LIST=(
"log-type"
"state"
"date"
)
# read arguments
opts=$(getopt \
-o t:s:d:h \
--longoptions "$(printf "%s:," "${ARGUMENT_LIST[@]}")",help \
--name "$(basename "$0")" \
-- "$@"
)
VALID_ARGUMENTS=$?
if [ "$VALID_ARGUMENTS" != "0" ]; then
usage
fi
eval set -- $opts
while [[ $# -gt 0 ]]; do
case "$1" in
-t | --log-type)
log_type=$2
shift 2
;;
-s | --state)
state=$2
shift 2
;;
-d | --date)
date=$2
shift 2
;;
-h | --help)
help=1
shift
;;
*)
break
;;
esac
done
if [[ "$help" == 1 ]]
then
usage
fi