Ubuntu 14.04 で LCD の明るさをコマンドラインから変えたい

# 目的
Ubuntu 14.04 (gnome edition) を Thinkpad X1 Carbon で使っているのだけど，たまにキーボードから LCD の明るさを変えるためのショートカットキーがうまく起動してくれないことがあります．特にスリープから復帰したあとなどにこの現象に遭遇しています．再起動すれば問題は解決するのですが，毎回再起動するわけにはいきません．ショートカットキーが完全に効かなくなってしまった場合には， GUI からの輝度変更も効かなくなってしまうようです．とりいそぎ解決策としてコマンドラインから LCD の輝度を変更する方法を調べました．

# 解決策
とりあえずわかりやすそうなものは 3 つほど見つけました．他にも `xgamma` による設定や `dbus` を直接叩く方法，ppa から `indicator-brigtness` をインストールする方法などがありました．他の方法についてはエントリ末尾の参考資料をあたってください．

## `xbacklight` を使う方法
`xbacklight` は LCD の明るさをコマンドラインから変更するためのプログラムのようです．

~~~{.sh}
sudo apt-get install xbacklight
~~~
以下のようにして使います．

~~~{.sh}
xbacklight -set 50 # brightness を 50 に設定
xbacklight -inc 10 # brightness を 10% あげる
xbacklight -dec 10 # brightness を 10% さげる
~~~

ただし，キーボードショートカットが効かなくなったときに `xbacklight` が有効に機能するかどうかまではきちんと調べていません．次回，同じ問題に遭遇したときに試してみたいと思います．

## `xrandr` を使う方法
`xrandr` はスクリーンへの出力をコントロールするコマンドです．

~~~{.sh}
xrandr -q | grep " connected"
~~~
このように入力することで現在出力しているディスプレイの名前を調べることができます．例えば __"LVDS1"__ という名前のディスプレイに出力していたとすると，

~~~{.sh}
xrandr --output LVDS1 --brightness 0.5
~~~
このように入力することで輝度を `0.0` から `1.0` の範囲で調節することができます．ただし入力として `0.0` を与えると完全にまっくらになってしまいます．

`xrandr` は間違いなくインストールされているので，まずはこの方法を試したのですが，結果的にあまりうまくはいきませんでした．ショートカットキーによる輝度の操作と `xrandr` による輝度の操作は別のレイヤー（ハードウェアとソフトウェア？）によるもののようで，`xrandr` で輝度を `1.0` にしてもハードウェア的に設定されている輝度の最大値を超えることはできないようです．`xrandr` で設定される輝度はデフォルトで `1.0` のようなので，キーボードショートカットが効かなくなったときに輝度を調整するような役割を果たすことは難しそうです．

## `/sys/class/(...)/brightness` を使う方法
こちらはよりプリミティブに設定ファイルを書き換えるというものです．

~~~{.sh}
echo 400 > /sys/class/backlight/intel_backlight/brightness
~~~
このようにして使います．当然 root 権限が必要です．

設定できる最大値は同じディレクトリ内にある `max_brightness` というファイルに記載されているようです．怖いのでこの値を超えた入力はしたことがありません．

この方法はハードウェアに設定されている輝度を直接操作するので，まさにキーボードショートカットが効かなくなったときの代替手段として使えそうです．しかし，毎回 root に化けるのも面倒ですし `max_brightness` の値を覚えておくのも億劫なので以下のようなシェルスクリプトを作成してみました．

```bash:brightness.sh
##
# @brief Change LCD brightness
#
#        Change the brightness of the current LCD via command line.
#        You should be a root to run this script.
#
# @usage
#   ./brightness value
# 
# @param value 
#    A relative brightness. The max brightness is when value = 100.
#    If value > 100, it is regarded as value = 100. The minimum
#    brightness is set when value = 0. But this means a LCD blackout.
#    Thus, value smaller than 20 is ignored and set value = 20.
#    Non-numeric input is regarded as value = 20. 

##
usage () {
  echo "usage:" >&2
  echo "   brightness value" >&2
  echo "   value is an integer number between 20 and 100." >&2
  exit 1;
}

## No argument, then show usage and exit. 
[ -z "${@}" ] && usage

## Parse the first argument. Non-numeric input is zero.
VALUE=$(echo ${1:?} | awk '{print $1*1}')
[ ${VALUE} -gt 100 ] && VALUE=100
[ ${VALUE} -lt  20 ] && VALUE=20

PREFIX="/sys/class/backlight/intel_backlight"

MAX_V=$(cat ${PREFIX}/max_brightness)
VALUE=$(echo "${MAX_V} * ${VALUE} / 100" | bc)

echo ${VALUE} | sudo tee ${PREFIX}/brightness >/dev/null
```
使い方は至って簡単で以下のように使います．

~~~{.sh}
brightness.sh 100 # 輝度を最大に設定
brightness.sh   0 # 輝度を最小に設定
~~~
ただし輝度 `0` はディスプレイが完全に真っ黒になるので輝度 `20` 以下にはならないようにセーフティをつけています．

とりいそぎ，簡単な 3 つの方法について紹介しました．もっとシンプルな方法を知っている方がいらっしゃいましたら，情報提供していただけると嬉しいです．


# 参考資料
- [How to change LCD brightness from command line (or via script)?](http://askubuntu.com/questions/149054/how-to-change-lcd-brightness-from-command-line-or-via-script)
- [What commands will change my screen's brightness?](http://askubuntu.com/questions/240857/what-commands-will-change-my-screens-brightness)