シェルでGUIダイアログ! CLIとGUIの架け橋となるZenityの使い方

Last modified: 2021-11-27

概要と実行方法

“Zenity” (zenityコマンド)とは、コマンドの実行によってGTKの各種ダイアログを表示し、ユーザの操作によって出力や戻り値が得られる小さなプログラム。

別のコマンドとの組み合わせにより、その便利さが実感できる。

GNOMEデスクトップ環境を構成するパッケージの一つとして提供されている。

ディストリによってはGNOMEを最小限構成でインストールすると含まれていないことがあり、その場合はzenityというパッケージを追加でインストールする必要がある。

書式としては、ダイアログの種類を指定するオプションを1つ付けた後、その種類に固有の詳細なオプションを付け加えていくものとなる。

ウィンドウタイトルの指定などのオプションは色々な種類のダイアログで共通して指定することができる。

$ zenity [種類指定オプション] ([共通オプション...] [種類固有オプション...])

詳細は

$ zenity --help-all

の出力を参照。

実行例

カレンダー

$ o=$(zenity --calendar --title "日付を指定" --text "日付を指定してください" --date-format="%Y|%m|%d"); echo "戻り値:'$?' 出力:'$o'"

エントリ(1行テキスト入力)

ユーザが入力した文字列が出力になる。

$ o=$(zenity --entry --title "テキスト入力" --text "文字列"); echo "戻り値:'$?' 出力:'$o'"

エラー

アイコン付きのエラーダイアログを表示する。

$ zenity --error --title "エラー" --text "メッセージ"

情報

アイコン付きの情報ダイアログを表示する。

$ zenity --info --title "情報" --text "メッセージ"

ファイル選択

ファイル選択ダイアログを表示し、処理対象を選択して閉じると0を返して出力としてその場所が得られる。キャンセルされると0以外の値を返す。

他のプログラムでも同様だが、GTKのファイル選択ダイアログではCtrl-Fでファイル名絞り込み(検索)を行ったりCtrl-Lで場所を手動で入力したりできる。

GNOME 3系以上のバージョンのZenityでは、保存ファイル選択時のウィンドウタイトルはウィンドウ自体には表示されない。

$ o=$(zenity --file-selection --title "保存ファイル選択" --save --confirm-overwrite); echo "戻り値:'$?' 出力:'$o'"
$ o=$(zenity --file-selection --title "複数ファイル選択" --multiple); echo "戻り値:'$?' 出力:'$o'"
$ o=$(zenity --file-selection --directory --title=ディレクトリ選択); echo "戻り値:'$?' 出力:'$o'"

リスト選択

OKが押されると0を返して選択肢の文字列が出力される。キャンセルされると0以外の値を返す。

$ o=$(zenity --list --title "リスト" --text "質問" --column 項目 "選択肢A" "選択肢B"); echo "戻り値:'$?' 出力:'$o'"

--hide-columnと複数の--columnの使用により、出力される文字列を表示されているものと異なるものにできる。

$ o=$(zenity --list --title "リスト" --text "質問" --hide-column 1 --column dummy --column 項目 A "選択肢A" B "選択肢B"); echo "戻り値:'$?' 出力:'$o'"

--radiolistでは複数の選択肢から一つを、--checklistでは複数の選択肢から一つまたは複数の選択ができ、複数の選択肢がチェックされた場合に|区切りで出力される。

$ o=$(zenity --list --title "ラジオリスト" --text "質問" --radiolist --hide-column 2 --column 選択 --column dummy --column 項目 true A "選択肢A" false B "選択肢B"); echo "戻り値:'$?' 出力:'$o'"
$ o=$(zenity --list --title "チェックリスト" --text "質問" --checklist --hide-column 2 --column 選択 --column dummy --column 項目 false A "選択肢A" false B "選択肢B"); echo "戻り値:'$?' 出力:'$o'"

進捗状況バー

パーセンテージの数字を標準入力から受け取ることでバーを制御する。--pulsateオプションは、進捗状況が分からないときに使用し、標準入力から文字が出力されると動き出す。

端末にも出力をするため、例ではteeコマンドを使用している。端末に出す必要のない場合は直接パイプでつなげてよい。

bash$ for ((i = 0; i < 100; i += 10)); do echo $i; sleep 0.5; done | tee >(zenity --progress --text "経過の表示")
bash$ for ((i = 0; i < 100; i += 10)); do echo $i; sleep 0.5; done | zenity --progress --text "経過の表示"
bash$ for ((i = 0; i < 100; i += 10)); do echo "dummy"; sleep 0.5; done | tee >(zenity --progress --text "経過の表示" --pulsate --auto-close)
$ wget -c [URL] 2>&1 | sed -u 's/.* \+\([0-9]\+%\).*$/\1/' | tee >(zenity --progress --title "ダウンロードの状態" --text "ダウンロード中...")

wgetの例では、sed-uオプションを使い、数字データをzenityへ次々と流している。

質問

“はい” を選択すると0が、“いいえ” を選択すると0以外が返る。

$ o=$(zenity --question --title "2択質問" --text "質問内容"); echo "戻り値:'$?' 出力:'$o'"

警告

アイコン付きの警告メッセージを表示する。

$ o=$(zenity --warning --title "警告" --text "メッセージ"); echo "戻り値:'$?' 出力:'$o'"

数字のつまみによる値の指定

つまみと数値を含むダイアログが表示され、つまみを動かすと内部の値も変化する。“OK” を押すと0が返り、“キャンセル” が押されると0以外が返る。

$ o=$(zenity --scale --title "値の指定" --text "文字列" --value 0 --min-value -50 --max-value 50); echo "戻り値:'$?' 出力:'$o'"

テキストデータの表示

複数行のテキストデータを入力欄(編集不可)に表示する。“OK” を押すと0が返り、“キャンセル” が押されると0以外が返る。

下の例でも、端末にも出力を出すために、teeコマンドを使用している。

$ dmesg | tee >(zenity --text-info --title "テキスト" --width=500 --height=300)

通知

通知機能を提供するライブラリ “libnotify” がインストールされていて、かつ、この機能を有効にしてビルドされた場合にのみ使える。

も参照。

$ exec 3> >(zenity --notification --window-icon /usr/share/pixmaps/xxx.png --text テスト --listen)

でシステムトレイに入り、マウスを乗せると指定した文字列を表示する。

メッセージをシステム通知で出力するには

$ echo "message: [メッセージ]" >&3

環境によっては、Pangoのマークアップ言語で装飾ができることがあるが、全ての環境が対応しているというわけではない。

例として、下のようにすると斜体になる。同様に、s,u,big,smallなども使える。

$ echo "message: <i>[メッセージ]</i>" >&3

マウスを乗せたときに表示する文字列(ツールチップ)を変更するには

$ echo "tooltip: [新しい文字列]" >&3

アイコンを変更するには

$ echo "icon: [アイコンの場所]" >&3

表示/非表示の切り替えは

$ echo "visible: [true(表示)かfalse(非表示)]" >&3

終了するには

$ exec 3>&-

注意点としては、execをした(擬似/仮想)端末の中でないとコマンドが送れない。シェルスクリプトの中でexec 3> >(zenity --notification --listenした後、現在の端末でコマンドを送りたい場合は.sourceでシェルスクリプトを実行する。
実際に使用する場合は、何かを処理するシェルスクリプトの中で起動させ、その状況を文字列に出力したり、バルーンに出したりしながら処理を行い、終了したときに閉じるような形になりそう。

  • 使用したバージョン
    • zenity 2.16.3 (USE=-debug libnotify)