怎样在 Linux 中使用 Whiptail 在 Bash 脚本中创建 GUI 对话框

前段时间,我们简要讨论了关于 禅度,一个简单的程序,允许您在命令行和 shell 脚本中创建图形 (GTK+) 对话框。 在本文中,我们将讨论另一个 GUI 实用程序,称为 鞭尾 可用于在 Linux 中的 Bash 脚本中创建 GUI 对话框。

并非您编写的每个脚本都需要前端图形界面。 但有时如果你创建一个图形界面而不是依赖于与命令行交互会更好。 就我而言,如果脚本中需要一长串响应,我会选择使用图形界面。

Whiptail 是一个友好的 GUI 实用程序,它使用 蝾螈 编程库。 Whiptail 为不同的目的提供不同的对话框。 根据您的用例,您可以使用这些对话框使您的脚本更具交互性。

在 Linux 中安装 Whiptail

Whiptail 预装了许多发行版,但如果您的发行版没有安装whiptail,请按照以下说明进行安装。

要检查是否已经安装了whiptail,请运行以下命令。

$ which whiptail

要在 Debian/Ubuntu 及其衍生发行版上安装 Whiptail,请运行以下命令:

$ sudo apt install whiptail -y

Fedora/RHEL/CnetOS/AlmaLinux/洛基 Linux:

$ sudo dnf install newt

Arch Linux、EndeavourOS、Manjaro Linux:

$ sudo pacman -S whiptail

高山Linux:

$ apk add newt

帮助选项

您可以使用 --help 标志,它将显示支持的对话框列表和您可以使用的其他选项。 总共有 10 个对话框支持各种功能,我们将在接下来的部分中介绍它们。

$ whiptail -help
Box options: 
    --msgbox <text> <height> <width>
    --yesno  <text> <height> <width>
    --infobox <text> <height> <width>
    --inputbox <text> <height> <width> [init] 
    --passwordbox <text> <height> <width> [init] 
    --textbox <file> <height> <width>
    --menu <text> <height> <width> <listheight> [tag item] ...
    --checklist <text> <height> <width> <listheight> [tag item status]...
    --radiolist <text> <height> <width> <listheight> [tag item status]...
    --gauge <text> <height> <width> <percent>

1. 消息框

消息框将向用户显示消息并等待用户按下 <好的> 要么 钥匙。 当你按下 <好的> 它会抛出一个 返回码 0 如果你按 它会抛出 返回码 255.

$ whiptail --title "Welcome Message" --msgbox "Howdy, Welcome to OSTechnix.." 8 78
消息框

让我们解码上面的命令。

– 标题 这将为窗口添加标题
-msgbox 这将打印您在引号内提供的消息。
8 78 这设置了窗口的高度(8)和宽度(78)。

您可以打开一个新终端并检查whiptail 进程。 它将处于睡眠状态。 意义——等你按 <好的> 要么 .

$ ps -ef | grep -i whiptail 
karthick   20023    9251  0 22:41 pts/0    00:00:00 whiptail --title Welcome Message --msgbox Howdy, Welcome to OSTechnix.. 8 78 
karthick   20071   19379  0 22:41 pts/1    00:00:00 grep --color=auto -i whiptail 
$ ps -q 20023 -o state --no-headers 
S 

笔记: 状态 (小号) -> 可中断睡眠(等待事件完成)。

2.信息框

Info 类似于消息框但不同的是,消息框信息框不会等待用户输入。 采用 –-infobox 标记并将字符串作为参数传递,该参数将显示在信息框中。

在某些 shell 中,信息框会运行但不会显示任何结果。 您必须更改终端仿真并像我在下面的代码段中那样运行它。

$ TERM=ansi whiptail --title "Welcome Message" --infobox "Howdy, Welcome to OSTechnix.." 8 78 
信息框

3. 是/否框

是/否框将显示一个对话框 是的 要么 选项,如果你选择 <是> 它会抛出 返回 代码 0 当你按下 <否> 它会抛出 返回码 1.

采用 --yesno 标志以提示选择。 运行以下代码片段,它结合了是/否框和消息框。 首先,它会显示是/否选项,根据您的选择,它会抛出返回码。

创建一个 shell 脚本,复制下面的代码片段,然后运行它。

#!/usr/bin/env bash

