2

2 つの必須引数 (arg1、arg2) と、オプションの -b フラグに加えて、ユーザーがフラグの使用を選択した場合に必要な引数を持つシェル スクリプトを作成しようとしています。

説明させてください:

これは、GIT を利用して Github リポジトリからアプリケーションをフェッチするインストール スクリプトです。ユーザーは端末に入力します f.ex.:

./shellscript.sh new <app_name> # fetches master branch by default

スクリプトは、このリポジトリから master ブランチのインスタンスをフェッチします。ただし、ユーザーがオプションの -b フラグを使用することを選択した場合、フェッチするブランチ (開発ブランチなど) を指定する必要があることを意味します。ユーザーができることを意味します:

./shellscript.sh new <app_name> -b develop # or which ever branch there is available

また、ユーザーが 'new' 引数と 'app_name' 引数の前に -b flag+branch_name を入力しても問題にならないように、スクリプトを機能させる方法についても知りたいです。しかし、それはおそらく現時点で最も重要なことではありません。

私が構築しようとしているものを正確に知るために、2 つの必須引数のみを取り、マスター ブランチのみをフェッチする現在のスクリプトへのリンクを次に示します。My Super Cool Artisan Executable Script

PS: getopts を使用して多くの例を試してきましたが、ここ Stackoverflow と他のブログの両方で見つけましたが、完全に機能させるのに役立つものはありませんでした。ですから、私はここで皆さんの偉大な人々に助けを求めています。

多大な感謝と私のLinux Mint / Ubuntu - Post Install Scriptをチェックしてください。

よろしく、 ヴィリ

4

3 に答える 3

6

私は通常、短いオプションと長いオプションを許可するために独自に記述します。

function Usage()
{
cat <<-ENDOFMESSAGE

$0 [OPTION] REQ1 REQ2

options:

    -b -branch  branch to use
    -h --help   display this message

ENDOFMESSAGE
    exit 1
}

function Die()
{
    echo "$*"
    exit 1
}

function GetOpts() {
    branch=""
    argv=()
    while [ $# -gt 0 ]
    do
        opt=$1
        shift
        case ${opt} in
            -b|--branch)
                if [ $# -eq 0 -o "${1:0:1}" = "-" ]; then
                    Die "The ${opt} option requires an argument."
                fi
                branch="$1"
                shift
                ;;
            -h|--help)
                Usage;;
            *)
                if [ "${opt:0:1}" = "-" ]; then
                    Die "${opt}: unknown option."
                fi
                argv+=(${opt});;
        esac
    done 
}

GetOpts $*
echo "branch ${branch}"
echo "argv ${argv[@]}"
于 2013-06-10T02:39:11.350 に答える
2

Unix ユーティリティは通常、位置引数の前にオプションの引数 (「フラグ」) を取りますが、C ライブラリ関数の GNU 実装を含むほとんどの GNU ユーティリティはgetopt、オプションの引数が最初に来るようにコマンド ライン引数をシャッフルします。ただし、組み込みの bashgetoptsはシャッフルしません。つまり、シャッフルするかどうかはユーザー次第です。

getopts常に変数の値を番号とする引数で始まりますOPTIND。(OPTIND は、bash 関数が実行されるたびに 1 に設定されます。これはグローバル変数です。したがって、相互に呼び出す bash 関数には少し注意が必要です。) 必要に応じて、OPTIND を自分で設定し、次のへの呼び出しgetoptsはそのインデックスで始まります。または、 を使用shiftして、すべてのコマンド ライン引数をシフトすることもできます。

したがって、たとえば、次のようにすることができます。

# "shift" version: always shift consumed arguments
local verb="$1" branch=master app_name option
shift
case $verb in
  new)  app_name="$1"
        shift
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done
        shift $((OPTIND - 1));;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > 0))

または:

# non-shift version: use OPTIND to index arguments
local verb="${!OPTIND}" branch=master app_name option
OPTIND=$((OPTIND + 1))
case $verb in
  new)  app_name="${!OPTIND}"
        OPTIND=$((OPTIND + 1))
        while getopts b: option; do
          case $option in
            b) branch=$OPTARG;;
            *) # handle the error;;
          esac
        done;;
  *) # handle the error or other subcommands;;
esac
# At this point, there are still arguments if ((OPTIND > $#))
于 2013-06-10T02:40:13.473 に答える
1

少し簡略化されたバージョンで、それを使用してgetoptsエラーを報告できます。

#!/usr/bin/bash

help() { echo -e "Usage\n\t$0: new <app_name> [-b <develop>]" >&2;}
die() { [ -n "$1" ] && echo -e "Error: $1\n" >&2; help; [ -z "$1" ]; exit;}

[ $# -lt 2 ] && die "Too few args"
[ $1 != "new" ] && die "Bad first arg ($1)"
app_name=$2
shift 2

unset develop
while getopts "b:" opt; do
  case $opt in
    \?) exit 1;;
    b) develop="$OPTARG";;
  esac
done

echo "app_name: $app_name, develop: $develop"

テスト:

$./test new App
app_name: App, develop:
$./test new App -b Dev
app_name: App, develop: Dev

とにかく、引数を渡す標準的な方法を使用することをお勧めします。の代わりにnewを使用できます-n

于 2013-06-11T08:30:33.427 に答える