0

私は bash スクリプトを持っており、スクリプトの呼び出し中に渡されたオプションに基づいて、そのコマンドの一部をスキップできるようにしたい (つまり、実行しない)。

達成したいことを説明するためにif、基本的に同じことを達成するステートメントを含むスクリプトを作成しました。

if [ "$1" != "skipA" ]
    then
    echo "A"
fi

if [ "$1" != "skipB" ]
    then
    echo "B"
fi

if [ "$1" != "skipC" ]
    then
    echo "C"
fi

if [ "$1" != "skipD" ]
    then
    echo "D"
fi

スクリプトの呼び出し中に引数が渡されない場合、4 つのechoステートメントすべてが実行されます。これらの echo ステートメントのいずれかをスキップする場合はskipLETTER、最初の引数として次を使用します。

./script.sh skipA

を除くすべての文字Aが印刷されます。機能しますが、多くの制限があります。たとえば、同じ引数 ( $1) を使用して多くの部分をスキップすることはできません。オプションで同じことを達成したいので、次のように入力できます。

./script -skipA -skipD

その結果、文字のみBを印刷しCます。

これを使用getoptまたはgetopts達成できることはわかっていますが、説明したことを達成する簡単な使用例が見つかりません。

4

2 に答える 2

0

POSIX標準のgetoptsは長いオプションを実行できず、単一文字のオプションのみを実行できるため、質問で概説されている正確なインターフェイスには使用できません。

余談ですが、長いオプションは 1 つではなく 2 つのダッシュで導入する必要があります。そうしないと、ユーティリティの詳細を知らずに、-skipA が単一のオプション (可能な optarg を含む) であるか、または 5 つの単一文字であるかを判断する方法がありません。バンドルされているオプション (-x -yは と同じですが-xy、両方とも とは異なります--xy)。

移植可能なコード ( getopts spec ) をs使用してスキップオプションを選択する場合の簡単な例を次に示します。

#!/bin/sh

contains()
{
  case "$1" in
  *$2*) return 0 ;;
  esac
  return 1
}

requested()
{
  ! contains "$skip" "$1"
}

while getopts s: optname; do
  case $optname in
  s) skip="$OPTARG" ;;
  ?) exit 1 ;;
  esac
done

if requested A; then
  echo A
fi
if requested B; then
  echo B
fi
if requested C; then
  echo C
fi
if requested D; then
  echo D
fi

などでテストできます./skip-parts.sh -s AC。不明なオプションに反応し、 optarg-sがなくても、次のようなメッセージが表示されます。

./skip-parts.sh: illegal option -- x
./skip-parts.sh: option requires an argument -- s

デフォルトのエラー メッセージが気に入らない場合は、getopts(1) の最初の引数の前にコロンを付けてメッセージを消すことができます。大文字と?小文字の区別を付ける必要があります (オプションは、optnameをコロンに設定することにより、引数が必要です。 ...しかし、あなたはすでにドキュメントを読んだと言いました)。

于 2014-02-25T15:02:29.217 に答える