You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在whiptail菜单中使用数组?时区选择脚本报错排查

问题描述

在搭载systemd的Linux机器上编写脚本,想用数组在whiptail中显示时区列表,脚本如下:

tzones=$(timedatectl list-timezones)
arr=( $tzones )
count=0
for i in "${arr[@]}"; do allzones[$count]=$(echo "\"$i\""); ((count=count+1)); done
for i in "${allzones[@]}"; do echo $i; done #So I know I have a list of items in quotes at this point
whiptail --title "Time zone" --menu "Select time zone" 25 78 16 "${allzones[@]}"

执行后Bash一直输出whiptail的帮助菜单,无法正常显示时区选择菜单。

问题原因

whiptail的--menu选项要求每个列表项必须是成对的参数:显示文本和对应的返回值。你当前构造的数组是每个元素带引号的单个字符串,不符合参数格式,导致whiptail识别失败,输出帮助菜单。

解决方案

方法1:修正数组构造逻辑

无需给时区字符串手动加引号,而是为每个时区添加对应的返回值(直接用时区本身即可),构造成对的数组元素:

# 初始化空数组
allzones=()
# 遍历所有时区,每一项添加两次(显示文本 + 返回值)
while IFS= read -r tz; do
    allzones+=("$tz" "$tz")
done < <(timedatectl list-timezones)

# 调用whiptail菜单
whiptail --title "Time zone" --menu "Select time zone" 25 78 16 "${allzones[@]}"

方法2:更简洁的写法

用mapfile读取时区到数组,再构造菜单参数:

# 读取所有时区到数组tzones
mapfile -t tzones < <(timedatectl list-timezones)

# 构造菜单参数数组
allzones=()
for tz in "${tzones[@]}"; do
    allzones+=("$tz" "$tz")
done

whiptail --title "Time zone" --menu "Select time zone" 25 78 16 "${allzones[@]}"

补充说明

  • 手动给时区加引号是多余操作,Bash会自动处理带空格的参数,反而会导致whiptail无法识别正确的成对参数。
  • 使用while IFS= read -r或mapfile是更健壮的写法,能兼容所有合法时区名称(即使包含特殊字符)。

内容的提问来源于stack exchange,提问作者megalamehaxxor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 09:33:17