ウェブサイト検索

Linuxのシェルスクリプトでncursesウィジェットを使用する方法


このチュートリアルでは、シェルスクリプトで dialog utility の基本を学び、ncurses ウィジェットを使用する方法を見ていきます。最も使用されているLinuxディストリビューションにdialogをインストールする方法、dialogの動作を変更するために使用できる一般的なオプション、一部のウィジェットの使用方法を確認します。これには、inputbox、checklist、radiolist、および yesno が含まれます。最後に、ウィジェット処理によって得られたデータの使用方法を見ていきます。

このチュートリアルでは、あなたは学びます:

  • Linuxにdialogユーティリティをインストールする方法
  • 最も関連性の高い対話オプションは何ですか?
  • 入力ボックス、チェックリスト、ラジオリスト、パスワードボックス、メッセージボックス、カレンダーおよびはい/いいえウィジェットの使用方法
  • ウィジェット処理から派生したデータを管理する方法
sudo dnf install dialog

Debianでは次のように実行できます:

sudo apt-get install dialog

この dialog ユーティリティは、Archlinuxのコアリポジトリにも含まれているので、pacman を使用してインストールできます:

sudo pacman -S dialog

コマンドのインストールは、上記のディストリビューションの派生にも適用されます。

一般的なダイアログオプション

これらのオプションを「一般的」と呼ぶのは、使用したいウィジェットのタイプに関係なく独立して使用できるからです。ここでは、dialogを使い始めるときにすぐに関心を持つかもしれないいくつかのオプションを見ていきます。

ウィジェットボックスのタイトルを設定する:–titleオプション

--titleオプションを使用することで、ウィジェットのタイトルとして使用される文字列を指定できます; それはボックスの上部に表示されます。以下はその例です:

dialog --title "Dialog title" --inputbox "Enter your name:" 0 0

上記のコマンドの結果として表示されるものは次のとおりです:

--and-widgetオプションを使用すると、「チェーン」された複数のウィジェットを使用できます。最初のウィジェットを使用した後、すぐに2番目のウィジェットが表示されます。チェーンは、どちらかのダイアログがゼロ以外の終了ステータスを返すと停止します。その使用例は次のとおりです:

dialog \
  --inputbox "Enter your name:" 0 0 \
  --and-widget --inputbox "Enter your age:" 0 0

上記のコマンドを実行すると、私たちの名前を入力するための最初のウィジェットが表示されます。OKボタンをクリックして入力を確認すると、次のウィジェットが表示され、私たちの年齢を入力するように求められます。

クリアオプションを使って画面をクリアする

「--and-widget」オプションを使用すると、1つのウィジェットによって作成されたコンテンツが前のウィジェットによって生成されたものを上書きします。ウィジェットが正確に同じ画面スペースを占めていない場合、2つのコンテンツが混ざり合い、混乱を引き起こすことになります。

内容が重なるのを避けるために、--clearオプションを使用することができます。このオプションを使うと、次のウィジェットが表示される前にウィジェットの内容が消去されます: 背景色だけが保持されます。

デフォルトでボタンをハイライトとして設定する: –default-button オプション

使用しているウィジェットによっては、画面上に複数のボタンが表示され、そのうちの1つがデフォルトでハイライトされており、ユーザーがエンターを押したときに実行されるデフォルトのアクションを決定します。

ウィジェットのデフォルトを上書きするには、--default-button オプションの後にボタンの名前を指定します。名前は ok、yes、cancel、no、help、または extra のいずれかです。

このオプションは、潜在的に危険なアクションを実行する前に確認を促すときなどに非常に便利です。

dialog --default-button "no" --inputbox "Enter your name:" 0 0

リスト内のデフォルト選択要素を設定する –default-item

チェックリストやメニューウィジェットを使用する場合、可能な選択肢のリストの最初の要素がデフォルトで選択されます。--default-itemオプションを使用し、要素を参照することで、これを代替デフォルトとして使用できます:

dialog --default-item 2 --checklist "Select:" 0 0 5 \
  1 "First element" off \
  2 "Second element" off \
  3 "Third element" off

