【コラム】

漢のzsh

12 一時ファイルはもういらない - プロセス置換

12/24

マニアックを突き進め、プロセス置換

zshにはプロセス置換(Process Substitution)と呼ばれる機能がある。これはファイルを指定すべき場所や、パイプとして処理すべきところを「コマンドやコマンドの組み合わせそのもの」を記述して処理するいう機能だ。コマンドをファイルのように扱えるものといってもよい。

表1.1 プロセス置換の記述方法

記述方法内容
<(コマンドリスト)コマンドの結果をファイルとして扱う
>(コマンドリスト)出力先をコマンドに渡す

コマンドで指定するファイルをファイルではなくコマンドとして直接指定することで、一時ファイルを作成する必要がなくなる。どれだけ使うシーンがあるかと問われると頭を捻ってしまうが、ログ解析や差分チェックなどを使っている人からは「けっこう便利に使っている」という話も聞く。

さあ、今回はこのマニアックな機能を堪能していこう。ちなみに今回の内容はその多くをzshマニュアルの「Process Substitution」の項を参考にしている。コマンド例もこれを参考にしたものだ。より詳しく知りたい読者の方は、そちらも合わせてご覧いただきたい。

例えばこういった場合

CSVファイルを編集する例を考えてみよう。表2.1のようなテーブルデータを用意したとしよう。テキスト状態ではプロンプト2.1のようになっている。

表2.1 CSVファイルの例

氏名年齢性別備考
Zsher0132MaleBoth bash
Zsher0232Male  
Zsher0335Female  
Zsher0432MaleFrom tcsh
Zsher0535MaleFrom bash

プロンプト2.1 テキストファイルの場合

% cat sheet01.csv
"氏名","年齢","性別","備考"
"Zsher01",32,"Male","Both bash"
"Zsher02",32,"Male",
"Zsher03",35,"Female",
"Zsher04",32,"Male","From tcsh"
"Zsher05",35,"Male","From bash"
%

例えばこのファイルから、氏名と年齢の2列だけを取り出したいとする。これにはさまざまな方法があるが、一例としてcut(1)コマンドを使えばプロンプト2.2のようになる。

プロンプト2.2 cut(1)コマンドの使用例

% cut -f 1,2 -d, sheet01.csv
"氏名","年齢"
"Zsher01",32
"Zsher02",32
"Zsher03",35
"Zsher04",32
"Zsher05",35
%

プロセス置換で実現してみよう

わざわざプロセス置換で同じことをする必要はないわけだが、説明を分かりやすくするために、同じことをプロセス置換でやってみる。cut(1)コマンドはプロンプト3.1やプロンプト3.2のようにすれば1列ずつ取り出せる。これらを組み合わせてプロンプト2.2のようにしてみよう。

プロンプト3.1 1列目だけ取り出す

% cut -f 1 -d, sheet01.csv
"氏名"
"Zsher01"
"Zsher02"
"Zsher03"
"Zsher04"
"Zsher05"
%

プロンプト3.2 2列目だけ取り出す

% cut -f 2 -d, sheet01.csv
"年齢"
32
32
35
32
35
%

paste(1)コマンドで出力結果をマージすればプロンプト3.3のようになる。これを見れば、コマンドの出力がそのままファイルを指定した場合のように扱われていることが分かるだろう。

プロンプト3.3 プロセス置換を使った場合

% paste <(cut -f 1 -d, sheet01.csv) <(cut -f 2 -d, sheet01.csv)
"氏名" "年齢"
"Zsher01" 32
"Zsher02" 32
"Zsher03" 35
"Zsher04" 32
"Zsher05" 35
%

プロセス置換は使われるシーンやシステムに用意されている機能などによって、場合によって/dev/fd/?のファイルへの置換、FIFO(名前付きパイプ)、パイプなどの機構に置き換えて実行される。つまりプロンプト3.3の場合、paste(1)コマンドとしてはファイルが指定された場合と処理は何ら変わっていないということだ。試しにdiff(1)コマンドなどで実行してみれば、実際にはどういったファイルが使われているかが分かる。

プロンプト3.4 diff(1)で実行した場合 - プロセス置換の部分がファイルに置き換えられていることが分かる

% diff -u <(cut -f 1 -d, sheet01.csv) <(cut -f 2 -d, sheet01.csv)
--- /tmp/zshiA99oo Thu May 10 19:57:03 2007
+++ /tmp/zshYfMoLl Thu May 10 19:57:03 2007
@@ -1,6 +1,6 @@
-"氏名"
-"Zsher01"
-"Zsher02"
-"Zsher03"
-"Zsher04"
-"Zsher05"
+"年齢"
+32
+32
+35
+32
+35
%

例えばプロセス置換に"; sleep 10"あたりを仕込んで「diff -u <(cut -f 1 -d, sheet01.csv; sleep 10) <(cut -f 2 -d, sheet01.csv)」のように実行し、プロンプト3.5のようにfile(1)コマンドを使えば、プロセス置換がFIFO(名前付きパイプ)に置き換えられていることが分かる。

