walkingmask’s development log

IT系の情報などを適当に書いていきます

MENU

caffeinateでコマンド実行中の自動スリープ防止

caffeinateというコマンドを最近知ったので、それを使ってコマンド実行中に自動スリープしないようにzshrcを書き換えました。

caffeinateについて

caffeinateについては、すでに色々な方が解説してくださっているのでググってみたください。

zshrc

今回追記したのはこんな感じです。

add-zsh-hook preexec be_awake
function be_awake() {
    sh -c 'caffeinate -i &'
}
add-zsh-hook precmd be_ease
function be_ease() {
    pkill caffeinate
    # say hi!
    sh -c 'peep &'
}

zshのadd-zsh-hookを使って、コマンド実行直前に呼び出されるpreexecにbe_awakeを、プロンプト表示直前に呼び出されるprecmdにbe_easeを登録してます。be_*はそれぞれcaffeinateをサブシェルでバックグラウンドで実行してkillするだでのものです(peepはシェルがピヨピヨ鳴くだけの自作コマンドで実行完了時に鳴いてもらってます)。

効果

実際問題、コマンド実行中に自動スリープに入るのかというのはわからないのですが、ssh接続中にスリープしててコネクションが切れていてイラというのは多々あったので、これで少しは改善されることを期待しています。

今後の課題

caffeinateを終了させる時に、pkillですべてのcaffeinateを切っているのですが、これだと複数シェルを並行で実行していると「片方は処理中で片方で作業してちょっと離席」というシチュエーションでアボンするので、プロセスIDを保存してなんとかしたいところです。

追記

zshだと

% echo "foo" | read FOO
% echo $FOO
foo

といったようにreadに標準出力をパイプして変数に格納できるようなので、これを利用してPIDを変数に出力することができました。しかし、ターミナルを複数立ち上げた場合に同一名の変数だと問題がありそうな気がしたのでevalとzshのPIDを使って次のように改良しました。

eval CAFFPID"$$"xyz=""
add-zsh-hook preexec be_awake
function be_awake() {
    sh -c 'caffeinate -i & echo $!' | read CAFFPID
    eval CAFFPID"$$"xyz=$CAFFPID
    CAFFPID=""
}
add-zsh-hook precmd be_ease
function be_ease() {
    eval CAFFPID=\$CAFFPID"$$"xyz
    if [ `echo $CAFFPID` ]; then
        kill $CAFFPID
        CAFFPID=""
    fi
    # say hi!
    sh -c 'peep &'
}

ちょっと苦しい部分もありますが、うまく動いてくれているようなので今回はここまでにしたいと思います。