確認後の時間遅延を指定する:-sleepオプション

時々、私たちのアプリケーションがダイアログボックスの処理後に特定の秒数待機するようにしたいことがあります。この動作を実現するために、--sleepオプションを使用し、待機する秒数を値として提供できます。

dialog --sleep 3 --inputbox "Enter your name:" 0 0

上記の命令の結果として、inputboxウィジェットが表示され、ユーザーがENTERキーを押すと、呼び出しスクリプト内の次の命令が実行される前に3秒待機します。

選択タイムアウトの提供

場合によっては、ユーザーが選択を行うための最大秒数を指定したいことがあります。ダイアログアプリケーションは、そのような動作を得るために--timeoutオプションを提供します。タイムアウトの秒数は、オプションの引数として渡す必要があります。指定された秒数が経過した後にユーザーが選択を行わなかった場合、アプリケーションはエラーステータスで終了します。

dialog --timeout 3 --inputbox "Enter your name:" 0 0

ボタンの代替ラベルを設定する

dialogユーティリティは、ボタンのデフォルトラベルをオーバーライドするための一連のオプションを提供します: --exit-label、--extra-label、--help-label、--no-label、--ok-label、--yes-labelを使用して、それぞれ「終了」、「追加」、「ヘルプ」、「いいえ」、「OK」、および「はい」のボタンのラベルを変更できます。

前述の各オプションは、ボタンラベルとして使用される文字列を引数として受け取ります。以下はオプションの使用例です:

dialog --default-button "no" \
  --no-label "I don't" \
  --yes-label "I do" \
  --yesno "Do you really want to format the partition?" 0 0

上記のコマンドは次の結果を生成します。

  1. ウィジェットに表示されるテキスト;
  2. ウィジェットの幅;
  3. ウィジェットの高さ;

幅または高さに0の値を指定すると、対応する属性の値が自動的に設定されます。

入力ボックスウィジェット

入力ボックスウィジェットは、ユーザーにテキスト入力で質問に回答するよう促すために使用されます。テキストパラメータは質問を提供するために使用されます:文字列がダイアログボックスよりも長い場合、ダイアログボックスはスクロール可能になります。このウィジェットを使用するには、--inputboxオプションを伴ってダイアログを呼び出します:

チェックリストウィジェット

以前の例で、チェックリストウィジェットの見た目をすでに見ました:このタイプのウィジェットでは、一連の選択肢がユーザーに提供され、ユーザーはそれらの中から1つまたは複数を選択できます。このウィジェットを使用するには、--checklistオプションを使用しなければならず、すべてのウィジェットに渡さなければならない標準の3つのパラメータに加えて、list-heightおよび表示する選択肢も提供する必要があります。

line-height パラメータは、一度に表示される行数を設定するために使用されます。行数が利用可能な選択肢よりも少ない場合、メニューはスクロール可能になります。もし line-height の値に 0 を指定すると、行数は選択肢の数に対応します。

各選択肢には識別子(タグ)、名前、そしてステータスを提供する必要があります。ステータスはoffまたはonのいずれかです。もしステータスがonであれば、その選択肢はデフォルトでチェックされます。一度選択肢を確認すると、チェックしたエントリに関連するタグがstderrに表示されます。

dialog --checklist "Select items:" 0 0 0 \
  1 "Choice number one" off \
  2 "Choice number two" on \
  3 "Choice number three" off \
  4 "Choice number four" on

上記のコマンドで、4つのオプションを持つメニューを起動し、オプション2と4をデフォルトでチェックされた状態に設定しました。コマンドの出力は以下の通りです:

ラジオリストウィジェットは、--radiolistオプションでダイアログが呼び出されると起動します。チェックリストウィジェットと同様に動作しますが、選択肢は相互に排他的であるため、1つの要素のみを選択できます。ここでウィジェットの使用方法を示します。

dialog --radiolist "Select items:" 0 0 0 \
  1 "Choice number one" Off \
  2 "Choice number two" on \
  3 "Choice number three" off \
  4 "Choice number four" Off

パスワードボックスウィジェットを使用してユーザーにパスワードを尋ねる

