コマンドをパイプでつなげると並列で動作する
昨日の記事に関連するメモ
完全に勘違いしていました。
パイプを繋ぐと左からコマンドが順次実行されるとばかり思い込んでいましたが、並列でそれぞれ動作してるんですね..
極端なはなしですが↓を実行すると即座に2が出力されて3秒後に1が出力されて終了する
$ sleep 3 | (read i; echo '1' 1>&2) | echo '2'
標準入力を受け取るコマンドが正しく動いているのは、入力待ち状態になっているから
上の例で言うと read i
がsleep3の出力を待っているので、2 -> 1の順で出力される
よくよく考えたらあたり前のことだった..
パイプはその名の通り、それぞれのプロセスの入出力をつなぎ合わせてるだけだと覚えればよさそう
2017/04/18
退社
tailと締め切りに悩まされた一日だった
ログファイルを監視してslackに通知する
仕事で使った
準備
通知用にincoming webhookの設定をする
↓のURLからURLを発行する
通知用のrubyスクリプト
※4/21追記
いろいろ勘違い等があり、紆余曲折あって↓のように変更した
nanka.hateblo.jp –ここまで
使用したrubyのバージョン
$ ruby -v ruby 2.0.0p648 (2015-12-16 revision 53161) [x86_64-linux]
require 'net/http' require 'uri' require 'json' uri = URI.parse("https://hooks.slack.com/services/*/*/*") text = ARGV[3] if File.pipe?(STDIN) || File.select([STDIN], [], [], 0) != nil then text ||= STDIN.read end exit unless text payload = { text: text, channel: ARGV[0], username: ARGV[1], icon_emoji: ARGV[2] } Net::HTTP.post_form(uri, { payload: payload.to_json })
こんな感じで使える
ruby slack.rb "#room" "name" ":ghost:" "hoge" echo "hoge" | ruby slack.rb "#room" "name" ":emoji:"
tail,grepと組み合わせて特定のログが書き込まれた際にslackに通知
ワンライナーにしてtmux上で動かしている
tail -n 0 -F logfile | grep --line-buffered "hoge" | while read i; do ruby slack.rb "#room" "name" ":emoji:" "$i"; done
tailの挙動がよくわからずに、ここまで作るのに結構時間がかかってしまった
以下はいくつかハマった?ポイント
監視対象が毎日貼り変わるシンボリックリンクだった
当初 tail -f
しか知らなかったので、貼り変わった時どうしようか少し悩んでしまった
-F
オプションにすることで、リネームされたときやシンボリックリンクが貼り変わった時でも自動で追従してくれる(らしい)
grepした結果が通知されない
tail -n 0 -F logfile | grep "hoge" | while read i; do ruby slack.rb "#room" "name" ":emoji:" "$i"; done
としてると全然通知されなかった
grepに --line-buffered
オプションを付けることで問題は解決した
どうやら出力バッファリングという機能が邪魔をしていたらしい
tail -Fの結果をパイプで渡すとruby側で上手に捌けない..?
tail -Fが特殊な挙動をすることが原因だと思いこんでいるが、
tail -F logfile | ruby slack.rb "#room" "name" ":emoji:"
とすると、どこかのタイミングで標準入力がない状態で↓のif文が通ってしまい、STDIN.readでキーボード入力待ちになってしまう場合がある
if File.pipe?(STDIN) || File.select([STDIN], [], [], 0) != nil then text ||= STDIN.read end
そこで while read i
で一度受け取るようにしたら、正しく動くようになった
tail -F logfile | while read i; do ruby slack.rb "#room" "name" ":emoji:" "$i"; done
原因がわからないのが気持ち悪い、いつかtailの実装を読んでみたい
※4/21追記
原因については↓
nanka.hateblo.jp –ここまで
久しぶりに外でお酒を飲みました
土曜日にとある小さい業界の社長さんとご飯を食べる機会があった
その方は、50前で僕と一回りも年齢が離れているにもかかわらず、かなり熱い思いを持っている人だった
その世代になると、目標がなくなってしまってる人も多いイメージだったので衝撃的だった
協力できることはしていきたいな