bashスクリプトでの“(〜)”と“{〜}”の違い

bashスクリプトを書いています。その中で、あるディレクトリが準備されているかどうかを判別する必要が出てきました。そこで次のように書きました。

TARGET_DIR=/mnt/usb_hdd/work
CHECK_FILE=$TARGET_DIR/.this-is-work

function main()
{
  # dir check
  is_target_prepared || (echo "target dir is not prepared."; exit 1)

  # (中略)
}

function is_target_prepared()
{
  ls $CHECK_FILE >/dev/null 2>&1
}

# (中略)

main

ディレクトリが準備されているかどうかを、“.this-is-work”というファイルがあるかどうかで判別しています。もしファイルが無かった場合、メッセージを出してスクリプトが停止するようにしました。

ところが実行してみると、メッセージを出した後、そのまま継続して次の文が実行されてしまいました。調べてみたところ、bashでは“(〜)”はサブシェルで実行されるため、exitはサブシェルを抜けるだけの効果しかないことがわかりました。同じシェルで動作させるには、次のように“{〜}”を使って書く必要があるようです。

  is_target_mounted || { echo "target dir is not prepared."; exit 1; }

これでディレクトリが準備されていない場合には、スクリプトが停止するようになりました。なお、“{〜}”を使う場合、中に入れるコマンドの末尾にセミコロンが必要になります。