bashで「exec echo some; echo test」を実行すると、「some test」は印刷されませんか?

bashで「exec echo some; echo test」を実行すると、「some test」は印刷されませんか?

Bashで実行すると、exec echo "some "; echo "test"「一部のテスト」は印刷されませんか?

exec私は小さなシェルスクリプトを書いていますが、コマンドを呼び出した後は何も続かないようにしたいので、この問題の確認を探しています。

私が理解したところによると、心配する必要はないと思います。

  • man 3 exec
  • man 1p exec

シェルスクリプトは、シェルによって実行されると次のようになります。

  1. シェルはプログラムを実行しますがexec
  2. exec***次のように、一連のシステム呼び出しを使用してスクリプトを実行するシェル/バスを置き換えます。邪魔するシェルの追加作業(「交換中」)

前述のように、この質問の主な目的は、echo testexecを実行した後にスクリプトで発生するすべてのことを防ぐために私の推論をチェックすることです。

できるだけ一般的な答え(POSIX)を取得したいと思います。しかし、私は知らないので、GNU / LinuxとGNU / Bashに最も興味があります。

答え1

しかしexec、成功すると現在のシェルを置き換えるので、次のコマンドは実行されません。 err..

しかし、少なくとも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関数(コマンド引数1を含む)はシェルプロセス2を置き換えます。シェルプロセスの後続のコードは実行されません。

exec echo "some "; echo "test"したがって、印刷する唯一の方法は、実行可能なコマンドがPATHから呼び出され、some text実行可能ファイルが代わりに印刷される場合です。一般的な状況では、実行可能ファイルはこの方法で名前付きコマンドで期待どおりに機能します。echosome textsomeechoecho

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"

関連情報