1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

yad : シェルスクリプトで簡単にGUIを作って活用したい

Last updated at Posted at 2022-01-09

はじめに

  • Githubの組織管理をしているときに、「新規ユーザのAさん、Bさん、…を組織Xに加えて」とかの依頼をよく受けます。
    • 最近は、Github Rest APIを用いて、スクリプトベースで登録処理ができるのでだいぶ楽になったのですが…、いちいちコマンドラインに打ち込むのも面倒。
    • slackで依頼を受けるので、slackの内容をコピペしたいな…、と思っておりました。
    • ちょっとしたGUIツールを作るのに、よくzenityを使用していたのですが、設定できる項目が少ないのが欠点でした。
  • 今回、zenityのforkであるyadを使用してみました。そこで、yadによるGUIの構築と得られるデータの処理についてまとめます。
    • yadについてまとめるつもりが、参考ページの「yad メモ」にすべてが書いてあります。感謝申し上げます。

0. 参考ページ

  • yad メモ
    • yadの使い方を非常に参考にさせていただきました。

1. 動作確認環境

  • OS : Ubuntu 20.04
  • CPU : Intel(R) Pentium(R) CPU G4560 @ 3.50GHz
  • RAM : 8GB
  • Software
    • bash : 5.0.17(1)-release
    • yad : 0.40.0 (GTK+ 3.24.20)
    • Xorg : 1.20.13

* yadのインストール

  • Ubuntuの場合、aptでインストール可能
sudo apt install yad

2. yadのお試し

  • yad メモ」を参考に、以下の情報が入力できるウィンドウを起動してみます。
    • 登録したい組織名(プルダウンリスト):TeamA, TeamB, TeamC
    • 登録したいユーザリスト(テキストボックス) *複数行を想定
  • コマンドを実行するだけでGUIが表示されます。これはzenityと同じですが、やはり神ツールです。
yad --title="ユーザ登録ウィンドウ" \
    --height=400 \
    --width=400 \
    --mouse \
    --fixed \
    --form \
      --item-separator='!'\
      --separator='|'\
      --field="所属チーム                   ":CB    'TeamA!TeamB!TeamC' \
      --field="登録するユーザを入力してください":TXT   ""
  • 下のような画面が表示されます。この状態で、適当入力してOKを押下すると、標準出力に入力情報が表示されます。
    • TeamA|hogehoge@gmail.com\nfugafuga@gmail.com\npiyopiyo@gmail.com|が出力となります。
yad_entry_window.png
$ yad --title="ユーザ登録ウィンドウ" \
>     --height=400 \
>     --width=400 \
>     --mouse \
>     --fixed \
>     --form \
>       --item-separator='!'\
>       --separator='|'\
>       --field="所属チーム                   ":CB    'TeamA!TeamB!TeamC' \
>       --field="登録するユーザを入力してください":TXT   ""
TeamA|hogehoge@gmail.com\nfugafuga@gmail.com\npiyopiyo@gmail.com|

* 出力内容のポイント

  • yadの表示項目ごとに|(パイプ)を区切り文字で連結した文字列が取得できる。
    • |(パイプ)となるのは、--form --separator='|'を設定しているからです。他の文字を指定することも可能です。
  • ただし、テキストボックスの"\n"は改行コードではなくただの文字
    • 実は、IFSを一時的に改行コードに修正して文字列分解を試みて、小一時間ハマってました。

3. yad出力結果を加工する

