bash で「exec echo some; echo test」を実行しても、「some test」は印刷されないのですか?

bash で「exec echo some; echo test」を実行しても、「some test」は印刷されないのですか?

exec echo "some "; echo "test"bash で実行すると、「some test」は出力されないのですか?

exec私は小さなシェル スクリプトを書いており、コマンドが呼び出された後は何も続行しないようにしたいので、この質問に対する確認を求めます。

私の理解では、相談した結果、心配する必要はないと思います。

  • man 3 exec
  • man 1p exec

シェルスクリプトは、シェルによって実行されると、

  1. シェルはプログラムを実行しexec
  2. 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存在し、ではなくこの実行可能コマンドが印刷される場合です。というコマンドから期待されるように実行可能コマンドが動作する通常の状況では、これは発生しません。echosome textsomeechoecho

echoPATH に実行可能ファイルがない場合や実行に失敗した場合は、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"

関連情報