Linuxでトラックボールのボタン割当をcrontab 自動化した話

スポンサーリンク

はじめに

トラックボールのボタンの割当をxinputコマンドで指定しているのだが、 起動時にトラックボールのidが変わってしまうことで設定が消えてしまう。

そこで起動時に自動でxinputコマンドを実行してしまおうという作戦。 crontabでシェルスクリプトを実行させてしまおうとしたが、 詰まったところが幾つか有ったので記録しておく。

www.shangtian.tokyo

目次

シェルスクリプトの作成

xinput -listコマンドを実行してトラックボールのid を調べてみるとid=14みたいだ。
このidが起動時に変わってしまうことがあるので、このidを取り出してボタンを割り当てる。

ELECOM TrackBall Mouse DEFT Pro TrackBall    id=14

xinput -list

作成したシェルスクリプトは次の通り。 まずxinput -list で吐き出されるデバイス情報から トラックボールの部分だけ取り出すためにgrepにパイプする。 grepでは”elecom trackball mouse deft pro”で検索をかける。

ここまで実行すると以下のようになる。
ほしいのは以下の写真の一番上のidの情報。ここでいうとid=「14」のデータだけほしい。
文字列処理はシェルスクリプトで実行するのがクソめんどくさいのでpythonに逃げることにした。

xinput -list | grep -i "elecom trackball mouse deft pro"

python のコードは以下の通り。
標準入力でgrepの出力までを受け取って、
splitを使ってidだけ取り出す。

tmp = input().split()
id_ = tmp[8].split("=")
print(id_[1])

実行するとこんな感じ。

完成したシェルスクリプトは以下。

#!/bin/bash
id=$(xinput -list | grep -i "elecom trackball mouse deft pro" | python3 /home/xian/Documents/shell/xinput_set_startup/xinput_set_startup.py)
$(xinput set-button-map $id 1 2 3 4 5 6 7 8 9 1 11 12)

crontabのテスト

PC起動時に毎回トラックボールのボタンを有り当てを実行するようにしたい。そこでcrontabを使って、先程作ったシェルスクリプトを実行することにしよう。

www.server-memo.net
まずは時間を指定せず、crontabで実行できるかを検証。絶対パスが間違っていたりすると上手く動かないので、底の部分のバグを確認。

$crontab -e

で編集画面に移行。移行したら、以下のコマンドを記入して保存。ログもとるように出力結果をリダイレクトしとく 。この実行はうまくいった。

* * * * * /home/xian/Documents/shell/xinput_set_startup/xinput_set_startup.sh > /tmp/nulli.log 2>&1

2>&1の意味は標準出力と標準エラー出力の両方をログファイルにかきこむと言う意味らしいぞ。知らなかった。 qiita.com

crontabでPC起動時に実行

crontabで上手く作ったシェルスクリプトを実行できることは確認できたので、次はPC起動時に実行するように設定を変更していく。

rebootで上手くいかない。

先程と同様に編集画面を開く。

$crontab -e

そして実行タイミングについて以下のように指定してやる。

@reboot export DISPLAY=:0.0 && /home/xian/Documents/shell/xinput_set_startup/xinput_set_startup.sh

だがどうにもPC起動後に作ったシェルスクリプトが実行されている気配がない。ログを見てみるとUnable to connect to X serverと出ている。xinputコマンドを使用しているため、X Window Systemが起動していないと当然エラーする。シェルスクリプト実行のタイミングをもう少し遅らせて、X serverの立ち上がりを待つことでこのエラーを回避してみよう。

Unable to connect to X server
Traceback (most recent call last):
  File "/home/xian/Documents/shell/xinput_set_startup/xinput_set_startup.py", line 1, in <module>
    tmp = input().split()
EOFError: EOF when reading a line

ja.wikipedia.org

実行タイミングを起動後60秒後に指定

というわけで、シェルスクリプトの実行タイミングをPC起動後の60秒後に指定してみる。 crontabの編集画面をひらいて、

$crontab -e 

以下のように書き換えてみる

@reboot sleep 60; export DISPLAY=:0.0 && /home/xian/Documents/shell/xinput_set_startup/xinput_set_startup.sh

再起動前のトラックボールの割当は以下。10->1に再起動後に変更されていればOK。

$ xinput get-button-map 14
1 2 3 4 5 6 7 8 9 10 11 12 

再起動して、ちゃんと反映されるかを確かめてみたら、上手く動作することを確認!!

$ xinput get-button-map 14
1 2 3 4 5 6 7 8 9 1 11 12 

<参考文献>

Unable to run a Python program with cron: cannot connect to X server - Stack Overflow

crontabの書き方 | server-memo.net

linux - How to run a shell script at startup - Stack Overflow