カテゴリー
【シェルスクリプトツール作成の基本】自作のシェルスクリプトでパイプを使えるようにする
※ 当ページには【広告/PR】を含む場合があります。
2022/08/09

ちょっとしたことですが、
Linuxコマンドにおいて、自作のシェルスクリプトをパイプ処理するといえば、「Xargsコマンド」が定石かもしれませんが、今回はXargsコマンドを使わないで、なおかつ簡単にパイプ処理を取り入れる方法を検討してみます。
自作パイプ処理の仕組み
パイプ処理の基本は、前段のコマンドが実行された結果の標準出力を、それを受け構える後段のコマンドの標準入力として扱うことにあります。
ということで、後段のシェルスクリプトの中で、「直前に実行された処理の標準入力」を、正しく受け取る仕組みが必要になります。
これを可能にするのが、シェルスクリプト中に使われる
この
cat -
以下ように
1.sh
#!/bin/bash
if [ -p /dev/stdin ]; then
echo 'パイプ処理から標準入力!'
cat -
else
echo '普通の標準入力!'
echo "$@"
fi
これでもうパイプできるシェルスクリプトとして機能します。
$ chmod +x 1.sh
$ echo 'タコ' | ./1.sh
パイプ処理から標準入力!
タコ
$ ./1.sh 'タコ'
普通の標準入力!
タコ
シェルスクリプト内の引数として格納する場合には、
#!/bin/bash
if [ -p /dev/stdin ]; then
_args=$(cat -)
else
_args=$@
fi
echo "引数は ${_args} です"
ここで、標準出力がパイプラインIOで待機しているかどうかを判定する部分が、
if [ -p /dev/stdin ] ...fi
前段からのコマンドからの処理が、現在のプロセスから処理された/別プロセスが開いて処理された、どちらの場合にでも適切に後段の標準入力として受け取れるようになります。
自作スクリプトを作って検証
ものは試しで、以下のようなシェルスクリプトでパイプ処理が正しく行われているか、簡単な計算で確認してみましょう。
#!/bin/bash
if [ -p /dev/stdin ]; then
_str=$(cat -)
else
_str=$@
fi
echo "${_str}" | bc -l
なおこのスクリプトでは、お手元の環境でbcコマンドが使えるか確認しましょう。
$ chmod +x 2.sh
#パイプ処理OK
$ echo '1+2' | ./2.sh
3
#通常の処理もOK
$ ./2.sh '3*4'
12
複数の引数がある場合の処理
引数として受け取った標準入力が、配列形式だった想定の場合、以下のようなスクリプトで処理ができると思います。
#!/bin/bash
if [ -p /dev/stdin ]; then
_arr=$(cat -)
else
_arr=$@
fi
sum=0
for i in ${_arr[@]}; do
sum=$((sum + i))
done
echo $sum
これを実行して、単純な配列の和を計算してみましょう。
$ chmod +x 3.sh
#👇通常の引数(配列)
$ ./3.sh 4 7 2 6 -10
9
#👇パイプで与える引数(配列)
$ echo 1 7 3 | ./3.sh
11
なんとも不思議な動作を行うシェルスクリプトに感じますが、色々とスクリプト化の際の効率が上がりそうです。
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー