System Status as SMS Text Messages
如果您非常关注,您会记得在我的上一篇文章中,我正在探索一个脚本的基本原理,该脚本将接受一个单词列表作为输入,并创建一个单词搜索网格,适合打印。事实证明,作为一个 shell 脚本,这非常难做到——它只是没有足够的能力以优雅的方式实现任何类型的函数式算法。所以,我打算放弃它,至少在我能找到别人的开源代码来激发灵感之前。
或者,当然,如果您有动力并且有一些时间进行实验,请回到我 2015 年 4 月的专栏,通读它,然后尝试自己动手实现一些东西。
在我收到关于作为 shell 脚本编程专栏作家却放弃脚本的奇怪之处的来信之前,我将指出,实际上从这次经历中学到很多东西。最具体地说,虽然想象 Linux 环境是完全平等的,并且每个脚本、每种语言和每个程序都与其他程序一样强大且设计良好,但这显然不是事实。
以 Perl 与 Awk 为例。Awk 功能强大,我经常使用它,但是尽管有使用 Perl 编写的主要软件程序,但您很难找到任何直接用 Awk 编程的重要软件、函数、应用程序或实用程序。C++ 与 PHP 也是如此,或者任何现代结构化语言与 Bourne Again Shell 也是如此。我说出来了。Shell 脚本编程只能带你走这么远,然后你意识到你已经触及了环境及其能力的边缘,现在是时候跳到另一种语言了。
事实上,当我写我广受欢迎的书籍《Wicked Cool Shell Scripts》时,由于必要性,偷偷加入了一个小型 C 程序:它是几行 C 代码,用于执行某个日期计算,如果用 shell 脚本编写,则需要几十行甚至数百行。
话虽如此,我将立即回到为 shell 辩护,认为它是一个功能强大、轻量级的编程和原型设计环境,非常适合各种任务,因为它能够非常轻松地访问整个 Linux 环境以及扩展到整个互联网的强大功能和能力。
您怎么看?您阅读了这个专栏,所以我可以合理地推断您有兴趣了解更多关于 Linux shell 环境中的编程。您多久会碰到 shell 的前沿,并意识到您必须切换到 Perl、Ruby、C、Cobol(开玩笑!)或其他更复杂的开发环境才能正确解决问题?
让我们谈谈短信我正在观看苹果公司推出新款 Apple Watch,并惊讶地发现,像一些高端 Android 智能手表一样,它会在小小的手表屏幕上显示完整的电子邮件和短信。这意味着对于系统管理员和 Linux IT 人员来说,这是一个很棒的设备,可以随时掌握他们的机器或机器组的状态。
当然,您可以通过让系统发送电子邮件来做到这一点,但让我们更进一步,利用电子邮件到 SMS 网关之一。表 1 显示了美国最常见的蜂窝运营商的网关地址列表。
表 1. 蜂窝运营商的 SMS 网关电子邮件地址无线运营商 | 域名 |
At&T | @txt.att.net |
Cricket | @mms.mycricket.com |
Nextel | @messaging.nextel.com |
Qwest | @qwestmp.com |
Sprint | @messaging.sprintpcs.com |
T-Mobile | @tmomail.net |
US Cellular | @email.uscc.net |
Verizon | @vtext.com |
Virgin | @vmobl.com |
例如,我可以向 AT&T 网络上号码为 (303) 555-1234 的人发送短信,方法是将电子邮件格式化为如下所示
3035551234@txt.att.net
掌握了这些信息后,您可以监控许多不同的状态,并在出现问题时收到简洁的短信。
担心负载平均值变得过高?这是一个可以通过 uptime
的单行输出轻松获得的数字
$ uptime
11:20 up 4 days, 22:44, 3 users, load averages: 1.08 1.40 1.46
最后三个数字是过去 1 分钟、5 分钟和 15 分钟的平均负载。在这种情况下,系统几乎没有被使用。但是,如果它跃升到 10、35 或超过 100 呢?那么一切都会慢下来。以下是如何编写一个简单的脚本来测试这种情况
#!/bin/sh
# loadwatch.sh - send an alert if uptime > MAXOK
MAXOK=10
loadavg=$(uptime | cut -d\ -f11 | cut -d. -f1)
if [ $loadavg -gt $MAXOK ] ; then
echo "Alert: Load avg $(uptime | cut -d\ -f11)"
fi
exit 0
掌握了有关各种 SMS 网关的信息,很容易硬编码收件人地址,这只会更改条件内的 echo
行
mail -s "Alert: Load avg $(uptime|cut -d\ -f11)" $recipient
在脚本的早期,“recipient”的格式类似于
recipient=3035551234@txt.att.net
或适合您自己的智能手表或其他设备的格式。
为了使此脚本有用,您可能希望每隔几分钟运行一次,以便在使用量激增时尽快收到警报。这最容易成为 cron 作业,如果您还没有探索您自己的自定义 cron 作业如何使您作为最基本的 Linux 用户的生活变得更好,那么您就错过了!
为了使脚本每十分钟运行一次,以下是它在 root 甚至只是您的用户 crontab 文件中的样子
0,10,20,30,40,50 * * * * /home/taylor/bin/loadwatch.sh
现代 crontab 具有更复杂的符号语言,可以使其更简洁一些
*/10 * * * * /home/taylor/bin/loadwatch.sh
为了真正有用,最好让脚本监控状态变化,这样它会在负载升到指定阈值以上时通知您,但在负载降回该阈值以下之前不会再次通知您。
这是通过我们老派程序员所说的信号量来完成的,信号量是一个状态变量,用于记住正在发生的事情。由于 shell 脚本本质上是短暂的,因此信号量需要是一个文件。通常,这些文件位于某种受保护的目录中,但为了演示脚本的目的,我们将其放在您的主目录中。
此时要知道的命令行函数是 lockfile(1)。这管理信号量的原子创建,以便您永远不会遇到所谓的“竞争条件”,即脚本的两个实例可能会在谁创建文件的问题上发生冲突。
以下是它如何与信号量一起工作
statefile=/home/taylor/bin/.loadavg
if [ -f "$statefile" ] ; then
# statefile already exists, we're in a high load situation
if [ $loadavg -gt $MAXOK ] ; then
# still in high load situation
echo "nothing to do, still in high load situation"
else
# high load situation has ended
/bin/rm -f $statefile
mail -s "Alert: load average back to normal" $recipient \
< /dev/null > /dev/null 2>&1
fi
else
# statefile doesn't exist, let's create it.
if [ $loadavg -gt $MAXOK ] ; then
# load average has jumped above OK level
lockfile $statefile
load=$(uptime | cut -d\ -f11)
mail -s "Alert: load average is $load" $recipient \
< /dev/null > /dev/null 2>&1
else
# load average was okay and still is.
echo "nothing to do, load average still ok."
fi
fi
当然,在四种可能的情况中有两种情况下,您真的希望删除调试代码,清理 if-then-else 链并缩短脚本,因为如果这要每十分钟运行一次,您肯定不希望生成“no change”消息!
考虑到这一点,以下是更简洁的代码块
if [ -f "$statefile" ] ; then
# statefile already exists, we're in a high load situation
if [ $loadavg -le $MAXOK ] ; then
# high load situation has ended
/bin/rm -f $statefile
mail -s "Alert: load average back to normal?" $recipient \
< /dev/null > /dev/null 2>&1
fi
else
# statefile doesn't exist, let's create it.
if [ $loadavg -gt $MAXOK ] ; then
# load average has jumped above OK level
lockfile $statefile
load=$(uptime | cut -d\ -f11)
mail -s "Alert: load average is $load?" $recipient \
< /dev/null > /dev/null 2>&1
fi
fi
请注意在使用命令行 Mail 程序时涉及的额外工作,您必须重定向输入,以便它不会等待来自 stdin 的消息,并重定向生成的“null message body”警告消息。这就是它的作用
< /dev/null > /dev/null 2>&1
否则,希望您可以通读并了解它的作用。
您还可以监控什么?当您想到 Linux 系统上可能发生的许多错误时,跟踪负载平均值是相当微不足道的,包括进程被卡住并使用过多的 CPU 时间、磁盘空间可能接近填满、RAM 被耗尽并导致过度交换,甚至未经授权的用户登录。
所有这些情况都可以分析,并且可以通过电子邮件或 SMS 短信向您发送警报,甚至发送到您闪亮的价值 17,000 美元的金色 Apple Watch。现在,您告诉我,您认为您的系统上有什么值得监控的?