我找到了一个很棒的小程序,它可以让我在我的Bash脚本中添加用户友好的GUI;
惠普尾巴
然而,whiptail man page并没有提供那么多帮助,并且没有提供任何示例。在谷歌上进行了一些搜索之后,我了解了如何使用whiptail创建一个简单的yes/no菜单:
#! /bin/bash
# http://archives.seul.org/seul/project/Feb-1998/msg00069.html
if (whiptail --title "PPP Configuration" --backtitle "Welcome to SEUL" --yesno "
Do you want to configure your PPP connection?" 10 40 )
then
echo -e "\nWell, you better get busy!\n"
elif (whiptail --title "PPP Configuration" --backtitle "Welcome to
SEUL" --yesno " Are you sure?" 7 40)
then
echo -e "\nGood, because I can't do that yet!\n"
else
echo -e "\nToo bad, I can't do that yet\n"
fi但我真正想要构建的是一个文件选择菜单,使用whiptail替换我在几个不同的备份/恢复bash脚本中的一些旧代码:
#!/bin/bash
#This script allows you to select a file ending in the .tgz extension (in the current directory)
echo "Please Select the RESTORE FILE you would like to restore: "
select RESTOREFILE in *.tgz; do
break #Nothing
done
echo "The Restore File you selected was: ${RESTOREFILE}"我认为这必须通过whiptail的'--menu‘选项来完成,但我不确定该如何进行?有什么建议吗?或者你能给我指出一些鞭尾的例子吗?
发布于 2009-10-14 07:15:47
构建一个文件名和菜单选择标记的数组:
i=0
s=65 # decimal ASCII "A"
for f in *.tgz
do
# convert to octal then ASCII character for selection tag
files[i]=$(echo -en "\0$(( $s / 64 * 100 + $s % 64 / 8 * 10 + $s % 8 ))")
files[i+1]="$f" # save file name
((i+=2))
((s++))
done即使有带空格的文件名,这样的方法也会起作用。如果文件数量很大,您可能需要设计另一种标记策略。
对标签使用字母字符可以让您按字母跳转到项目。数字标签似乎不能做到这一点。如果您不需要该行为,那么您可以消除一些复杂性。
显示菜单:
whiptail --backtitle "Welcome to SEUL" --title "Restore Files" \
--menu "Please select the file to restore" 14 40 6 "${files[@]}"如果退出代码为255,则对话已取消。
if [[ $? == 255 ]]
then
do cancel stuff
fi要捕获变量中的选择,请使用此结构(将whiptail命令替换为"whiptail- command "):
result=$(whiptail-command 2>&1 >/dev/tty)或
result=$(whiptail-command 3>&2 2>&1 1>&3-)变量$result将包含与数组中的文件相对应的字母表中的字母。不幸的是,Bash版本4之前的版本不支持关联数组。您可以像这样从字母计算文件数组的索引(请注意“额外的”单引号):
((index = 2 * ( $( printf "%d" "'$result" ) - 65 ) + 1 ))示例:
Welcome to SEUL
┌──────────┤ Restore Files ├───────────┐
│ Please select the file to restore │
│ │
│ A one.tgz ↑ │
│ B two.tgz ▮ │
│ C three.tgz ▒ │
│ D another.tgz ▒ │
│ E more.tgz ▒ │
│ F sp ac es.tgz ↓ │
│ │
│ │
│ <Ok> <Cancel> │
│ │
└──────────────────────────────────────┘发布于 2009-10-13 20:34:28
Whiptail是使用Newt library的dialog最流行特性的轻量级重新实现。我做了一个快速检查,Whiptail中的许多功能看起来与对话框中的对应功能相似。因此,对话框教程应该可以帮助您入门。你可以找到一个here,但谷歌当然是你的朋友。另一方面,extended example可能包含了很多针对您的问题的灵感。
发布于 2019-06-14 03:50:06
这个函数是我的whiptail函数存储库的一部分
# ----------------------------------------------------------------------
# File selection dialog
#
# Arguments
# 1 Dialog title
# 2 Source path to list files and directories
# 3 File mask (by default *)
# 4 "yes" to allow go back in the file system.
#
# Returns
# 0 if a file was selected and loads the FILE_SELECTED variable
# with the selected file.
# 1 if the user cancels.
# ----------------------------------------------------------------------
function dr_file_select
{
local TITLE=${1:-$MSG_INFO_TITLE}
local LOCAL_PATH=${2:-$(pwd)}
local FILE_MASK=${3:-"*"}
local ALLOW_BACK=${4:-no}
local FILES=()
[ "$ALLOW_BACK" != "no" ] && FILES+=(".." "..")
# First add folders
for DIR in $(find $LOCAL_PATH -maxdepth 1 -mindepth 1 -type d -printf "%f " 2> /dev/null)
do
FILES+=($DIR "folder")
done
# Then add the files
for FILE in $(find $LOCAL_PATH -maxdepth 1 -type f -name "$FILE_MASK" -printf "%f %s " 2> /dev/null)
do
FILES+=($FILE)
done
while true
do
FILE_SELECTED=$(whiptail --clear --backtitle "$BACK_TITLE" --title "$TITLE" --menu "$LOCAL_PATH" 38 80 30 ${FILES[@]} 3>&1 1>&2 2>&3)
if [ -z "$FILE_SELECTED" ]; then
return 1
else
if [ "$FILE_SELECTED" = ".." ] && [ "$ALLOW_BACK" != "no" ]; then
return 0
elif [ -d "$LOCAL_PATH/$FILE_SELECTED" ] ; then
if dr_file_select "$TITLE" "$LOCAL_PATH/$FILE_SELECTED" "$FILE_MASK" "yes" ; then
if [ "$FILE_SELECTED" != ".." ]; then
return 0
fi
else
return 1
fi
elif [ -f "$LOCAL_PATH/$FILE_SELECTED" ] ; then
FILE_SELECTED="$LOCAL_PATH/$FILE_SELECTED"
return 0
fi
fi
done
}用法很简单
if dr_file_select "Please, select a file" /home/user ; then
echo "File Selected: \"$FILE_SELECTED\"."
else
echo "Cancelled!"
fihttps://stackoverflow.com/questions/1562666
复制相似问题