2009-10-13 17 views
6

私はBashスクリプトにユーザーフレンドリーなGUIを追加できる素晴らしい小さなプログラムを見つけました。 whiptail man pageはすべてその役に立たないとすべての例を提供していないが BASHスクリプト:whiptailファイルの選択

です:whiptail

#! /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を使用して、ファイル選択メニューを構築したいと思い、私はいくつかを持っている:私はです:whiptailを使用して、単純なはい/いいえメニューを作成しない方法を理解し、いくつかのGoogle検索を行った後異なるバックアップ/私が持っているの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」オプションを経由して行われなければならないと仮定し、私はそれについて移動する方法がわからないのですか? ポインタはありますか? または、私はいくつかのwhiptailの例の方向に向けることができますか?

+0

私は私の答え(8進換算式)に小さな変更を加えました。 –

答えて

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 

( "です:whiptail-コマンド" のためのあなたです:whiptailコマンドを置き換えて)このような構造を使用し、変数に選択をキャッチする:

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

注:以前の8進換算式(ほぼ)を完全に間違ったものに置き換えて回答を編集しました。 –

+0

一時ファイルの場合、mktempを使用できます。たとえば、mytempfile=$(mktemp) ; echo "Hello world">$mytempfile; echo Contents of ${mytempfile}: $(cat $mytempfile) ; rm -f $mytempfile jbatista

+0

@bbatista:それは本当ですが、どのように適用できますか?ここには一時ファイルの言及はありません。 –

3

Whiptailは、最も一般的な機能のdialogの軽量再実装で、Newt libraryを使用しています。私は迅速なチェックを行い、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 

きれいなインターフェイスを得るために番号を調整する。必要に応じて"-"を他のものに置き換えることができます。しかし、そうしないと、1行に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を取り除いてください。 [1]明示的に。

whiptailの混乱していることは、このような状況で配列から読み込むと、1行に2つのデータ項目があり、どちらも表示されます。いくつかの状況では文字か数字かもしれません)、そして2番目のものはあなたが望むかもしれない記述的なテキストです。そのため、最初の行では、空の文字列を結果として与えるために[0]を使用し、記述テキストとして[1]を使用しますが、ペアの最初の項目にはファイル名が含まれています返りたいと思っています)、2番目の文字列は空文字列です。ファイル名以外のテキストを表示したくないからです。

また、キャンセルボタンが押された場合、whiptailは255のエラーコードを返しましたが、それは私が持っているバージョンではそうではありませんでした - それは1を返します。それが有効なエントリかもしれないと仮定している場合は、有効な文字列の長さ(文字を含むファイル拡張子の文字数以上)をテストします。

関連する問題