在 shell 脚本中添加 Counter

我在 shell 脚本中有以下代码,如果没有找到任何文件,它将继续休眠。它会睡半个小时,但是目前我没有任何计数器,比如只执行下面的代码20次,然后如果文件仍然不存在就退出程序(意味着在20次检查之后不要做任何事情并退出完整的脚本)。

解决这个问题的最好方法是什么?因此,我也意识到,通过看电子邮件,它已经尝试了20次。

希望我说得够清楚了。

while true; do
if /home/hadoop/latest/bin/hadoop fs -ls /apps/hdtech/bds/quality-rt/dt=$DATE_YEST_FORMAT2 then
echo "Files Present" | mailx -s "File Present"  -r admin@host.com admin@host.com
break
else
echo "Sleeping for half an hour" | mailx -s "Time to Sleep Now"  -r admin@host.com admin@host.com
sleep 1800
fi
done
215615 次浏览

下面是实现计数器的方法:

counter=0
while true; do
if /home/hadoop/latest/bin/hadoop fs -ls /apps/hdtech/bds/quality-rt/dt=$DATE_YEST_FORMAT2 then
echo "Files Present" | mailx -s "File Present"  -r admin@host.com admin@host.com
exit 0
elif [[ "$counter" -gt 20 ]]; then
echo "Counter: $counter times reached; Exiting loop!"
exit 1
else
counter=$((counter+1))
echo "Counter: $counter time(s); Sleeping for another half an hour" | mailx -s "Time to Sleep Now"  -r admin@host.com admin@host.com
sleep 1800
fi
done

一些解释:

  • counter=$((counter+1))-这就是你如何增加一个计数器。在本例中,counter$在双括号内是可选的。
  • elif [[ "$counter" -gt 20 ]]; then-检查 $counter是否不大于 20。如果是这样,它将输出适当的消息并中断 while 循环。

试试这个:

counter=0
while true; do
if /home/hadoop/latest/bin/hadoop fs -ls /apps/hdtech/bds/quality-rt/dt=$DATE_YEST_FORMAT2 then
echo "Files Present" | mailx -s "File Present"  -r admin@host.com admin@host.com
break
elif [[ "$counter" -gt 20 ]]; then
echo "Counter limit reached, exit script."
exit 1
else
let counter++
echo "Sleeping for another half an hour" | mailx -s "Time to Sleep Now"  -r admin@host.com admin@host.com
sleep 1800
fi
done

解释

  • break-如果文件存在,它将中断并允许脚本处理文件。
  • [[ "$counter" -gt 20 ]]-如果计数器变量大于20,则脚本将退出。
  • let counter++-在每次传递时计数器增加1。

你可以用 for循环代替 while循环:

max_loop=20
for ((count = 0; count < max_loop; count++)); do
if /home/hadoop/latest/bin/hadoop fs -ls /apps/hdtech/bds/quality-rt/dt=$DATE_YEST_FORMAT2 then
echo "Files Present" | mailx -s "File Present"  -r admin@host.com admin@host.com
break
else
echo "Sleeping for half an hour" | mailx -s "Time to Sleep Now"  -r admin@host.com admin@host.com
sleep 1800
fi
done


if [ "$count" -eq "$max_loop" ]; then
echo "Maximum number of trials reached" >&2
exit 1
fi
#!/usr/bin/env bash
counter=0
while [[ "$counter" -lt 20 ]]
do
if [[ $counter -gt 0 ]] ; then
echo "Counter: $counter time(s); Sleeping for another half an hour" | mailx -s "Time to Sleep Now"  -r admin@host.com admin@host.com
sleep 1800
fi
if /home/hadoop/latest/bin/hadoop fs -ls /apps/hdtech/bds/quality-rt/dt=$DATE_YEST_FORMAT2 ; then
echo "Files Present" | mailx -s "File Present"  -r admin@host.com admin@host.com
exit 0
fi
: $((counter++))
done


echo "Counter: $counter times reached; Exiting loop!"
exit 1

下面是另一个例子,我添加了这段代码来说明以下几点:

  1. while可以将您的计数器作为条件-这消除了在循环中检查变量值的需要。
  2. 由于 if 分支无论如何都会导致循环结束(通过中断或退出) ,因此不需要最终的 else
  3. 我为增加计数器提供了不同的语法。老实说,我从来没有看过库拉的版本(let counter++) ,但我很喜欢它(它对我来说更简单)。
  4. 我不能100% 确定有些 while 循环提供的答案实际上循环了20次。相反,我认为它们中的一些循环了21次。
  5. 提出的解决方案实际上是给管理员额外的时间发电子邮件——如果你无论如何都要退出,就没有必要告诉管理员你睡了半个小时。我在 while 循环的开头添加了一个额外的 if,以避免额外的电子邮件(和睡眠)。

下面是20次找不到文件的运行的输出:

Counter: 1 time(s); Sleeping for another half an hour
Counter: 2 time(s); Sleeping for another half an hour
...
Counter: 19 time(s); Sleeping for another half an hour
Counter: 20 times reached; Exiting loop!

If 的短语是我们检查文件20次,但只睡19次。