exec echo "some "; echo "test"
bash で実行すると、「some test」は出力されないのですか?
exec
私は小さなシェル スクリプトを書いており、コマンドが呼び出された後は何も続行しないようにしたいので、この質問に対する確認を求めます。
私の理解では、相談した結果、心配する必要はないと思います。
man 3 exec
man 1p exec
シェルスクリプトは、シェルによって実行されると、
- シェルはプログラムを実行し
exec
、 exec***
スクリプトを実行していたシェル/bashを置き換えるファミリーシステムコールを使用します。妨害するシェルのさらなるアクション(「置き換えられた」)
前に述べたように、この質問の主な目的は、exec 後にスクリプト内で発生するもの (などecho test
) が実行されないようにするための私の推論を確認することです。
できる限り一般的な回答(POSIX)をいただければ幸いですが、特にGNU/LinuxとGNU/Bashに最も興味があります。
答え1
はい、exec
成功した場合は現在のシェルが置き換えられるので、次のコマンドは実行されません。
しかし、少なくともBashではシェルは、exec
失敗する:
exec [-cl] [-a name] [command [arguments]]
もし指示が指定されると、新しいプロセスを作成せずにシェルを置き換えます。[...]指示何らかの理由で実行できない場合、シェル オプションが有効になっていない限り、非対話型シェルが終了します
execfail
。その場合は失敗を返します。
次のようなものでも、bash -c 'exec /bin/nosuchfile; echo foo'
プログラムファイルが見つからないというエラーメッセージが表示されるだけです。スクリプト内でエラーを処理するには、次のようなものが必要です。
#!/bin/bash
shopt -s execfail
exec /someprogram
echo whoops, it failed
しかし、 からのエラーメッセージはまだ表示されますexec
。 にリダイレクトを設定するとexec
、それは有効のままであるスクリプトがexec
失敗した後も続行する場合。
答え2
組み込みコマンドexec
(コマンド引数¹ 付き) は、シェル プロセスを置き換えます²。シェル プロセス内の後続のコードは実行されません。
exec echo "some "; echo "test"
したがって、が印刷される唯一の方法は、 という実行可能コマンドがPATH 内にsome text
存在し、ではなくこの実行可能コマンドが印刷される場合です。というコマンドから期待されるように実行可能コマンドが動作する通常の状況では、これは発生しません。echo
some text
some
echo
echo
echo
PATH に実行可能ファイルがない場合や実行に失敗した場合は、exec
エラー メッセージを表示してシェルを終了します。その場合でも、echo "test"
は実行されません。
¹コマンド引数なしの場合は異なります。シェル プロセスを置き換えるのではなく、リダイレクトを適用するだけです。²
サブシェルでは、サブシェルのみが影響を受け、親シェルは正常に実行され続けます。 exec
答え3
exec
常にスクリプトを完了しますもしコマンドを実行し、正常に実行します (コマンドの終了コードではなく、コマンドの開始に関係します)。
exec
コマンドなしで非常に便利な方法で実行できます: ファイル記述子を永続的にリダイレクトするには:
exec 3>/path/to/file
コマンドを開始できない場合、シェルの動作は設定によって異なります。bash
デフォルトでは終了します。
代わりに関数を使用するのが最善かもしれません:
safe_exec () {
cmd="$1"
if test -z "$cmd" || ! test -f "$cmd" || ! test -x "$cmd"; then
exit 1
else
exec "$@"
fi
}
safe_exec echo "some "; echo "test"