(exit 1) このスクリプトを終了しないのはなぜですか?

(exit 1) このスクリプトを終了しないのはなぜですか?

私が望むときに終了しないスクリプトがあります。

同じエラーを持つサンプルスクリプトは次のとおりです。

#!/bin/bash

function bla() {
    return 1
}

bla || ( echo '1' ; exit 1 )

echo '2'

私は出力を見ると仮定します:

:~$ ./test.sh
1
:~$

しかし、実際には次のようになります。

:~$ ./test.sh
1
2
:~$

コマンド接続は()どのようにスコープを生成しますか?exitスクリプトでない場合は何を終了しますか?

ベストアンサー1

()サブシェルでコマンドを実行するので、サブシェルをexit終了して親シェルに戻ることができます。{}現在のシェルでコマンドを実行するには、中かっこを使用します。

Bashのマニュアルから:

(リスト)リストはサブシェル環境で実行されます。シェル環境に影響を与える変数割り当ておよび組み込みコマンドは、コマンドの完了後に無効になります。戻り状態はリストの終了状態です。

{リスト; }listは現在のシェル環境でのみ実行されます。リストは改行またはセミコロンで終わる必要があります。これをグループコマンドと呼びます。戻り状態はリストの終了状態です。メタ文字(および)とは異なり、{と}は予約語であるため、予約語を認識できる場所に表示する必要があります。単語の分離を引き起こさないので、スペースやその他のシェルメタ文字でリストと区別する必要があります。

シェル構文は非常に一貫しており、サブシェルは()コマンド置換(以前のスタイル`..`構文を使用)やプロセス置換などの他の構成にも参加しているため、以下は現在シェルで終了しません。

echo $(exit)
cat <(exit)

コマンドが明示的に内部に配置されたときにサブシェルが関連付けられることは明らかですが()、サブシェルがこれらの他の構造内でも生成されるという事実はあまり明らかではありません。

  • コマンドはバックグラウンドで開始されます。

    exit &
    

    man bash(以降)ので、現在のシェルを終了しないでください。

    コマンドが制御演算子&によって終了すると、シェルはサブシェルのバックグラウンドでコマンドを実行します。シェルは、コマンドが完了するのを待たずに状態0を返します。

  • 管路

    exit | echo foo
    

    それでもサブシェルでのみ終了します。

    しかし、これに関して、他のシェルは異なる動作をします。たとえば、AT&T はbashパイプラインのすべてのコンポーネントを別々のサブシェルに入れます (タスク制御が有効になっていない呼び出しlastpipeでこのオプションを使用しない限り)、AT&T は現在のシェルで最後の部分をksh実行しますzsh(POSIX では 2 つすべての動作を許可します)。だから

    exit | exit | exit
    

    デフォルトでは、bashでは何もしませんが、次のようにzshを終了します。ついに exit

  • coproc exitexitサブシェルでも実行されます。

おすすめ記事