インフラエンジニアbacchiのわかったことまとめ

bacchi.me

シェルのグルーピングについて、( )と{ } の違いを調べた

グルーピングで使う、{ }( )の違いがあやふやだったので調べてみました。

グルーピングを使うとコマンドを単独で実行するのではなく、
複数のコマンドを1つのコマンドとみなして実行することができます。

グルーピングには以下の利点があります。

  • グループ内でのみ環境の変更が有効になる
  • 複数のコマンドの実行結果をまとめる事ができる

大きな違いはコマンドをサブシェルで実行するか、カレントシェルで実行するかです。

{ }を使って実行した場合、{ }内で変更した環境変数などを以後もカレントシェルで実行できます。

( )を使って実行すると( )内で環境を変更してもカレントシェルに影響を与えません。

( )の場合は(の直後にスペースの有無は問いませんが、{ }の場合は{の直後にスペースが必要です。

## (  ) でグルーピングした場合
[root@bacchi ~]# pwd
/root
[root@bacchi ~]# (cd /usr/local/apache2/logs ; tail -n 10 access_log)
127.0.0.1 - - [24/Feb/2015:23:33:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:37:58 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:04:00 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:08:29 +0900] "x16x03x01" 501 205 "-" "-" 36 205
127.0.0.1 - - [25/Feb/2015:00:09:42 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:11:01 +0900] "x16x03x01" 501 205 "-" "-" 41 205
127.0.0.1 - - [25/Feb/2015:00:12:09 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:13:42 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:14:44 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:15:45 +0900] "x16x03x01" 501 205 "-" "-" 64 205
[root@bacchi ~]# pwd
/root     # ディレクトリはコマンド実行前から変わっていない!

## {  } でグルーピングした場合
[root@bacchi ~]# pwd
/root
[root@bacchi ~]# { cd /usr/local/apache2/logs; tail -n 10 access_log ;}
127.0.0.1 - - [24/Feb/2015:23:33:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:37:58 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:04:00 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:08:29 +0900] "x16x03x01" 501 205 "-" "-" 36 205
127.0.0.1 - - [25/Feb/2015:00:09:42 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:11:01 +0900] "x16x03x01" 501 205 "-" "-" 41 205
127.0.0.1 - - [25/Feb/2015:00:12:09 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:13:42 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:14:44 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [25/Feb/2015:00:15:45 +0900] "x16x03x01" 501 205 "-" "-" 64 205
[root@bacchi logs]# pwd
/usr/local/apache2/logs  # ディレクトリが cd した先のディレクトリになっている!

また、{ }の場合は{ command_A ;}のように、;}としないと処理から抜けられません。

### }の前に;を付与しない場合
# { cd /usr/local/apache2/logs ; tail -n 10 access_log }
>
> ^C          ## Enterの入力待ち状態

## }の前に;を付与した場合
[root@bacchi logs]# { cd /usr/local/apache2/logs ; tail -n 10 access_log ;}
127.0.0.1 - - [24/Feb/2015:22:45:38 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:22:57:20 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:01:33 +0900] "x16x03x01" 501 205 "-" "-" 43 205
127.0.0.1 - - [24/Feb/2015:23:03:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:10:12 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:12:31 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:17:32 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:22:30 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:33:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:37:58 +0900] "x16x03x01" 501 205 "-" "-" 64 205
# コマンドの結果が返ってきた!

{ };はEnter(改行)を意味するので、{ }内で改行があればコマンドは通ります。

[root@bacchi logs]# cd
[root@bacchi ~]# {
> cd /usr/local/apache2/logs
> tail -n 10 access_log
> }
127.0.0.1 - - [24/Feb/2015:22:45:38 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:22:57:20 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:01:33 +0900] "x16x03x01" 501 205 "-" "-" 43 205
127.0.0.1 - - [24/Feb/2015:23:03:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:10:12 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:12:31 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:17:32 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:22:30 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:33:56 +0900] "x16x03x01" 501 205 "-" "-" 64 205
127.0.0.1 - - [24/Feb/2015:23:37:58 +0900] "x16x03x01" 501 205 "-" "-" 64 205

シェルスクリプトにおいて、コマンドをグルーピングするのはコマンドリストとして
複数のコマンドの実行結果をまとめてごにょごにょしたい、という場合がほとんどだと思います。

しかし、これらを使い分けることが必要となるシーンがあまりないと思います。

ですので、私は分かりやすさの点で( )を使うほうがベターかなと思いました。

  • B!