3

から呼び出す次のスクリプトがあります.bash_profile

# Set directories based on current path
__set_dirs() {
    currdir=`pwd`
    if [[ ${currdir} =~ "\/path\/to\/main\/(.*)\/working\/([a-z]+)(/?.*)" ]]
    then
        ws=${BASH_REMATCH[1]}
        subdirs=${BASH_REMATCH[3]}
        stgdir=${ts}/${ws}/STAGING${subdirs}
    else
        echo "${currdir} is not a workspace"
        stgdir=""
    fi
}

# Update local version with staging version
upd() {
    __set_dirs
    if [[ -n ${stgdir} ]]
    then
        __overwrite=0
        while getopts "o" opt
        do
            case $opt in
                o)
                    __overwrite=1
                    ;;
                \?)
                    echo "Invalid option: -$OPTARG" >&2
                    ;;
            esac
        done

        echo "Updating ${currdir} with latest from ${stgdir}..."
        if [ ${__overwrite} -eq 0 ]
        then
            update -r ${stgdir} ${currdir}
        else
            echo "Overwriting all local changes!"
            update -r -w ${stgdir} ${currdir}
        fi
    fi
    unset __overwrite
}

私が実行するとき

> upd -o

フラグは完全に無視されます。「すべてのローカル変更を上書きしています!」というメッセージは表示されません。私はどこかで何かを逃しましたか?

更新:機能しますが、スクリプトを初めて実行するときだけです。2 回目以降、フラグは無視されます。

4

2 に答える 2

4

わかりました。

マニュアルページをgetoptsざっと調べたところ、次の情報が見つかりました (強調は私のものです)。

呼び出されるたびに、getopts は、処理される次の引数のインデックスを変数 OPTIND に配置します。OPTIND は、シェルまたはシェル スクリプトが呼び出されるたびに 1 に初期化されます。シェルは OPTIND を自動的にリセットしません。新しいパラメータ セットを使用する場合は、同じシェル呼び出し内で getopts を複数回呼び出す間に手動でリセットする必要があります。

スクリプトは .bashrc から 1 回だけ実行するため、OPTIND初期化されるのは 1 回だけです。関数を初めて実行すると、すべてがうまくいきません。2 回目OPTINDは 2 に設定され、getoptsそこには何も見つからないため、先に進みます。

この知識を武器に、 1upd()にリセットOPTINDするように変更しました。

upd() {
    __set_dirs
    if [[ -n ${stgdir} ]]
    then
         __overwrite=0
         OPTIND=1
         while getopts "o" opt
...

それはそれを修正しました。OPTIND:あなたが思っているよりも重要です。

于 2013-09-09T21:18:32.250 に答える