プロンプト3.5 プロセス置換の部分に"; sleep 10"を仕込んでfile(1)コマンドでチェック

% file /tmp/zsh*
/tmp/zshiA99oo: fifo (named pipe)
/tmp/zshYfMoLl: fifo (named pipe)
%

要するに一時ファイルはzshが適当に用意してくれるわけだ。

もう1つの方も

コマンドの出力をファイルではなく、逆に出力をコマンドに流し込む指定が「>(コマンドリスト)」だ。コマンドの出力を複数のコマンドリストに流し込むことができる。少々分かりにくいかもしれないが、プロンプト3.3のコマンドの出力を2つの処理に渡して処理する例をプロンプト4.1に示す。

プロンプト4.1 出力結果をコマンドへ流し込む

% atoZ() { tr "[a-z]" "[A-Z]" }
% Atoz() { tr "[A-Z]" "[a-z]" }
% paste <(cut -f 1 -d, sheet01.csv) <(cut -f 2 -d, sheet01.csv) \
> >(grep 32 | atoZ) > >(grep 35 | Atoz)
"ZSHER01" 32
"ZSHER02" 32
"ZSHER04" 32
"zsher03" 35
"zsher05" 35
%

「>(コマンドリスト)」についてだが、コマンドにそのまま流し込みたいので「> >(コマンドリスト)」のようにリダイレクトも併用している。これでパイプで流した場合と同じような効果がある。このあたりは理解しにくいかもしれないが、「>(コマンドリスト)」に対してリダイレクト「>(コマンドリスト)」しているので「> >(コマンドリスト)」だ。パイプで同じことをするなら「| tee >(コマンドリスト) > /dev/null」のようにすればよい。

プロセス置換はけっこう便利なことがある

コマンドによっては引数にファイルしか受け取らず、パイプ、要するに標準入力を受け付けないものがある。代わりに出力に標準出力(やパイプ)を指定できずファイルしか指定できないものがある。プロセス置換を使うと、そういったファイルに対しても一時ファイルを作成することなく処理ができるわけだ。パイプが使えないコマンドに対する代替処置ととらえてもよいだろう。

プロセス置換をゴリゴリ活用するときがあるかと言われると、はっきり言って筆者にはほとんどない。しかしながら使っている人の話によると、使えば便利な機能だそうだ。また、都合によりサーバで一時ファイルを作成したくない(または作成できない)場合や、シェルスクリプトにおいて一時ファイルを考えたくない場合などには、便利な機能である。

12/24

インデックス

連載目次
第24回 グッバイ野郎ども! コピペではじめるzshファイナル
第23回 コマンド補完設定 - アーキテクチャタイプ編
第22回 もってけ泥棒! コピペで始めるzsh - リターンズ
第21回 コマンド補完設定 - ファイルシステムタイプ編
第20回 コマンド補完設定 - cal/ncalコマンド編
第19回 コマンド補完設定 - trafshowコマンド編
第18回 コマンド補完設定 - daemonコマンド編(2)
第17回 コマンド補完設定 - daemonコマンド編(1)
第16回 拡張子ごとにコマンドを自動実行 - 「alias -s」
第15回 **で簡単ヒット!!! - 漢達への熱いお願い付き
第14回 zshとscreenで最強のターミナル環境
第13回 タブキーは最強だ - ファイルグロブもサクっと展開
第12回 一時ファイルはもういらない - プロセス置換
第11回 zshはエディタか? - 「zed」でお手軽編集
第10回 もってけ泥棒! コピペで始めるzsh
第9回 世界はモノクロからカラーへ
第8回 これは既にシェルを超えている…… zshの算術演算
第7回 ひと味違うzshのリダイレクト
第6回 漢はだまって先方予測 - あなたはこの機能使いこなせるか
第5回 「あーっ!」というそのときのために - 備えあれば憂いなしの設定集
第4回 コマンド履歴の検索~EmacsとVi、どっちも設定できるぜzsh
第3回 同じことを2度するなんて…… 自分の過去は利用しましょう
第2回 取りあえず、プロンプトを整えておく。カッコつけたいからね
第1回 最強のシェル、それは「zsh」

もっと見る



転職ノウハウ

あなたが本領発揮できる仕事を診断
あなたの仕事適性診断

シゴト性格・弱点が20の質問でサクッと分かる!

「仕事辞めたい……」その理由は?
「仕事辞めたい……」その理由は?

71%の人が仕事を辞めたいと思った経験あり。その理由と対処法は?

3年後の年収どうなる? 年収予報
3年後の年収どうなる? 年収予報

今の年収は適正? 3年後は? あなたの年収をデータに基づき予報します。

激務な職場を辞めたいが、美女が邪魔して辞められない
激務な職場を辞めたいが、美女が邪魔して辞められない

美人上司と可愛い過ぎる後輩に挟まれるエンジニアの悩み

人気記事

一覧

イチオシ記事

新着記事

求人情報