whiptail --title "CONFIRMATION" --yesno "Should I proceed" 8 78 
if [[ $? -eq 0 ]]; then 
  whiptail --title "MESSAGE" --msgbox "Process completed successfully." 8 78 
elif [[ $? -eq 1 ]]; then 
  whiptail --title "MESSAGE" --msgbox "Cancelling Process since user pressed <NO>." 8 78 
elif [[ $? -eq 255 ]]; then 
  whiptail --title "MESSAGE" --msgbox "User pressed ESC. Exiting the script" 8 78 
fi 
是/否对话框是/否对话框

如果你不知道 bash 条件语句,请使用下面的链接查看我们的简短文章。

  • Bash 脚本 – 条件语句

4. 文本框

文本框将读取并打印文件。 在下面的片段中,我正在阅读 ostechnix.txt 文件。 标志 –scrolltext 允许您在有不适合当前窗口的长文本页面时使用鼠标滚轮垂直滚动。

$ whiptail --textbox --scrolltext ostechnix.txt 10 80
文本框文本框

5. 重定向

您将在接下来的部分中看到的对话框要求将输出存储在一个变量中,以便稍后用于处理。 小部件的返回值被发送到 stderr 而不是 stdout。 所以你必须交换 stdout 和 stderr 以便结果存储在变量中。

您必须使用以下表达式来交换标准输出和标准错误。

3>&1 1>&2 2>&3

让我们试着理解上面的表达式。 你知道 FD1 是标准输出,FD2 是标准错误。

  • 3>&1 – 任何被重定向到文件描述符 3 的东西都会被重定向到文件描述符 1。
  • 1>&2 – 发送到文件描述符 1(Stdout)的任何内容都被重定向到文件描述符 2。
  • 2>&3 – 发送到文件描述符 2(stderr) 的任何内容都被重定向到文件描述符 3。

通过这种方式,我们交换了 stdout 和 stderr,因此变量可以存储来自对话框的返回值。

6.密码箱

使用密码对话框,您可以键入在您键入时不会显示为纯文本的密码。 采用 --passwordbox 提示输入密码。

$ whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password"
密码对话框密码对话框

当你按下 <好的>,如果您从终端运行,它将抛出返回码 0 并将您键入的密码返回到控制台 (stderr)。

输出端输出端

您需要将密码捕获到一个变量中,然后在脚本中使用它。 如重定向部分所述,您必须重定向结果。

$ PASSWORD=$(whiptail --title "SET PASSWORD" --passwordbox "Choose a strong password" 8 78 3>&1 1>&2 2>&3)
$ echo "The password entered by the user is $PASSWORD"
将输出存储在变量中将输出存储在变量中

7.输入框

输入对话框将提示用户提供输入。 与密码对话框一样,如果您从终端运行它,您提供的输入将被打印到终端。 您必须使用重定向并将值存储到变量中,然后根据您的程序逻辑用于处理。

NEW_USER=$(whiptail --title "Create New User" --inputbox "Username to be created" 8 40 3>&1 1>&2 2>&3)
输入框输入框
将输出存储到变量将输出存储到变量

您还可以设置默认输入文本。 您所要做的就是在高度和宽度之后添加文本。 下面是语法 where 而不是 [init] 您将放置默认文本。

--inputbox <text> <height> <width> [init]

例子:

whiptail --title "Create New User" --inputbox "Username to be created" 8 40 noname
默认文本默认文本

现在让我们结合输入框、密码框、是/否框和文本框,编写一个简单的用户创建程序,看看怎样将这些对话框耦合在一起。

8. 清单对话框

清单允许您创建用户可以从中选择的选项列表。

--checklist <text> <height> <width> <listheight> [tag item status]...

以上是创建清单对话框的语法。 您必须使用 --checklist flag 后跟设置对话框的高度和宽度。

选项 <listheight> 指定您要创建多少个列表。 每个列表都将被标记 <status> 设置为 ON 或 OFF。 On 指向选择列表,Off 指向不选择列表。

$ whiptail --title "SELECT PACKAGES TO INSTALL" --checklist 
"List of packages" 20 100 10 
"chrome" "browser" OFF 
"pip3" "Python package manager" OFF 
"ksnip" "Screenshot tool" OFF 
"virtualbox" "virtualization software" ON

要选择一个列表,请按空格键并使用向上和向下箭头在列表之间移动。 完成后按回车。

