Quantcast
Channel: Bashタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 2722

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

$
0
0

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

  1. コマンドを括弧「()」で囲うとサブシェルによる実行となる1
  2. パイプラインの前後はサブシェルによる実行となる。

サブシェルによる実行例

上記の 2 は勘違いしやすかったです。下記例を読み解くと、

command1; command2;{ command3; command4;} | { commmand5; command6;}; command7; command8

加えてコマンドグループにすると(すなわち brace「{}」で囲うと)一つのシェルで実行されるので、結局のところ下記のように実行されます:

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

サブシェル内の変数更新

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

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

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

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

$

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

元シェルでの変数更新であれば、「サブシェル内の変数更新」を回避できます。下記例で末尾の echo $nの出力は 0となります。

$unset n;{n=0;printf'a\nb\n';};echo$na
b
0
$unset n;{n=0;printf'a\nb\n' | cat;};echo$na
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$n2
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$n2
2
$

  1. こちらは勘違い(=問題化)しにくいと思います。 


Viewing all articles
Browse latest Browse all 2722

Trending Articles