パスワードボックスウィジェットは、ユーザーにパスワードの入力を促すために使用されます。セキュリティ上の理由から、ユーザーが入力したテキストは表示されません。この動作は、--insecureオプションを使用することで変更できます。このオプションを使用すると、ウィジェットは対応するフィールドに入力されたパスワードの各文字に対してアスタリスクを表示します。

私たちは、--passwordboxオプションを使用してダイアログを起動することでウィジェットを使用します:

dialog --insecure --passwordbox "Enter your password:" 0 0

上記のコマンドの出力は:

このウィジェットの使用は非常に簡単です:--msgboxオプションでダイアログを呼び出すことで呼び出され、textパラメーターの内容であるメッセージを表示します。単一のOKボタンが表示されます:

dialog --msgbox "This is a very important message that should be read carefully!" 0 0

カレンダーウィジェットは、--calendarオプションを使用してダイアログユーティリティを呼び出すことで使用できます。このウィジェットでは、表示される別々のセクションから月、日、年を選択することで日付を選ぶことができます。コマンドの一部としてデフォルトの日付を渡すことで、デフォルトの日付を設定することも可能です。

2020年5月5日をデフォルトの日付としてウィジェットを開始するには、例えば、次のコマンドを実行します:

dialog --calendar "Select a date:" 0 0 27 05 2020

次の出力が生成されます:

dialog --date-format %Y/%m/%d --calendar "Select a date" 0 0 27 05 2020

ユーザーに確認を促す: yesno ウィジェット

私たちはすでにこのウィジェットに遭遇しました:これはユーザーに確認を求めることを可能にします。これを使用する際には、textパラメータを介して尋ねる質問を指定します。ユーザーの選択に応じて、終了ステータスが返されます:ユーザーがはいボタンをクリックして確認した場合は0、それ以外の場合は1です。

このウィジェットを呼び出すには、--yesnoオプションを使用する必要があります。

dialog --yesno "Do you confirm?" 0 0

こちらがウィジェットです:

dialog --checklist "Select items:" 0 0 0 \
  1 "Choice number one" off \
  2 "Choice number two" on \
  3 "Choice number three" off \
  4 "Choice number four" on 2> choice.txt

ユーザーが選択を確認すると、それらはスペースで区切られて choice.txt ファイルに書き込まれます。

選択を直接変数に保存したい場合はどうすればよいでしょうか?このタスクを達成するためには、--stdoutオプションを使用し、ウィジェットの出力をstderrではなくstdinに表示する必要があります。

choices="$(dialog --stdout --checklist "Select items:" 0 0 0 \
  1 "Choice number one" off \
  2 "Choice number two" on \
  3 "Choice number three" off \
  4 "Choice number four" on)"

上の例では、ウィジェット処理の結果はchoices変数を介してアクセスできます。おそらく、私たちはそれらをループ処理したいかもしれません:

for choice in ${choices}; do echo "${choice}"; done
2
4

yesnoウィジェットのプロセスを管理するためには、異なる行動をする必要があります。すでに見たように、このウィジェットは出力を生成することはなく、表示に使用されるコマンドの終了コードをユーザーの選択に応じて変更します。ユーザーが確認し、質問に肯定的に答えた場合、終了コードは0に設定され、それ以外の場合は1に設定されます(これは奇妙に思えるかもしれませんが、0はOKを意味し、1はコマンドが成功しなかったことを示す終了ステータスであることを思い出してください)。これを考慮して、次のように書くことができます:

if dialog --yesno "Do you want to open an instance of gnome-terminal ?" 0 0; then
  clear
  gnome-terminal
fi

結論

このチュートリアルでは、dialog アプリケーションを使用してシェルスクリプト内で ncurses ウィジェットを使用する方法を見ました。最初に、ウィジェットタイプに依存せずに使用できるいくつかの一般的なオプションを見てから、特にいくつかのウィジェットを見ていきました。dialog と一緒に使用できるウィジェットは他にもたくさんあります。完全なリストについては、アプリケーションのマニュアルを参照することをお勧めします。

関連記事: