パイプ専用スクリプト


0. Contents

1.Concept
2.Run Test
3.Summary


1. Concept

他のコマンドの出力をパイプで受けて処理を行うことを
前提としたスクリプトを作成する事もあると思う。

ここでは単独で起動された場合の対策も含めて
自分が作った際に工夫した点をメモしておく。


2. Run Test

まずは出力をどう受け取るかだが、たいていのコマンドは
引数が無ければ標準入力から読み込んで処理をするので
通常通りスクリプトを書けば OK。

また、引数に '-' を指定すると標準入力から読み込むコマンドが
数多く存在するのでこれを使うと標準入力を直接変数に格納できる。

script1.sh
#! /usr/bin/env bash

a=$( cat - )
echo "$a" | tr '[a-z]' '[A-Z]'
exit

$ echo -e 'aBc\nDeF' | ./script1.sh
ABC
DEF

一行ずつ処理を行うスクリプトなら read を使う方法もある。
以下の例では -t オプションを使用して入力待ち時間を
一秒に設定し、単独で起動された場合にも一応対処してある。

script2.sh
#! /usr/bin/env bash

while read -t 1 ; do
  echo "$REPLY" | tr '[a-z]' '[A-Z]'
done
exit

test ( [ ) コマンドの -t オプションを使うと標準入力の有無を
判別する事ができる。

script3.sh
#! /usr/bin/env bash

if [ -t 0 ] ; then
  echo 'error: Not pipeline.' 1>&2

else
  tr '[a-z]' '[A-Z]'
fi

exit

$ echo -e 'aBc\nDeF' | ./script3.sh
ABC
DEF

$ ./script3.sh
error: Not pipeline.


3. Summary

標準入力は通常コマンドの引数 '-' や read で
柔軟に処理する事ができ、test -t を使えば
標準入力の有無によって処理を分ける事も可能になる。