--
    --.--

    スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    このエントリーをはてなブックマークに追加
    2015
    08.12

    zsh - 「コマンド終了時に通知」をさらにカスタマイズ

    Category: Mac   Tags:MaczshHomebrew通知
    お久しぶりです^-^;
    忙しい上にこの暑さ…
    たまらんですね^-^;

    予告していたネタがまとまったので
    とりあえず公開します!



    zshで時間がかかる処理が終了したらGrowlなどでお知らせする方法を
    以前ご紹介しました(前の記事)。

    自分でも使っていて重宝しているんですが、
    使っていくうちに不満点も見えてきたので
    素人ながらいくつか改善してみました。
    一応うまくいってるみたいです^-^

    先にできあがりを出しちゃいます


    zshrcに以下を追記
    # 以下を参考にいろいろ改変
    # http://umezo.hatenablog.jp/entry/20100508/1273332857
    # http://kazuph.hateblo.jp/entry/2013/10/23/005718

    local COMMAND=""
    local COMMAND_TIME=""
    local EXITSTATUS=""

    precmd() {
    EXITSTATUS=$?
    COMMAND="$COMMAND"
    if [ "$COMMAND" != "" ] ; then
    local COMMAND_FIRST=""
    COMMAND_FIRST="$(echo $COMMAND | awk '{print $1}')"
    #OK COMMAND_FIRST="${COMMAND%% *}"
    #NG COMMAND_FIRST=(${(s: :)${1}})
    #NG COMMAND_FIRST=(${(s: :)${COMMAND}})

    case "$COMMAND_FIRST" in
    brewupd )
    if [ $EXITSTATUS -eq 0 ] ; then
    growlnotify --appIcon Terminal --title "Homebrew" --message "COMPLETED";
    else
    growlnotify --appIcon Terminal --title "Homebrew" --message "Some ERROR occurred";
    fi ;;
    man | pico | ssh )
    return ;;
    * )
    local d=`date +%s`
    d=`expr $d - $COMMAND_TIME`
    if [ "$d" -ge "30" ] ; then
    if [ "$EXITSTATUS" -eq 0 ] ; then
    growlnotify --appIcon Terminal --title "$COMMAND" --message "COMPLETED";
    else
    growlnotify --appIcon Terminal --title "ERROR" --message "$COMMAND";
    fi
    fi ;;
    esac
    fi
    COMMAND=""
    COMMAND_TIME="0"
    }

    preexec () {
    COMMAND="${1}"
    COMMAND_TIME=`date +%s`
    EXITSTATUS=""
    }

    文字列のパターンマッチにはcaseを使うといいらしいので、勉強がてら使ってみました。
    ifでもできるんですが、caseの方が少し見やすい^-^

    その他の変更点は以下のとおりです。

    Homebrewのアップデートの結果は処理時間の長さに関わらず通知

    Homebrewのアップデート&チェックコマンドの実行後は
    時間がかからなくても正否をGrowlなどで通知するようにしました。

    brewupdというのは、私が以前の記事で設定した
    「Homebrewのアップデート&チェックコマンド」のエイリアスです。
    これを実行した時用の処理を用意しました(ソースコードの20〜25行目)。

    通知不要のコマンドを除外

    manコマンドとかは明らかに通知のいらないコマンド。
    いちいち通知されないように除外設定してみます(ソースコードの26〜27行目)。
    今回はman, pico, sshを除外指定しています。

    ただ、manコマンドなどはオプションをつけて実行するのが常。
    それらすべてをホワイトリストとして登録しておく訳にもいきません。
    そこで先頭のmanコマンドだけを検出する関数を作ることで対処。

    元のスクリプトでも同様の関数(${${(s: :)COMMAND}[1]})が用意されていたのですが
    スクリプトをいじってるうちにうまく機能しなくなったのと
    私が (s: :)の辺りがよく理解できてないので(自爆)
    以下のような自分に分かる形に変更しました(awkで1番目の文字列を取ってくる)
    $(echo $COMMAND | awk '{print $1}')

    上記に合致しないコマンドは30秒以上かかっていれば通知

    case構文の最後の* )
    if〜else if〜else〜という構文でいうところの
    最後のelse〜に相当します。
    (ここまで引っかからなかった文字列すべてが対象)
    今回のスクリプトでは「30秒以上かかったら通知」としてみました(ソースコードの28〜37行目)。

    エラーの時は別の通知にしたい

    シェル変数の$?にコマンドの終了状況が入っています。
    0なら真(正常終了)、1なら偽(エラー)。
    これを適当な変数に写し取って
    正常終了ならこんな表示、異常終了ならこんな表示、という風に
    条件分岐に使いました。

    preexecは逆に簡素化

    元のスクリプトのpreexecには以下のような処理がありました。
    if [ "`perl -e 'print($ARGV[0]=~/ssh|^vi/)' $COMMAND`" -ne 1 ] ; then
    COMMAND_TIME=`date +%s`
    fi

    これは多分
    「ssh接続でのコマンド?の時はタイマーをセットしない(=precmdで処理しない)」
    というものだと思うんですが、きちんと理解できず^-^;
    argv=argument variable、コマンドライン引数、argv[0]=コマンドライン引数の1つ目
    という所までは分かりましたが、sshをよく知らないので撃沈^-^;
    今のところ私には必要ないので、この部分を削除しました。

    参考

    時間がかかる処理が終了したらGrowlなどでお知らせ
    処理時間が一定以上かかったらGrowlで通知するzshrc - 心魅 - cocoromi -

    同様の処理・terminal-notifierの例(+終了状況が分かるシェル変数の使用例)
    zshでエラーや時間のかかる処理後に通知センターで通知するようにする - 僕のYak Shavingは終わらない

    より高度な記述の例:awkを使っているところなどを参考にさせて頂きました。
    実行時間が長いコマンドが終わったら、zshが勝手にGrowl通知してくる (Mac/Linux/SSH接続先) - Qiita

    シェルスクリプト・caseの使い方
    case 文の使用方法 - UNIX & Linux コマンド・シェルスクリプト リファレンス

    .zshrcのオプション:
    Zsh 入門者のための超速設定ガイド - Qiita

    おまけ:zshで自身のrコマンドと統計処理パッケージRとが名前かぶりしてる件


    zshにはrというコマンドが元々入っています(最後に実行したコマンドを再実行)。
    1文字だし、他のコマンドやパッケージと名前かぶりしてないだろう
    と思いきや、かぶる場合があるんです^ー^;

    Rという統計処理パッケージがあってですね。
    これをインストールしてると
    zshでrを実行すると…
    統計処理パッケージRではなく、zshのrコマンドが実行されてしまいます。

    これを回避するには以下のように
    「zshのrコマンドを無効化」すればOK。

    .zshrcに以下を追記
    disable r

    参考:`r`コマンドと言えば、統計だよねという全ての人のために - zshデフォルトの`r`コマンドをオフにする方法 - Qiita

    スポンサーサイト
    このエントリーをはてなブックマークに追加
    Comment:0  Trackback:0
    back-to-top
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。