0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

シェル芸Advent Calendar 2023

Day 20

パイプを分岐する [ワンライナー]

Last updated at Posted at 2023-12-20

パイプを分岐する

シェルのパイプ構文(|)による入出力ストリームはプロセスを直列で接続します。プロセスAの出力を分岐/複製して、プロセスBとプロセスCに並列接続で同じデータを渡すことは、パイプ構文だけを用いてシンプルに実現することはできません。

古くから、シェルで一つの出力を複数プロセスへ分岐させる手段として、FIFO (名前付きパイプ) とteeコマンドを組み合わせる方法が知られています。W. Richard Stevensの「Advanced Programming in the UNIX® Environment」でも、具体的なコード付きで紹介されています。

mkfifo fifo1
prog3 < fifo1 &
prog1 < infile | tee fifo1 | prog2

# 出典: W. Richard Stevens, Stephen A. Rago. Advanced Programming in the UNIX® Environment, Third Edition

ですが、正直に言って面倒ですよね。スクリプトファイルならともかくコマンドラインでこれをやろうとは思えません。FIFOの削除も意識しなければなりません。

ワンライナーでやる

プロセス置換 (Process Substitution) に対応したシェル限定ですが、プロセス置換を活用することで上記のコードをワンライナーで書くことできます。FIFOの削除も気にする必要がありません (Bash on GNU/Linux環境では/dev/fd/n (実体はパイプ) を通じて入出力が行われます)。

prog1 < infile | tee >(prog3) | prog2

<(list)と比べて、>(list)のプロセス置換は利用頻度が圧倒的に少ないと思いますが、こういうときに利用できます。パイプを分岐したいユースケース自体もあまり多くありませんが、例えばネットワーク経由で大きなデータを取得して異なるパターンの集計や加工を行いたいとき等に、データ取得を1回で済ませて一時ファイルも作らずワンライナーできれいに片付けることができるので、シェル芸人にはきっと役立つでしょう。

プロセス置換の具体的なユースケースは、TLDPのAdvanced Bash-Scripting Guide等でもたくさん紹介されているので参考にしてみてください。

参考文献

0
2
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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?