フューチャー技術ブログ

シェルスクリプトでもGUI

シェルスクリプト連載の5日目です。

僕が大学に入ったときに買ったPCは、Celeron 300AMHzというやつで、300MHzのパッケージ違いの2モデル目みたいな今見ると変なモデル名のやつでした。ちょっといじると450MHzで動くいいやつでした。BeOS 4.0が付属しているショップブランドの自作PCでした。

BeOSはPOSIX対応のOSではあるものの、カーネルからGUIから大部分がオリジナルで楽しいOSでした。いくつか独自コマンドがインストールされていて、その中にダイアログを出すコマンドがありました。BeOSの魂の後継としてOSSで開発されているhaikuでもそのあたりのコマンドがあります。次のスクリーンショットはhaikuをQEMUで動かして撮ってみたものです。

提供されているのは情報の通知(notify, プログレスバーを作れたり、クリック時のintentも設定可能)、最大3択までのボタンが押せるメッセージパネル(alert)、ファイルのダイアログ(filepanel)です。ボタン選択やファイルのダイアログの場合はエラーコードで選択されたボタンが、標準出力に選択されたボタンのラベルやファイルのパスが出力されます。

これらのコマンドをシェルスクリプトでつなぎ合わせるだけでもちょっとした対話型のプログラムができます。

BeOS以外にはそういうのないのかな、と思っていたのですが、@aodag氏にZenityというのがあると教えてもらったので試してみました。ZenityはLinuxでもmacOSでも動きますし、Windows版のインストーラもあります。クレジット見ると2003年ということでBeOSの方が古いですね。BeOSにインスパイアして作られたんですかね。

Zenityを試す

Windowsは上記のインストーラで入ります。macOSはbrew install zenityです。MacPortsはBig Surではまだビルドが成功しませんね。Linuxとしては、Ubuntuはデスクトップの最小インストールでも入っていましたので、何もしなくても使えるようです。

BeOS/Haikuは3つのコマンドでしたがZenityは1コマンドでオプション違いで14種類のダイアログ(–formsは他の要素の集合)が利用できます。これらも、選択したものがエラーコードや標準出力で帰ってきます。

--calendar         カレンダーダイアログを表示する
--entry テキスト入力ダイアログを表示する
--error エラーダイアログを表示する
--info 情報ダイアログを表示する
--file-selection ファイル選択ダイアログを表示する
--list 一覧ダイアログを表示する
--progress 進捗表示ダイアログを表示する
--question 質問ダイアログを表示する
--warning 警告ダイアログを表示する
--scale スケールダイアログを表示する
--text-info テキスト情報ダイアログを表示する
--color-selection 色選択ダイアログを表示する
--password パスワードダイアログを表示する
--forms フォームダイアログを表示する

Ubuntuで実行してみました。

プログレスバーは、標準入力で流し込まれるテキストを使ってバーを更新したりラベルを更新できます。

progress.sh
#!/bin/sh

echo "10"; sleep 1
echo "# やる気が少したまってきました"
echo "20" ; sleep 1
echo "30" ; sleep 1
echo "40" ; sleep 1
echo "# やる気がそこそこたまってきました"
echo "50" ; sleep 1
echo "60" ; sleep 1
echo "70" ; sleep 1
echo "# やる気がだいぶ溜まってきました"
echo "80" ; sleep 1
echo "90" ; sleep 1
echo "100" ; sleep 1
echo "# やる気Maxです!"

macで実行させた結果はこちらです。

./progress.sh | zenity --progress --title="やる気" --text="やる気をためています..." --percentage=0

これらを駆使すると、ちょっとした変換プログラムをPythonでもNode.jsでも作って、入力ファイルや出力先のファイルをGUIから入力してもらうといったことが可能になります。ターミナルの画面が怖いという非プログラマーなユーザーにも使ってもらえるツールが簡単に作れますね。以前は、マスタの更新とか、ちょっとしたことをするのにGUIとしてJenkinsを立ててそこを使ってもらったりしましたが、これで単独で各PCで利用してもらえますね。

ZenityのGo移植

macOS版はいちおうHomebrewでもMacPorts(10.15なら)でもインストールはできるものの、かなり大量の依存を呼び込んで大量にビルドやらインストールやらが走ります。いろいろ調べてみたら、Go移植版がありました。

https://github.com/ncruces/zenity

WindowsとmacはOS標準機能を使うので外部ライブラリ非依存、Linux/FreeBSDなどのOSも、zenityがインストールされていなくてもqarma、matedialogといった類似のコマンドにフォールバックすることでポータビリティをあげています。

go get github.com/ncruces/zenity/...

使える機能は4種類です。BeOSと比べると、プログレスバーがない代わりに色選択が入ったという感じですね。

  • message (error, info, question, warning)
  • file selection
  • color selection
  • notification

cgo非依存で外部ライブラリに依存しないため、ビルドすればシングルバイナリになるので配布も簡単です。またライブラリとしても利用可能です。オプション体系はzenityとは違うので、そのまま置き換えとは行きませんが、便利です。

$ zenity -question -text シェルスクリプト連載の原稿書けた? \
-ok-label ばっちり -cancel-label まだ -extra-button 見直しをする

まとめ

シェルスクリプトをGUI化するZenityを紹介しました。標準入力、標準出力、エラーコードといったUNIXのお作法に従ってGUIが作れるのは面白いですね。

シェルスクリプト連載の5日目でした。次の月曜日は尾崎さんのオプション付きのオリジナルコマンドを作成しようです。