シェルスクリプトは、端末に入力されたキーストロークのレコードではありません。あなたはこのようなスクリプトを記述する場合:
command1
bash
command2
それはスクリプトがbashのに切り替え、その後、別のシェルでcommand2
を実行することを意味するものではありません。つまり、bash
が実行されます。制御端末がある場合、そのbashはプロンプトを表示し、コマンドの入力を待ちます。そのbashを終了するには、exit
と入力する必要があります。その後、元のスクリプトはcommand2
に進みます。
スクリプトを途中で別のシェルに切り替える方法はありません。これをシミュレートする方法があります。スクリプトは、別のシェルを使用して自身を再実行することができます。これを実行するには、スクリプトに再実行されていることを検出するロジックが含まれている必要があります。これにより、再度実行し直すことを防ぎ、2回実行しないコードをスキップできます。
では、このような再実行ハックを実装しました。これは、これらの行で構成されています:
#
# The #!/bin/sh might be some legacy piece of crap,
# not even up to 1990 POSIX.2 spec. So the first step
# is to look for a better shell in some known places
# and re-execute ourselves with that interpreter.
#
if test x$txr_shell = x ; then
for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do
if test -x $shell ; then
txr_shell=$shell
break
fi
done
if test x$txr_shell = x ; then
echo "No known POSIX shell found: falling back on /bin/sh, which may not work"
txr_shell=/bin/sh
fi
export txr_shell
exec $txr_shell $0 ${@+"[email protected]"}
fi
txr_shell
変数(ない変数の標準的な、私の発明)は、このロジックは、それが再実行されていたことを検出する方法です。変数が存在しない場合、これは元の実行です。 export txr_shell
を再実行すると、再実行されたインスタンスはこの環境変数を持ちます。
また、変数はシェルへのパスも保持します。これはスクリプトの後半で使用されます。変数SHELL
としてMakefile
に渡されるため、ビルドレシピは同じシェルを使用します。上記のロジックでは、txr_shell
の内容は関係ありません。これはブール値として使用されます。存在するかどうかです。
上記のコードスニペットのプログラミングスタイルは、非常に古いシェルで動作するように意図的にコード化されています。そのため、最新の構文[ -z "$txr_shell" ]
の代わりにtest x$txr_shell = x
が使用され、理由は"[email protected]"
ではなく、${@+"[email protected]"}
が使用されます。
スクリプトの残りの部分は、再実行トリックのおかげで、合理的で現代的なシェルで実行されるため、スクリプトのこの時点以降は使用されなくなりました。
出典
2016-07-25 16:20:50
Kaz
このスクリプトをどのように実行していますか?それは何を目的としていますか?最初にbashとして実行するのではなく、途中でbashを起動しようとしているのはなぜですか? –
あなたがbashスクリプトの作成方法と実行方法の基礎を持っているかどうかわからない。見てください:http://stackoverflow.com/documentation/bash/300/hello-world#t=201607251613433976444 – Sundeep
http://shellcheck.net/にアクセスしてから、人間にデバッグを依頼してください。 – tripleee