Bashシェルスクリプト上での `read` コマンドの便利な使い方いろいろ
Bashシェルスクリプトで標準入力からの情報を取り扱う read
コマンドと declare
コマンドを組み合わせると便利 で read
コマンドについて触れたついでに、 read
コマンドの便利な使い方にも触れておきます。
検証環境
$ bash -version
GNU bash, バージョン 5.0.2(1)-release (x86_64-apple-darwin18.2.0)
Copyright (C) 2019 Free Software Foundation, Inc.
ライセンス GPLv3+: GNU GPL バージョン 3 またはそれ以降 <http://gnu.org/licenses/gpl.html>
変数をバラす
read
コマンドは 区切り文字を元に標準入力からのデータをばらして変数に投入してくれる という機能があるので、それを上手に使うと変数をバラすのが楽になります。
例)年、月、日を別の変数に代入する
date
コマンドを3回実行すれば取得できます。
# 年、月、日を取得
$ Y="$(date +%Y)"
$ M="$(date +%m)"
$ D="$(date +%d)"
# 確認してみる
$ echo "$Y と $M と $D"
2019 と 02 と 07
date
コマンドの実行結果を read
コマンドに 食わせることで同じことができます。
# dateの実行結果を標準入力として渡す
$ read Y M D < <(date +'%Y %m %d')
# 確認してみる
$ echo "$Y と $M と $D"
2019 と 02 と 07
ちなみに以下のコマンドではうまくいきません。
# dateの実行結果を標準入力として渡す
$ date +'%Y %m %d' | read Y M D
# 正しく表示されない!
$ echo "$Y と $M と $D"
と と
パイプで繋いだコマンドは、現在実行中のBashプロセスの子プロセスとなります。
上記例では Y
/ M
/ D
のそれぞれの変数は、子プロセス終了とともに破棄されてしまうので、後続処理では参照できません。
ログにタイムスタンプを表示
Linuxサーバ上でログ監視やリソース監視をすることがあります。
tail -f
を使って監視を行う場合に、タイムスタンプが出力されていない場合があります。
(データが正しく連携されてきたかな?みたいなのを眺めてるときに、データそのものに書き込み時間のような情報がない場合もあります。)
以下のようにすれば、 tail -f
で逐次流れてきたデータに対して、タイムスタンプを付与できます。
(本当は書き込みタイミングとの時間のずれがあるが、ズレが許容できるなら便利な方法)
# テストデータのために、1秒ごとにランダムな数値を出力するファイルを作成
$ while true; do
echo $RANDOM;
sleep 1;
done > test.log &
# この状態だと、いつ書き込まれたかわからない
$ tail -f test.log
17434
15657
21714
10082
12302
30370
5088
# タイムスタンプが表示されている。($REPLYとは?後述)
$ tail -f test.log | while read; do
echo "[$(date)] $REPLY";
done
[木 2 7 04:52:12 JST 2019] 28710
[木 2 7 04:52:13 JST 2019] 31432
[木 2 7 04:52:14 JST 2019] 3341
[木 2 7 04:52:15 JST 2019] 475
[木 2 7 04:52:16 JST 2019] 27598
[木 2 7 04:52:17 JST 2019] 22992
[木 2 7 04:52:18 JST 2019] 31265
[木 2 7 04:52:19 JST 2019] 15051
[木 2 7 04:52:20 JST 2019] 27332
[木 2 7 04:52:21 JST 2019] 7600
[木 2 7 04:52:22 JST 2019] 14547
[木 2 7 04:52:23 JST 2019] 16859
[木 2 7 04:52:24 JST 2019] 14108
[木 2 7 04:52:25 JST 2019] 13379
[木 2 7 04:52:26 JST 2019] 10708
[木 2 7 04:52:27 JST 2019] 20908
[木 2 7 04:52:28 JST 2019] 10264
[木 2 7 04:52:29 JST 2019] 28112
[木 2 7 04:52:30 JST 2019] 8908
いきなり出てきた変数 REAPLY
について。read
コマンドが引数無しで呼び出された場合、変数 REPLY
に値が代入されます。
メッセージを表示し、ユーザの入力を促す
インタラクティブなスクリプトを書くときに、 read -p
コマンドでメッセージを表示し入力を促すことができます。
$ read -p '合言葉をどうぞ! > '
合言葉をどうぞ! > hello
$ echo "$REPLY"
hello
入力された合言葉が見えるのはさすがに、という場合もあります。read -s -p
コマンドで入力された内容が表示されないようにできます。
$ read -s -p '合言葉をどうぞ! > '; echo
合言葉をどうぞ! >
$ echo "$REPLY"
hello
echo
コマンドを追加しているのは、入力情報がエコーされないので、入力最後の改行が表示されず、プロンプトがおかしな場所に表示されるのを回避するため。
ディスカッション
コメント一覧
まだ、コメントがありません