2

現在いる場所からソースディレクトリからbinディレクトリに移動するために使用するbashスクリプトがあります(このスクリプトを「テレポート」と呼びます)。基本的には単なる「cd」コマンドなので、現在のシェル(つまり、.. / teleport.sh)で実行する必要があります。'teleport'が'と一致するように.bashrcファイルにエイリアスを設定しました。teleport.sh'。

初めて実行したときは、正常に動作します。しかし、一度実行した後でもう一度実行すると、何も実行されません。ターミナルを閉じてから新しいターミナルを開くと、再び機能しますが、これは初めてです。私の直感では、BASHの内部で私がよく知らないことが起こっているので、ここで教祖を調べて、答えが得られるかどうかを確認したいと思いました。

スクリプトは次のとおりです。

numargs=$#

function printUsage 
{
        echo -e "Usage: $0 [-o | -s] <PROJECT>\n"
        echo -e "\tMagically teleports you into the main source directory of a project.\n"
        echo -e "\t PROJECT: The current project you wish to teleport into."
        echo -e "\t -o: Teleport into the objdir.\n"
        echo -e "\t -s: Teleport into the source dir.\n"
}

if [ $numargs -lt 2 ]
then
        printUsage
fi

function teleportToObj
{
  OBJDIR=${HOME}/Source/${PROJECT}/obj
  cd ${OBJDIR}
}

function teleportToSrc
{
  cd ${HOME}/Source/${PROJECT}/src
}

while getopts "o:s:" opt
do
  case $opt in
    o)
      PROJECT=$OPTARG
      teleportToObj
      ;;
    s)
      PROJECT=$OPTARG
      teleportToSrc
      ;;
   esac
done

私の使い方は次のようなものです。

sjohnson@corellia:~$ cd /usr/local/src
sjohnson@corellia:/usr/local/src$ . ./teleport -s some-proj
sjohnson@corellia:~/Source/some-proj/src$ teleport -o some-proj
sjohnson@corellia:~/Source/some-proj/src$ 
<... START NEW TERMINAL ...>
sjohnson@corellia:~$ . ./teleport -o some-proj
sjohnson@corellia:~/Source/some-proj/obj$
4

2 に答える 2

5

問題はgetopts、ループで呼び出すことができるように、必然的に少しの状態を保持し、その状態をクリアしていないことです。呼び出されるたびに、もう1つの引数が処理され、シェルのOPTIND変数がインクリメントされるため、次に呼び出されたときに処理する引数がわかります。すべての引数が完了すると、呼び出されるたびに1(false)が返され、while終了します。

スクリプトを初めてソースするときは、期待どおりに機能します。2回目(および3回目、4回目...)は、getoptsfalseを返すだけです。

ループを開始する前に、状態をリセットするために1行追加します。

unset OPTIND   # clear state so getopts will start over
while getopts "o:s:" opt
do
    # ...
done

(2回目の試行でスクリプトを呼び出す(ソースではない)ことを示しているため、トランスクリプトにタイプミスがあると思いますが、これは実際の問題ではありません。)

于 2011-07-14T01:59:42.373 に答える
2

問題は、最初に呼び出すときに、現在のシェルでスクリプトを実行してCDを保持するスクリプト( "../teleport")が実行するスクリプトをソーシングしていることです。2回目に呼び出すときは、ソースがないため、サブシェルを作成し、適切なディレクトリにcdしてから、サブシェルを終了して、スクリプトを呼び出した場所に戻ります。

これを機能させる方法は、teleportToSrcおよびteleportToObjのエイリアスまたは関数を現在のシェル(つまり、スクリプトの外部)で作成することです。

于 2011-07-13T22:21:55.607 に答える