2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

サブシェルによる実行(および変数更新)

Last updated at Posted at 2020-03-15

こんにちは。
サブシェルによって実行される場合を簡単にまとめてみました:

  1. コマンドを括弧「( )」で囲った場合1
  2. パイプラインの前後。
  3. シェルコマンドへ文字列・テキストを渡して実行させた場合2

コマンドグループ(サブシェルではなく元シェルで実行)

これに対して、下記の一塊の実行単位は、そのままでは元シェルで実行されます3

  • コマンドグループ(すなわち brace「{ }」で囲う)
  • 関数、
  • while do 〜 done ループ 4

サブシェルによる実行例

パイプラインとコマンドグループとの組み合わせは勘違いしやすかったです。下記例を読み解くと、

command1; command2; { command3; command4; } | { commmand5; command6; }; command7; command8
  1. 元シェルで実行されるのは:
    • command1, command2
    • command7, command8
  2. サブシェルで実行されるのは:
    • command3, command4
    • command5, command6

サブシェル内の変数更新

次にサブシェル内の変数更新を考えると、これは元シェルへは伝播しません。下記例で末尾の echo $n の出力は空となります。

$ unset n; { n=0; printf 'a\nb\n'; } | cat; echo $n
a
b

$ unset n; printf 'a\nb\n' | (n=0; while read -r line; do n=$((n+1)); done; echo $n); echo $n
2

$ unset n; printf 'a\nb\n' | { n=0; while read -r line; do n=$((n+1)); done; echo $n; }; echo $n
2

$ 

「サブシェル内の変数更新」を回避

元シェルでの変数更新であれば、「サブシェル内の変数更新」を回避できます。下記例は混み入っていますが、n=0 は元シェルで実行され末尾の echo $n の出力は 0 となります。

$ unset n; { n=0; printf 'a\nb\n' | cat; } ; echo $n
a
b
0
$

「ヒア・ドキュメント」の利用

同様に元シェルでの変数更新とするために、「ヒア・ドキュメント」を利用する方法もあります(パイプラインを回避できます)。下記例で末尾の echo $n の出力は 2 となります。

$ unset n; { n=0; while read -r line; do n=$((n+1)); done << EOT
 $(printf 'a\nb\n')
EOT
 echo $n; }; echo $n
2
2
$

もしくは、POSIX shell ではなく、Bash などでは Process Substitution を利用できます:

$ unset n; { n=0; while read -r line; do n=$((n+1)); done < <(printf 'a\nb\n'); echo $n; }; echo $n
2
2
$
  1. 括弧「( )」で囲ったサブシェル実行の標準出力を得る $(...) の形式も同様です。しかし $((...)) の形式は元シェルで実行されます(「サブシェル内における変数」)。

  2. シェルスクリプトを実行させたり、sh -c 'n=0; echo $n' のような実行例を指します。これに対して source コマンドを用いて動かすと、元シェルで実行されます。

  3. これは、括弧「( )」で囲った場合と似ていますが、サブシェル扱いとなるわけではありません。

  4. 例えば、printf 'a\nb\n' | while read -r line; do echo $line; done

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?