bashスクリプトのパラメーターのいずれかが文字列と一致するかどうかを確認します


67

bashスクリプトに渡されたパラメーターのいずれかが文字列と一致するかどうかを確認するスクリプトを作成しようとしています。今のセットアップ方法は

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]

しかし、多くのパラメータがあるかもしれないので、これを行うより良い方法があるのだろうかと思っていましたか?

ありがとう

編集:このコードの塊を試し、オプション-disableVenusBldを指定してスクリプトを呼び出しましたが、それでも「Starting build」が出力されます。私は何か間違っていますか?前もって感謝します!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi

返信をありがとう、私は私を助けるために時間を割いてくれて感謝しています。大量のコードを試しましたが、何が間違っているのかわかりません。何か案は?(元の投稿の編集でコードを貼り付けました)
iman453

うーん:それは私のために動作します。#! /bin/sh -そこに含まれているものの先頭に追加し、スクリプトを実行可能にし、./t.sh「Starting build」を./t.sh -disableVenusBld出力しますが、何も出力しません。
ノーマングレイ

回答:


59

シェルスクリプトでオプション処理を行っているようです。そのイディオムは次のとおりです。

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0

(をインデントするためのいくつかの規則があり;;、一部のシェルでは、オプションをとして指定(--opt1)してブレースのマッチングを支援できますが、これは基本的な考え方です)


3
shiftコマンドの引数の数が事前に知られていないとき、彼らは好きなように、ユーザーが多くの引数として与えることができたときのステートメントは、例えば、使用されています。このような場合、引数はwhileのテスト条件でループで処理されます$#。引数の数がゼロより大きい限り、この条件は真です。$1変数とshift文は各引数を処理します。引数の数shiftは実行されるたびに減少し、最終的にゼロになり、whileループが終了します。ソース
セルジュストローバンド


26

これは私のために働いた。まさにあなたが要求したことを行い、それ以上のことはしません(オプション処理は行いません)。それが良いか悪いかは、ポスターの練習です:)

if [[ "$*" == *YOURSTRING* ]]
then
    echo "YES"
else
    echo "NO"
fi

これは、特別な処理$* とbashスーパーテスト[[]]ブラケットを利用します。


2
私見では、これは最も正しい答えでなければなりませんでした。なぜなら、質問はパラメータの存在をチェックするだけでよいからです。ただし、テスト対象の文字列にスペースが含まれている可能性があり、それに関するbashのドキュメントへのリンクが追加されたため、に変更$*して編集$@しました。
h7r

9
=〜演算子を使用するつもりでしたか?そうしないと、なぜこれが機能するのかわかりません。実際、正確なスクリプトを試しても機能しません。
セポエナルヴィ

3
動作していません。bash -c 'echo args=$*; [[ "$@" == "bar" ]] && echo YES || echo NO' -- foo bar
トビア

2
これにより、引数リスト全体がと比較されyour stringます。この答えが示唆することをする必要があると思います。すなわち:bash -c 'echo args=$*; for i in "$@" ; do [[ $i == "bar" ]] && echo "Is set!" && break ; done' -- bar foo動作します。
スターフライ16

2
h7rの編集が壊れたため、この答えは過去4年間間違っていました。「あなたの文字列」にグロブ文字が含まれておらず、いくつかの誤検出がある場合、元の答え(今復元しています)は機能します。たとえば、コマンドがでcreate a new certificate、「文字列」がのcat場合、がcertificate 含まれて catいるため一致が報告されます
スコット

8

パラメータスペース全体を(ワイルドカードで)検索する方法は次のとおりです。

if [[ $@ == *'-disableVenusBld'* ]]
then

編集:わかりました、それでそれは一般的な答えではありませんでした。これはどうですか、完璧です!:

if [[ "${@#-disableVenusBld}" = "$@" ]]
then
    echo "Did not find disableVenusBld"
else
    echo "Found disableVenusBld"
fi

Edit2:OK、OK、これは完璧ではないかもしれません... -paramがリストの先頭にあり、-paramXZYまたは-paramABCにも一致する場合にのみ機能すると思います。私はまだ元の問題はbash文字列操作で非常にうまく解決できると思いますが、ここではそれをクラックしていません...-できますか??


2番目の提案-フィルター置換を完全置換と比較する-は合理的に機能し、引数のリストを混乱させないという利点があります。
ドナルドフェローズ

2番目の提案(特に${@#)が何をするのか説明してもらえますか?
velop

1
@velop確かに!あなた$@はそれがすべてのコマンドライン引数を保持する特別な変数であることを知っていますか?さて、その変数でBash文字列操作を使用してサブストリング「-disableVenusBld」を削除し、それを元のものと比較しました$@。あれば$@イコールは-foo -barその後、${@#-disableVenusBld}まだだろう-foo -barので、私は私が探しているフラグが存在しないことがわかります。しかし、場合$@等号は-foo -disableVenusBld -barその後${@#-disableVenusBld}になり-foo -barこれに等しくされていない$@ので、私が探しているフラグが存在していることを私に言って、!かっこいい!
リッチ

ここでのバッシュの文字列操作の詳細情報@velop:tldp.org/LDP/abs/html/string-manipulation.html
リッチ

@Richはかなりきちんとした^^、説明のためのthx。
velop

4
disCopperBld=
for x; do
  if [ "$x" = "-disCopperBld" ]; then disCopperBld=1; break; fi
done
if [ -n "$disCopperBld" ]; then
  ...
fi

で始まるパラメーターのみをテストする必要がある場合$3は、関数で検索を実行します。

## Usage: search_trailing_parameters NEEDLE NUM "$@"
## Search NEEDLE amongst the parameters, skipping $1 through ${$NUM}.
search_trailing_parameters () {
  needle=$1
  shift $(($2 + 2))
  for x; do
    if [ "$x" = "$needle" ]; then return 0; fi
  done
  return 1
}
if search_trailing_parameters -disCopperBld 2 "$@"; then
  ...
fi

でも、そもそもなぜこれをやろうとしているのだろう、それは一般的な必要ではない。通常、前の質問に対するデニスの回答のように、オプションを順番に処理します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.