function main() {
  # ユーザ登録ウィンドウの表示
  local input=$(ここにyadによるウィンドウ処理を書く)

  # input情報をグループとユーザリストに分割する
  # input = グループ名|登録するユーザ|
  (
    # IFSを一時的に変更するため、サブシェルを利用する
    IFS=\|; ARR=(${input})
    GROUP_NAME=${ARR[0]}
    tmp_USERLIST=${ARR[1]}

    # 登録ユーザの分解
    USERLIST=(${tmp_USERLIST//\\n/|})
    for user in "${USERLIST[@]}"
    do
      // ここに登録処理とかを書く
      register ${GROUP_NAME} ${user}
    done
  )
}
  • yad処理を``か$()でサブ処理で実行し、その出力結果をbashスクリプトの変数に格納します。
  • その後、IFSを変数して、区切り文字を|(パイプ)にして、文字列をArray分割します。
    • ユーザは複数入力されるので、"\n"を|(パイプ)に置換して、文字列を再度Array分割します。
    • ちなみに、IFSを一時的に修正するので、サブシェルを利用すると安全です。
  • 以下のようなスクリプトとなりました。
# -----------------------------------------------------------
# @file ui_register.sh
# @brief ユーザ登録ウィンドウ、および入力情報を取得する
# @auther tomoten-umino
# @date 2022-01-09
# -----------------------------------------------------------
# !/bin/bash

# -----------------------------------------------------------
# @fn open_window
# @brief ユーザ登録ウィンドウ描画処理
# @param なし
# @return 0 : 正常終了, 1 : それ以外
# -----------------------------------------------------------
function open_window() {
  yad --title="ユーザ登録ウィンドウ" \
      --height=400 \
      --width=400 \
      --mouse \
      --fixed \
      --form \
        --item-separator='!'\
        --separator='|'\
        --field="所属チーム                   ":CB    'TeamA!TeamB!TeamC' \
        --field="登録するユーザを入力してください":TXT   ""
}


# -----------------------------------------------------------
# @fn register
# @brief 登録処理
# @param group : グループ名
# @param user : ユーザ名
# @return 0 : 正常終了, 1 : それ以外
# @remark ダミー処理
# -----------------------------------------------------------
function register() {
  local group=$1
  local user=$2

  echo "グループ名: ${group} , ユーザ名: ${user}"

  return 0
}


# -----------------------------------------------------------
# @fn main
# @brief メイン処理
# @param なし
# @return 0 : 正常終了, 1 : それ以外
# -----------------------------------------------------------
function main() {

  # errorチェック:yadインストール確認
  type yad >/dev/null 2>&1
  if [ $? != 0 ]; then
    # インストールされていない場合、エラー分を表示して終了する。
    echo "This script needs \"yad\". Please install yad"
    echo "ex) sudo apt install yad, dnf install yad, ..."
    return 1
  fi

  # errorチェック:DISPLAY変数は設定されているか
  # GUIアプリなので、DISPLAY変数は必須
  if [ x$DISPLAY = x ]; then
    # DISPLAY変数が空なので失敗
    echo "Please set DISPLAY"
    return 1
  fi

  ## 定数
  local GROUP_NAME=""
  local USERLIST=""
  local tmp_USERLIST=""

  # ユーザ登録ウィンドウの表示
  local input=$(open_window)

  # input情報をグループとユーザリストに分割する
  # input = グループ名|登録するユーザ|
  (
    # IFSを一時的に変更するため、サブシェルを利用する
    IFS=\|; ARR=(${input})
    GROUP_NAME=${ARR[0]}
    tmp_USERLIST=${ARR[1]}

    # 登録ユーザの分解
    USERLIST=(${tmp_USERLIST//\\n/|})
    for user in "${USERLIST[@]}"
    do
      register ${GROUP_NAME} ${user}
    done
  )
}

# 処理を実行する
main

4. デモ

regist_user.gif

5. おわりに

  • デモでの起動では、出力結果を見るためにあえてスクリプト起動をしていますが、Desktopにアイコンを作成して、アイコンダブルクリックから実行すれば、なんちゃってデスクトップアプリケーションが作成できます。
  • register処理は、このページに載せているのは登録情報をechoするだけのdummyですが、実際にGithub Rest APIを叩けば登録処理を実行できます。
  • 凝ったGUIを作成することはできませんが、zenityよりもはるかに自由度が高いため、いろいろと応用が効くと感じました。
1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?