ヘルプパラメータを持つシェルgetopt

ヘルプパラメータを持つシェルgetopt

台本を準備しています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、引用符がない場合は$optsksh93と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

関連情報