清单对话框清单对话框

您可以将输出存储到数组中,然后再使用它。 标签(“Chromepip3, ksnip, virtualbox”) 名称将根据选择打印为 stderr 的输出。

SELECTED=($(whiptail --title "SELECT PACKAGES TO INSTALL" --checklist 
"List of packages" 20 100 10 
"chrome" "browser" OFF 
"pip3" "Python package manager" OFF 
"ksnip" "Screenshot tool" OFF 
"virtualbox" "virtualization software" ON 3>&1 1>&2 2>&3))
$ echo ${SELECTED[@]} # Array of values

样本输出:

"pip3" "ksnip" "virtualbox"

如果你不知道 bash 数组,我们有一篇关于 bash 大批。 我建议你看看下面的链接。

  • Bash 脚本 – 用示例解释的索引数组

9. 单选列表对话框

单选列表对话框类似于清单对话框,但唯一的区别是您只能从列表中选择一个选项。 从语法上讲,无线电列表和清单是相同的。

--radiolist <text> <height> <width> <listheight> [tag item status]...

例子:

SELECTED=$(whiptail --title "Choose Only One Package" --radiolist 
"List of packages" 20 100 10 
"chrome" "browser" OFF 
"pip3" "Python package manager" OFF 
"ksnip" "Screenshot tool" OFF 
"virtualbox" "virtualization software" OFF 3>&1 1>&2 2>&3)
单选按钮单选按钮
$ echo $SELECTED
virtualbox

10. 菜单对话框

菜单对话框类似于单选按钮对话框。 我觉得唯一的区别是,在单选按钮对话框中,您必须按 从列表中选择一个项目,然后按 Enter。 但在菜单对话框中,您只需按回车键,即可将标签名称返回到 stderr。

语法类似于清单和单选按钮,但唯一的区别是不需要“状态”选项在菜单对话框中设置 ON/OFF。

--menu <text> <height> <width> <listheight> [tag item]

例子:

TO_RUN=$(whiptail --title "Menu example" --menu "Choose an option" 25 78 5 
"backup" "Start taking defined backup" 
"restore" "restore from last backup" 
"Schedule" "Display active backup schedules" 3>&1 1>&2 2>&3)
菜单对话框菜单对话框
$ echo $TO_RUN 
backup

11. 进度条

要创建进度条,您必须使用以下语法。 首先,您将传递一个文本,该文本将在进度条运行时打印,并设置窗口的高度和宽度以及进度百分比。

--gauge <text> <height> <width> <percent>

进度百分比将由我们的逻辑控制。 看看下面的代码片段。 我将 while 循环重定向到进度条,并将 COUNTER 变量增加 10 个计数,这将用作进度百分比。

#!/usr/bin/env bash

COUNTER=0
while [[ ${COUNTER} -le 100 ]]; do
  sleep 1
  COUNTER=$(($COUNTER+10))
  echo ${COUNTER} 
done | whiptail --gauge "Running Data Loader" 6 50 ${COUNTER}

进度条将以 10 为单位递增。

进度条对话框进度条对话框

结论

我们已经到了本文的结尾。 在这里,我们简要了解了怎样使用 Whiptail 在 bash 脚本。 如果你已经用过whiptail,并且在slave下有什么绝招,可以通过评测区分享给我们。

资源:

Bash 脚本指南:

  • 怎样在 Linux 中的 Bash 脚本中使用日期命令
  • 怎样在 Linux 和 Unix 中调试 Bash 脚本
  • Bash 脚本——使用 getopts 解析 Bash 脚本中的参数
  • 怎样在 Linux 和 Unix 中使用 Zenity 在 Bash 脚本中创建 GUI 对话框
  • Bash 脚本 – 案例陈述
  • Bash 脚本 – 条件语句
  • Bash 脚本——字符串操作
  • Bash 脚本 – Printf 命令用示例解释
  • Bash 脚本——用示例解释索引数组
  • Bash 脚本——用示例解释的关联数组
  • Bash 脚本——用例子解释 For 循环
  • Bash 脚本 – While 和 until 循环用示例解释
  • 用示例解释 Bash 重定向
  • Bash 脚本——用例子解释的变量
  • Bash 脚本——用例子解释的函数
  • 用 Linux 中的示例解释 Bash Echo 命令
  • Bash Heredoc 初学者教程