LoginSignup
0
1

More than 5 years have passed since last update.

xmonadのマルチディスプレイ環境で壁紙のローリングをするスクリプトを重複起動せずに自動で動作させる

Last updated at Posted at 2019-02-25

概要

  • 壁紙に色々と用意しているので,背景を自動でスライドショーさせたい
    • そこで,xmonadのstartupHookに所望のshell scriptを指定してループさせることにする
    • ただし,接続されたディスプレイ環境によりnitrogenでマルチディスプレイをぶち抜きにしたいマシンと,なんか分からんけどnitrogenがうまく設定できずfehを使う必要があるマシンがある
  • 私の環境ではログアウト→ログインで多重起動してしまうので,重複起動チェックを入れた
  • 私の環境ではtrapを仕掛けたところで,そもそもスクリプトがkillで停止してくれないので,crontabも併用する必要があった

参考文献

set background

nitrogenとfehの振り分け

    if type nitrogen > /dev/null 2>&1; then
        # procedures for nitrogen
    else
        if type feh > /dev/null 2>&1; then
            # procedures for feh
        fi
    fi

nitrogenとfehそれぞれ一方しか使えない場合があるが,スクリプトを2種類用意するのが面倒なので,コマンドの存在で振り分けることとした.
インストールしたら使うというdebian文化を信じることにする.(ご都合主義)

ランダム画像選択

random_pick() {
    JPGLIST=$(find ${PICDIR} -type f)
    NUM_JPG=$(echo "$JPGLIST" | wc -l)
    RAND=$(expr $(date +%s) % ${NUM_JPG} + 1)
    SRC=$(echo "$JPGLIST" | head -${RAND} | tail -1)

    cp -f ${SRC} $1
}

random_pick $TARGETFILE

nitrogenの背景ランダム化に--restoreを用いているため,固定パスの画像をランダムに選択した画像で強制上書きすることにした.
それに合わせfehも同じ方式に統一しランダマイズは一つの実装で行なうこととした.
固定パスを各々のソフト用のディレクトリ内としたため,random_pick関数の引数のパスにランダムに選定された画像を上書きコピーするように実装した.

set-background.sh

#!/bin/sh

# if you wanna set a single background over multiple display, you should choose nitrogen.

PICDIR=~/Pictures/wallpapers

interval=900

_lockfile=/tmp/$(basename $0.lock)

random_pick() {
    JPGLIST=$(find ${PICDIR} -type f)
    NUM_JPG=$(echo "$JPGLIST" | wc -l)
    RAND=$(expr $(date +%s) % ${NUM_JPG} + 1)
    SRC=$(echo "$JPGLIST" | head -${RAND} | tail -1)

    cp -f ${SRC} $1
}

ln -s /dummy $_lockfile 2> /dev/null || { echo 'Cannot run multiple instance.' >&2; exit 9; }

trap "rm $_lockfile; exit" 1 2 3 15

# following sentences don't work if `sh -c $0' exists.
#if [ $$ = $(pgrep -fo $0) ]; then
    if type nitrogen > /dev/null 2>&1; then
        EXEC=nitrogen
        TARGETFILE=$HOME/.config/nitrogen/bg.jpg
        if [ ! -e ~/.config/nitrogen/bg-saved.cfg ]; then
            echo First of all you have to setup ~/.config/nitrogen/bg-saved.cfg
            echo Next, change 'file' value into \$TARGETFILE.
        else
            while true
            do
                random_pick $TARGETFILE
                $EXEC --restore
                sleep $interval
            done
        fi
    else
        if type feh > /dev/null 2>&1; then
            EXEC=feh
            TARGETFILE=$HOME/.config/feh/bg.jpg
            mkdir -p $HOME/.config/feh
            while true
            do
                random_pick $TARGETFILE
                $feh --bg-fill -z $TARGETFILE
                sleep $interval
            done
        fi
    fi
#fi

rm $_lockfile

xmonad.hs

main = do
  -- (中略)
  xmonad $ ewmh defaultConfig
    { -- (中略)
    , startupHook           = myStartupHook
    }


myStartupHook = do
    --spawn "feh --bg-fill -z ~/Pictures/wallpapers/*"
    spawn "/home/USER/bin/set-background.sh"

kill processes

set background側で慣れないtrapなんか使っちゃったりして.
でもってxmonadを落とす時,Mod3+Shift+Qで落とすわけで,その際にSIGQUITあたりが飛んでいるんだと思うんだが,
どうやら私の書いたスクリプトは落ちてくれないことが分かった.

具体的には,

  • メインのプロセスはSIGKILLでないと落とせなかった
  • xmonadのstartupHookで起動した場合,/bin/sh -cからの呼び出しと処理するプロセスの2プロセスが実行されるため,両方落とす必要がある

以上のことから,以下の実装とcrontabの設定を行なった.
現象さえ分かれば,実装には特筆することがないので,最終的なスクリプトと設定だけ記載する.

kill-set-background.sh

#!/bin/sh

# to kill set-background.sh set this script in crontab

rm /tmp/set-background.sh.lock
pgrep -f set-background.sh | xargs kill -KILL

crontab

crontab -l

#(略)
# m h dom mon dow  command
0 0 * * * /home/USER/bin/kill-set-background.sh
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1