pywalを使ってシェルログイン時にpcの壁紙をランダムに変更し、壁紙からターミナルのカラースキーマを自動生成する

公開:2020/10/11
更新:2020/10/20
3 min読了の目安(約3100字TECH技術記事

はじめに

まず、pywalを使うとどうなるのかをお見せすると、

こんな感じで、壁紙からターミナルのカラースキーマを自動生成してくれます。
カラーテーマは上書きしているわけではないので、シェルを立ち上げ直すと元に戻ります。

今回は、このpywalの導入方法ではなく、「pywalを導入した状態からシェルのログイン時にランダムに指定しておいたフォルダ内の画像に壁紙を変更し、変更した壁紙からカラースキーマを自動生成、ターミナルに適用する」ところまでのやり方を備忘録的に記すものです。

したがって、walコマンドがターミナルで使えることを前提とするので、そこまでの設定方法は少し前Qiitaでバズった下記の記事をご参考ください(僕自信参考にさせていただきました。ありがとうございます。)

自分の好きなデスクトップ画像を元に、自動で良い感じに合うターミナル/Vim/VSCodeのテーマを1コマンドで作る - Qiita

やり方

まず、walコマンドが使えることを確認します。

$ type wal
wal is /usr/local/bin/wal

この状態で、現在のログインシェルを確認、bashなら~/.bashrc、zshなら~/.zshrcなどシェルのログイン時に読み込まれるスクリプトの頭に下記を追記します。僕の場合はzshを使っているため、~/.zshrcに記載しました。

~/.zshrc(または~/.bashrc)
# pywal settings
    WAL_IMGS=($(ls -d ~/path/to/wallpaper-images/*))
    # WAL_IMGS+=($(ls -d ~/path/to/other-wallpaper-images/*))
    SEC=`date +%S`
    I=$((SEC%$(echo ${#WAL_IMGS[@]})+1))
    wal -i ${WAL_IMGS[$I]}

wallpaper-imagesフォルダにターミナルのカラースキーマを生成したい壁紙の画像を複数配置しておいてください。(複数フォルダを設定したい場合は、other-wallpaper-imagesフォルダにも画像を配置し、コメントアウトしている行のコメントアウトを外してください)

bashでも動くことを確認済みです。以下解説をします。(自分の勉強用も兼ねて書き方にバラエティを持たせているので一貫性がないのはご了承ください。)

解説

WAL_IMGS=($(ls -d ~/path/to/wallpaper-images/*))

lsの-dオプションにて絶対パス付きでフォルダの中身を標準出力にアウトプットしています。

$()()内部のコマンドの実行結果を文字列として受け取る記法です。バッククォートで囲むやり方でも同じです。

WAL_IMGS=(`ls -d ~/path/to/wallpaper-images/*`)

外側の()は内部の文字列をリストとして解釈するものです。したがって、ls -dwallpaper-imagesフォルダ内部の画像がタブ区切りの文字列として展開されているので、それらのリストとしてWAL_IMGS変数に代入しています。

SEC=`date +%S`
I=$((SEC%$(echo ${#WAL_IMGS[@]})+1))

どうやってランダム性を持たせるのかという部分です。今回は、現在の時刻(秒数)を取得し、それを画像の数で割った余りを用いることで実現しています。

${#リスト名[@]}もしくは${#リスト名[*]}でリストの要素数を取得しています。$()は先ほど見た通り、コマンドの結果を文字列として解釈する記法です。ここでバッククォートの記法を用いないのは、そちらは入子にすることができないという仕様があるからです。

$((算術計算式))の記法は、内部の文字列を計算式として解釈、計算結果を文字列として取得するものです。

ちなみに、シェルスクリプトでは基本的に全てが文字列のリテラルとして扱われるので、その文字列をどう解釈するか(数字なのか式なのかなど)は解釈する側の問題らしいです。

記法の説明が終わったので、式の意味について解説します。

まず前提として、どんな数でもある整数nで割った余りの数は0~n-1までのn通りになります。

この性質を使って時間とともに変わる数である現在時刻を画像の数nで割ることにより0~n-1までのランダムな数を取得します。

シェルスクリプトの場合、リストからn番目の要素を取得するには0番目からではなく1番目から指定する必要があるため、上記の0~n-1までの数に+1をして1~nまでの数に変換しています。

wal -i ${WAL_IMGS[$I]}

そして最後に、n番目の画像を取得し、walコマンドに食わせているかたちとなっています。

おわりに

最終的にこうなります。

それでは、良い開発ライフを!!

壁紙引用元

https://www.deviantart.com/kawitt/art/The-Neon-Shallows-823330548
https://www.deviantart.com/wolfsecho/art/Raging-colors-824543549
https://www.deviantart.com/0xconfig/art/Wonderland-in-the-Icebox-810241520
https://www.deviantart.com/0xconfig/art/Internal-Layers-806269916

2020/10/20追記

~/.bash_profile~/.zprofileでtmuxを起動する設定をしている場合、~/.bashrc~/.zshrcの内容が読み取られないため、

~/.zprofile(または~/.bash_profile)
wal -R

と記載してやれば、iterm2などログインシェルを起動したタイミングで前回適用したpywalのキャッシュからテーマを復元してくれる。