我有一个 bash 脚本,用于检查 163 个站点(全国各地的商店)的 ping,如下所示:
#!/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
做过输出行缓冲(这有助于使仪表按预期工作)。 - 重定向使
UP
andDOWN
在子进程中,因此总计没有到达最后一行。我通过计算输出文件中的行数来解决这个问题。 - 最后,它在进度栏中显示百分比。