如何退出bash循环并停止脚本,但仅当所有迭代完成时



我有这样的代码,它基本上在DF命令内部执行一个循环,以查看哪些磁盘已满90%以上。

df -H | sed 1d  | awk '{ print $5 " " $1 }' | while read -r dfh; 
do 
#echo "$output" 
op=$(echo "$dfh" | awk '{ print $1}' | cut -d'%' -f1 ) 
partition=$(echo "$dfh" | awk '{ print $2 }' ) 
if [ $op -ge 90 ];  
then 
echo ">> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)" >> LOGFILE 
echo -e ">> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)" 
echo ">> There is not enough left storage in the disk to perform the upgrade, exiting..." >> LOGFILE 
echo -e ">> There is not enough left storage in the disk to perform the upgrade, exiting..." 
exit 1 
elif [ $op -ge 85 ]; 
then 
echo -e ">> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)" >> LOGFILE 
echo ">> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)" 
echo ">> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition" >> LOGFILE 
echo -e ">> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition"  
fi 
done 
if [ "$?" -eq 1 ]; 
then 
exit 
else 
echo -e ">> There is enough left storage in the disk to continue with the upgrade, OK" 
fi

我希望它只有在至少一个磁盘已满90%以上时才退出,这是最后一个if语句的用途

这里的问题是,循环在第一个识别为90%以上的磁盘上退出,这很糟糕,因为如果我有3个磁盘的识别率超过90%,它只会报告其中一个(循环中的第一个(,然后退出。基本上,我希望脚本报告所有处于90%或以上的磁盘(以及那些处于85%但不退出的磁盘,正如您所读到的(。

这可能吗?提前感谢

您的脚本看起来像是在大声要求重构为Awk。但这里有一个更温和的重构。

rc=0
df -H |
awk 'NR>1 { n=$5; sub(/%/, "", n); print n, $1 }' |
while read -r op partition; 
do 
if [ $op -ge 90 ];  
then 
tee -a LOGFILE <<-________EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There is not enough left storage in the disk to perform the upgrade, exiting...
________EOF
rc=1
elif [ $op -ge 85 ]; 
then
tee -a LOGFILE <<-________EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There enough left storage in the disk to perform the upgrade, but it is recommended to first increase the size of the disk $partition
________EOF
fi
[ "$rc" -eq 0 ]
done &&
echo ">> There is enough left storage in the disk to continue with the upgrade, OK" ||
exit 1

这将在所有分区上循环时跟踪rc,然后仅在循环完成时才继续执行最终条件。

一般来说,避免使用echo -e而使用printf,不过在这里,由于-e无论如何都没有做任何有用的事情,所以使用here文档效果更好。

您可以执行以下操作:

#!/bin/sh
warn=${1-85}
fail=${2-90}
test "$warn" -lt "$fail" || { echo Invalid parameters >&2; exit 1; }
check_disk(){
op=${1%%%}
partition=${2}
if test "$op" -ge "$warn"; then
tee -a LOGFILE <<-EOF
>> ### WARNING! Running out of space on "$partition ($op%)" on $(hostname) as on $(date)
>> There is not enough left storage in the disk to perform the upgrade, exiting...
EOF
fi
if test "$op" -ge "$fail"; then
return 1
fi
} 2> /dev/null
rv=0
df -H | awk 'NR > 1{ print $5 " " $1 }' 
| { while read -r op partition; do
if ! check_disk "$op" "$partition"; then rv=1; fi
done
test "$rv" -eq 0
} || exit 1

几个注意事项:

如果希望<<-在输出中抑制缩进,则必须使用文字硬选项卡作为缩进。

你需要把while/done放在括号里,给rv变量一个完整的范围来检查它。如果你只做df ... | while do/done,那么该变量将在管道外取消设置。

这仍然有点笨拙,可能最好在awk中完成整个过程,而不是在外壳中有while/do循环,但这些都是一些想法。特别是,你绝对不想写同一个echo行4次!

还要注意,解析df的输出非常脆弱。在我的框中,有几行文件系统列包含空白,因此第5列是,而不是装入点的当前用法。这个脚本在这样的输出中可能无法正常工作。

您可以在一次检查中完成,如下所示:

$ a=10 b=5  c=7 ; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
$ a=10 b=5  c=10; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
$ a=10 b=10 c=10; (( a>=10 && b>=10 && c>=10 )) && echo 'all >= 10'
all >= 10

最新更新