bashで中括弧のグループコマンドをパイプでつなぐとサブシェルで実行されるので一応気をつける
Wed Apr 9 15:52:57 JST 2014 (modified: Sun Dec 22 12:15:39 JST 2019)
views: 4614, keywords:サブシェル,グループコマンド,bash, この記事は最終更新日が4年以上前のものです。
どうも。寝不足太郎上田です。細かい話が嫌いなのですが、調べる必要があり、調べたことを書きます。
{}で囲ったグループコマンドについてはシェルスクリプト本体と同じプロセスで動作するという記述がmanにあります。
ueda@remote:~$ man bash
...
{ list; }
list is simply executed in the current shell environment.
...
私の場合、グループコマンドはパイプに複数のコマンドを渡すときに使います。こんな感じで。
{
echo ファイルのヘッダだよーん
cat file
echo ファイルのフッタだよーん
} |
cat -n
ただ、こういうときはmanのとおりの同じプロセスでは動いていないんじゃないかと。なぜなら、パイプでグループコマンドをつなぐときに、別プロセスにする方がパイプを楽に繋げることができるからです。
ということで実験。bash4からBASHPIDという変数があって、これがサブシェルのプロセスIDを持っているので、こいつをechoしてみます。$$だとサブシェルでもシェルスクリプト本体のプロセスIDを保持し続けるのでこの実験はできません。
パイプでつながない場合
ueda@remote:~$ cat hoge.bash
#!/bin/bash
echo 親: $BASHPID
{
echo 子: $BASHPID
}
ueda@remote:~$ ./hoge.bash
1671
親: 1671 子:
同じプロセスです。
パイプでつなぐ場合
ueda@remote:~$ cat hoge2.bash
#!/bin/bash
echo 親: $BASHPID
{
echo 子: $BASHPID
} | cat
ueda@remote:~$ ./hoge2.bash
1706
親: 1707 子:
サブシェルですね。
ということは、次のように子供で定義した変数は親から見えません。こんな使い方しませんが、一応気をつけておいた方が良さそうです。
ueda@remote:~$ cat hoge2-2.bash
#!/bin/bash
echo 親: $BASHPID
{
A=aaa
echo 子: $BASHPID
} | cat
echo $A
ueda@remote:~$ ./hoge2-2.bash
1836
親: 1837
子: <- aaaと出てこない
丸括弧だと
次のようにデフォルトでサブシェルです。
ueda@remote:~$ cat hoge3.bash
#!/bin/bash
echo 親: $BASHPID
(
echo 子: $BASHPID
)
ueda@remote:~$ ./hoge3.bash
1758
親: 1759 子:
ご相談
これは自明だからmanに書かないんでよいんですかね??in the current shell environmentというのがサブシェル云々の話とは違う話なのかな??どうしよう・・・。
気が小さいのでドキドキするだけで放置・・・。うーん。