Bash:シフト中の使用方法。do..case $ 1 in


5

私はbashスクリプトに取り組んでおり、「オプション」を実装する必要があります。どうすればbashでできますか?

私の目標は、次の方法でスクリプトを実行することです。 /myscript.sh -d "/var/log/" -c "test"

私が試したこと:

while shift; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
done

echo "$DIR"
echo "$COMMAND"

そして、これを試してみるとどうなりますか?
デニス

-c)ケースのみを印刷
テスラシムス

回答:


5

@chorobaの答えを拡張するために、使用方法の例を示しますgetopts

# parse the flag options (and their arguments)
while getopts c:d: OPT; do
    case "$OPT" in
      d)
        DIR="$OPTARG" ;;
      c)
        COMMAND="$OPTARG" ;;
      [?])
        # got invalid option
        echo "Usage: $0 [-d directory] [-c command]" >&2
        exit 1 ;;
    esac
done

# get rid of the just-finished flag arguments
shift $(($OPTIND-1))

フラグ引数をシフトオフした後、「通常の」引数はすべて残ることに注意してください。そのため、その時点でそれらに対処することができます(例... for arg in "$@"; do ...)、またはスクリプトがそれらを取得する場合に不満を感じない場合(if [ $# -gt 0 ]; then echo "Usage ...)。


getoptは外部依存関係です。元の著者は、getoptではなく、シフトについてのみ尋ねました。
-heroxbd

@heroxbd getoptは外部コマンドですgetoptsが、シェル組み込みである( "s"に注意)をお勧めします。
ゴードンデイヴィソン

8

あなたの間違いは、あなたがそれを調べる前に最初の引数を投げ、ループの先頭でシフトしていることです。これはおそらくあなたが意味するものだと思います:

#!/bin/bash
while (( "$#" )); do
   case $1 in
      -d)
         shift&&DIR="$1"||die
         ;;
      -c)
         shift&&COMMAND="$1"||die
         ;;
   esac
   shift
done

echo "$DIR"
echo "$COMMAND"

死ぬ?bashはPerlではない
グレンジャックマン

@glennjackman良いコメント。私はそれを問題の可能性として捉えませんでした。(OPは、苦情は-cのみを出力するということだと説明していることに注意してください)die
ニコールハミルトン

右、私は...間違った人にコメント
グレン・ジャックマン

2

chorobaが既に言ったように、getoptsはより良いアプローチです。

あなたの場合、次を使用できます:

getopts c:d: d || die
DIR=$OPTARG
getopts c:d: c || die
COMMAND=$OPTARG

whileループでやろうとしていることを達成するために。

文字列c:d:は、可能なスイッチを指定します。コロンは、スイッチに引数が必要であることを意味します。

アプローチの問題はshift、最初の引数を分析する前に呼び出して、プロセスで破棄することです。

これを修正するには、whileループを次のように変更します。

while true; do
        case $1 in
                -d)
                        shift&&DIR="$1"||die
                ;;
                -c)
                        shift&&COMMAND="$1"||die
                ;;
        esac
        shift || break
done

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