台本を準備しています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関数をチェックして呼び出すために別のセクションを追加しましたが、これが良い方法であるかどうかはわかりません。
-
さらにもう1つの問題は、単一のフラグ(-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日と理解しています。また、これらの文字列を時間順に並べ替えることは、語彙順に並べ替えることとは異なります(フィールドの順序を変更した後もその部分がゼロで埋められないため)。
日付は国際形式です。 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
オプションが終わる場所を知らせるために1つが追加されたので、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