Ansatzの備忘録

勉強したことあるいはふと思い立ったこと

シェルワンライナー160本ノック問題16

問題16 変数のローカル化

次のワンライナー

n="XYZ"; for i in {A..C}; do n+=$i; echo $n;done;echo $n

に対して、for の内部の処理が done の後の echo の処理に影響を与えないようにうまく書き換える問題だった。

別の変数を用意してごまかそうかと思ったがどう考えてもそういう意図の問題ではない。もしかして練習問題で習ったサブシェルを使うのかなと思い、試しに

 n="XYZ"; (for i in {A..C}; do n+=$i; echo $n;done);echo $n

と打ってみたら正解だった。久しぶりに問題を解けた気がする。

サブシェルは別のプログラムなので、その中で変数を変更しても元のシェルには伝わらない。こういう仕組みで変数のスコープが決まっている。と本に書いてあった。

別解も興味深かった。かっこを用いて明示的にサブシェルを作るのではなく、パイプを用いて暗黙の裡にサブシェルを作るやり方もあるそうだ。パイプというのは異なるプロセス間でのデータの受け渡し方法(プロセス間通信)の一つであると本では解説されている。プロセス間通信という言葉をどこかで聞いたことがある気がするが、オブジェクト指向の話で出てきた気がする。オブジェクト指向とはなんなのか、なんだか怪しい説明ばかりで納得できたためしがないが、何かいい解説はないだろうか。話がそれたが、パイプでつながっているプロセスは、パイプが機能するために別々のプロセスとして動く。だから暗黙の裡にサブシェルを作ったのと同じことになる。

linuxunix で動くプログラムを書くときは fork という仕組みで簡単にプロセスを分身させることができる。これに加えて exec という仕組みがあるためなんかいろいろうまくいっているらしい。一度にあれもこれも勉強しようとしても頭に入らないのでいまは深入りしないでおく。