forループでhiptailが機能するようにします。

forループでhiptailが機能するようにします。

次のように163サイト(全国の店舗)のpingを確認するbashスクリプトがあります。

#!/bin/bash
#storestest.sh
#version 0.9.2

clear;
printf "Check stores procedure started; `date +"%d/%m/%Y %H:%M:%S"`\n";

declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an array and populated by the file stores.txt
declare -i UP=0; # Create a variable to serve as a counter for stores that are up
declare -i DOWN=0; # Create a variable to serve as a counter for stores that are down

touch storesdown.txt; # Create a file if does not exist to store the list of the store the stores that are down
printf "" > storesdown.txt; # Clear the contents of the file
touch storesup.txt; # Create a file if does not exist to store the list of the store the stores that are up
printf "" > storesup.txt; # Clear the contents of the file

whiptail --title "Testing stores connectivity" --backtitle "Store Test" --yes-button "OK" --no-button "Cancel" --yesno "Check stores procidure has started" 10 50

if [ $? -ne 0 ]; then
    exit;
fi


for i in "${STORESITE[@]}" ; do
    ping -c 3 $i > /dev/null 2> /dev/null;
    if [ $? -eq 0 ]; then
        echo "$i is up" >> storesup.txt;
        let UP++
        sleep 1
    else
        echo "$i is down"  >> storesdown.txt;
        let DOWN++
        sleep 1
    fi
    printf "Total: $UP are online and $DOWN are off line.\r";
done

echo "Total: $UP are online and $DOWN are off line.";
exit;

上記のスクリプトはうまくいきましたが、全体の進捗状況を表示するゲージを追加して、よりクールにすることにしました。これが私が次にしたことです:

#!/bin/bash
#storestest.sh
#version 0.9.3

clear;
printf "Check stores procedure started; `date +"%d/%m/%Y %H:%M:%S"`\n";

declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an array and populated by the file stores.txt
declare -i UP=0; # Create a variable to serve as a counter for stores that are up
declare -i DOWN=0; # Create a variable to serve as a counter for stores that are down

touch storesdown.txt; # Create a file if does not exist to store the list of the store the stores that are down
printf "" > storesdown.txt; # Clear the contents of the file
touch storesup.txt; # Create a file if does not exist to store the list of the store the stores that are up
printf "" > storesup.txt; # Clear the contents of the file

whiptail --title "Testing stores connectivity" --backtitle "Store Test" --yes-button "OK" --no-button "Cancel" --yesno "Check stores procidure has started" 10 50

if [ $? -ne 0 ]; then
    exit;
fi

total="${#STORESITE[*]}";

{
for ((g = 0; g <= $(( $total -1)); g++)); do

    for i in "${STORESITE[@]}"; do
        ping -c 3 $i > /dev/null 2> /dev/null;
        if [ $? -eq 0 ]; then
            echo "$i is up" >> storesup.txt;
            let UP++
            sleep 2
        else
            echo "$i is down"  >> storesdown.txt;
            let DOWN++
            sleep 2
        fi
        printf "Total: $UP are online and $DOWN are off line.\r";
    done
    sleep 1
    echo $g
  done
} | whiptail --gauge "Please wait" 6 60 0


echo "Total: $UP are online and $DOWN are off line.";
exit;

これは私が思ったようには機能しません...これは、少なくとも鞭の尾が機能するようにするために私が考えて書くための最良の方法ですが、明らかにこの方法でやっていることは入れ子になったループをスキップすることです。

PS 私は私のコーディングのいくつかが昔ながらで、昔ながらのbashスクリプトであることを知っています。

答え1

あなたのスクリプトには追加のループ(とにかく実行されます)があります。配列にpingを送信しています。下付き文字配列の下付き文字メンバーではありません。

追加のループがないバージョンは次のとおりです(予想どおりpingが実行されます$site)。

#!/bin/bash
#storestest.sh
#version 0.9.3

clear;
printf "Check stores procedure started; `date +"%d/%m/%Y %H:%M:%S"`\n";

declare -a STORESITE=($(cat 'stores.txt' | awk -F, '{print $1}')); # Declaring an array and populated by the file stores.txt
declare -i UP=0; # Create a variable to serve as a counter for stores that are up
declare -i DOWN=0; # Create a variable to serve as a counter for stores that are down

touch storesdown.txt; # Create a file if does not exist to store the list of the store the stores that are down
printf "" > storesdown.txt; # Clear the contents of the file
touch storesup.txt; # Create a file if does not exist to store the list of the store the stores that are up
printf "" > storesup.txt; # Clear the contents of the file

total="${#STORESITE[*]}";

whiptail --title "Testing stores connectivity" --backtitle "Store Test" --yes-button "OK" --no-button "Cancel" --yesno "Check stores procedure has started, with $total stores" 10 50

if [ $? -ne 0 ]; then
    exit;
fi

{
UP=0
DOWN=0
for ((g = 0; g <= $(( $total -1)); g++)); do

    site="${STORESITE[$g]}"
    ping -c 3 $site > /dev/null 2> /dev/null;
    if [ $? -eq 0 ]; then
        echo "$site is up" >> storesup.txt;
        let UP++
    else
        echo "$site is down"  >> storesdown.txt;
        let DOWN++
    fi
    # sleep 2
    # stdbuf --output=L printf "Total: $UP are online and $DOWN are off line.\r"
    stdbuf --output=L echo $(( ( g * 100 ) / total ))
    sleep 1
  done
} | whiptail --gauge "Please wait" 6 60 0

online=$(wc -l storesup.txt | awk '{print $1;}')
offline=$(wc -l storesdown.txt | awk '{print $1;}')

echo "Total: $online are online and $offline are off line.";
exit;

その他の修正:

  • stdbuf出力してみましたラインバッファ(これは測定器が期待どおりに機能するのに役立ちます。)
  • リダイレクトはサブプロセスに配置されるため、合計は最後の行に達しませんUPDOWN私は出力ファイルの行数を数えてこの問題を解決しました。
  • 最後に、進行状況バーにパーセントが表示されます。

関連情報