2009-10-13 99 views
6

我發現了一個很棒的小程序,可以讓我將用戶友好的GUI添加到我的Bash腳本中;BASH腳本:whiptail文件選擇

鞭尾

然而whiptail man page是不是所有的樂於助人,不提供任何例子。做了一些谷歌搜索後,我明白瞭如何創建一個簡單的是/否菜單使用鞭尾:

#! /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 

但我真的想用鞭尾,以取代一些舊的代碼,我有幾個建一個文件選擇菜單不同的備份/恢復的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}" 

我認爲這必須通過鞭尾的「--menu」選項來完成的,但我不知道如何做呢? 任何指針? 或者你能指點我一些whiptail例子的方向嗎?

+0

我已經對我的答案(八進制轉換公式)做了一些小改動。 – 2009-10-16 22:11:56

回答

8

生成的文件名和菜單中選擇標籤的數組:

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 

趕選擇一個變量,使用此結構(代替你的鞭尾命令 「鞭尾命令」):

result=$(whiptail-command 2>&1 >/dev/tty) 

或者

result=$(whiptail-command 3>&2 2>&1 1>&3-) 

變量$result將包含與數組中的文件相對應的字母表的字母。不幸的是,版本4之前的Bash不支持關聯數組。你可以計算索引從這樣的信的文件的數組(注意「額外」的單引號):

((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>  │ 
       │          │ 
       └──────────────────────────────────────┘ 
+0

請注意:我編輯了我的答案,以取代之前的八進制轉換公式(差不多)完全錯誤。 – 2009-10-16 22:11:09

+0

對於臨時文件,您可以使用mktemp。例如,mytempfile=$(mktemp) ; echo "Hello world">$mytempfile; echo Contents of ${mytempfile}: $(cat $mytempfile) ; rm -f $mytempfile jbatista 2010-04-28 09:21:59

+0

@jbatista:這是真的,但它是如何適用的?這裏沒有提到臨時文件。 – 2010-04-28 10:21:57

3

Whiptail是使用Newt librarydialog最受歡迎的功能的輕量級重新實現。我做了一個快速檢查,Whiptail中的許多功能似乎都像對話框中的對手一樣。所以,一個對話教程應該讓你開始。你可以找到一個here,但Google當然是你的朋友。另一方面,extended example可能包含你的問題很多靈感。

0

我試過以下,它的工作:

whiptail --title "PPP Config" --backtitle "Welcome to SEUL" --menu YourTitle 20 80 10 `for x in $(ls -1 *.tgz); do echo $x "-"; done` 

你可能會變成一個多班輪這個問題,以及,我添加了檢查空單:

MYLIST=`for x in $(ls -1 *.tgz); do echo $x "-"; done` 
WC=`echo $MYLIST | wc -l` 

if [[WC -ne 0]]; then 
    whiptail --title "PPP Config" --backtitle "Welcome to SEUL" --menu YourTitle 20 80 10 $MYLIST 
fi 

你需要調整數字以獲得清晰的界面。如果你願意,你可以用其他任何東西代替"-"。但是,如果你不這樣做,你會看到每行有2個條目。

順便說一句:所選條目打印到stderr

這可能需要一些改進,但對於一個基本的想法,我認爲這已經足夠了。

0

這似乎是頂部的一個搜索whiptail時的結果,以前的結果都不適用於我。這是我使用的結果:

#! /bin/bash 
shopt -s nullglob 
dir=`pwd` 
cd /path/to/files 
arr=(*.tgz) 
for ((i=0; i<${#arr[@]}; i++)); do j=$((2*$i+2)); a[j]="${arr[$i]}"; a[j+1]=""; done 
a[0]="" 
# Next line has extra spaces at right to try to center it: 
a[1]="Please make a selection from the files below              " 
result=$(whiptail --ok-button "OK button text" --cancel-button "Cancel Button Text" --title "Title Text" --backtitle "Text at upper left corner of page" --menu "Menu Text (not used??)" 30 160 24 "${a[@]}" 2>&1 >/dev/tty) 
if [[ $? = 0 ]] 
then 
# ge 5 in next line should be length of file extension including . character, plus 1 
    [ ${#result} -ge 5 ] && outfile="/path/to/files/$result" || echo "Selection not made" 
fi 
cd "$dir" 

如果沒有有效的選擇,結果將爲空。我在列表頂部添加了一個虛擬選擇,作爲結果返回一個空字符串,這樣您就不會在菜單出現後意外地按Enter鍵來錯誤地選擇錯誤的文件。如果你不想這樣做,那麼在「for」行中刪除「do j = $((2 * $ i + 2))」中的+2以及下面兩行設置[0]和a [1]明確。

關於whiptail的令人困惑的事情是,當在這樣的情況下從數組中讀取數據時,它預計每行顯示兩個數據項,這兩個數據項都會顯示,第一個是希望返回的結果(如果預計該行)在某些情況下可能是字母或數字),第二種是您可能需要的任何描述性文字。這就是爲什麼在第一行中,我使用[0]給出一個空字符串作爲結果,並使用[1]作爲描述性文本,但是從那裏的第一個項目中包含文件名(這是我實際上想要返回),第二個是空字符串,因爲我不想在這些行上顯示文件名以外的任何文本。

另外一個以前的帖子說whiptail返回的錯誤代碼是255,如果取消按鈕被按下,但這不是我所擁有的版本的情況 - 它返回1.所以我只測試一個錯誤代碼0和如果它是我認爲它可能是一個有效的條目,那麼我測試一個有效的字符串長度(不僅僅是文件擴展名中的字符數,包括。字符)以確保。