在上一篇文章中,我们谈到了正则表达式,我们看到了如何在 sed 和 awk 中使用它们进行文本处理,我们之前讨论过Linux sed命令和awk 命令。在这个shell脚本编写教程中,我们写了一些小的 shell 脚本,但我们并没有混淆,我认为我们应该更进一步,编写一个有用的 shell 脚本。
那么,如何编写shell脚本呢?这篇文章中的脚本将帮助你增强你的脚本编写技巧,其中包括详细的shell脚本编程示例。
bash shell脚本编程教程目录
- 发送消息
- 写命令
- 创建发送脚本
- 检查用户是否接受消息
- 检查消息是否包含在内
- 获取当前终端
- 发送长消息
- 监控磁盘空间
发送消息
我们将构建一个 bash 脚本,该脚本将向登录 Linux 系统的用户发送消息。
对于这个简单的 shell 脚本,我们只需要几个函数。我们将使用我们之前介绍的一些基本命令;你可以查看以前的帖子。
首先,我们需要知道登录的用户。你可以使用 who 命令执行此操作,该命令会检索所有登录用户。
$ who
要发送消息,你需要用户名和他当前的终端。
然后,你需要知道用户是否允许使用 mesg 命令发送消息。
$ mesg
如果结果显示“is y”,则表示用户允许消息。如果结果显示“is n”,则表示相反。
要检查任何记录的用户消息状态,请使用带有 -T 选项的 who 命令。
$ who -T
如果你看到破折号 (-),则表示用户关闭了消息,如果你看到加号 (+),则表示相反。
要允许消息,请键入带有“y”选项的 mesg 命令,如下所示:
$ mesg y
果然,它显示“is y”,这意味着该用户可以发送消息。
当然,我们需要另一个用户才能与他通信,所以在我的情况下,我将使用 SSH 从另一台 PC 连接到我的 PC,并且我已经和我的用户一起在系统上,所以我们有两个用户登录系统。
让我们看看如何发送消息。
write命令
你可以使用 write 命令在使用用户名和当前终端的用户之间发送消息。
对于登录图形环境(KDE、Gnome、Cinnamon 或任何)的用户,他们无法接收消息。用户必须登录到终端。
我们将从我的用户 likegeeks 向 testuser 用户发送一条消息,如何编写shell脚本?如下的shell脚本编程示例:
$ write testuser pts/1
键入 write 命令,后跟用户和终端,然后按 Enter。
当你按 Enter 键时,你可以开始输入消息。完成消息后,可以通过按Ctrl+D组合键发送消息,这是文件结束信号。我建议你查看有关信号和工作的帖子。
接收者可以识别哪个用户在哪个终端上发送消息。EOF 表示消息完成。
我认为现在我们拥有了构建 shell 脚本的所有部分。
创建发送脚本
在我们创建我们的 shell 脚本之前,我们需要确定我们要向他发送消息的用户当前是否在系统上,你可以使用 who 命令来确定。
logged=$(who | awk -v IGNORECASE=1 -v usr=$1 '{ if ($1==usr) { print $1 }exit }')
shell脚本编写教程:我们使用 who 命令获取登录用户并将其通过管道传输到 awk 并检查它是否与输入的用户匹配。
awk 命令的最终输出存储在变量记录中。
然后我们需要检查变量是否包含某些内容:
if [ -z $logged ]; then
echo "$1 is not logged on."
echo "Exit"
exit
fi
我建议你阅读有关 if 语句以及如何使用它的帖子Bash Script。
我们测试了记录的变量以检查它是否为零。
如果为零,脚本将打印消息,然后脚本终止。
如果用户已登录,则记录的变量包含用户名。
bash shell脚本编程教程:检查用户是否接受消息
你可以使用带有 -T 选项的 who 命令来检查用户是否允许消息。
check=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ "$check" != "+" ]; then
echo "$1 disable messaging."
echo "Exit"
exit
fi
请注意,我们将 who 命令与 -T 一起使用。如果他允许消息传递,则会在用户名旁边显示一个 (+)。否则,如果他将其关闭,它会在用户名旁边显示一个 (-)。
最后,如果指示符不等于加号 (+),我们会检查消息指示符。
如何编写shell脚本?检查消息是否包含在内
你可以检查发件人是否输入了消息,如下所示:
if [ -z $2 ]; then
echo "Message not found"
echo "Exit"
exit
fi
获取当前终端
在我们发送消息之前,我们需要获取当前用户终端并将其存储在一个变量中。
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
然后我们可以发送消息:
echo $2 | write $logged $terminal
现在我们可以测试整个 shell 脚本,看看它是如何进行的:
$ ./senderscript likegeeks welcome
让我们看看另一个 shell 窗口:
好的!你现在可以发送简单的单字消息。
发送长消息
如果你尝试发送多个单词:
$ ./senderscript likegeeks welcome to shell scripting
它没有用。只有我们发送了消息的第一个字。
shell脚本编写教程:为了解决这个问题,我们将在 while 循环中使用shift 命令。
shift
while [ -n "$1" ]; do
message=$message' '$1
shift
done
现在,我们需要解决的一件事是消息参数。
echo $whole_message | write $logged $terminal
所以现在整个shell脚本编程示例如下:
#!/bin/bash
logged=$(who | awk -v IGNORECASE=1 -v usr=$1 '{ if ($1==usr) { print $1 }exit }')
if [ -z $logged ]; then
echo "$1 is not logged on."
echo "Exit"
exit
fi
check=$(who -T | grep -i -m 1 $1 | awk '{print $2}')
if [ "$check" != "+" ]; then
echo "$1 disable messaging."
echo "Exit"
exit
fi
if [ -z $2 ]; then
echo "Message not found"
echo "Exit"
exit
fi
terminal=$(who | grep -i -m 1 $1 | awk '{print $2}')
shift
while [ -n "$1" ]; do
message=$message' '$1
shift
done
echo $message | write $logged $terminal
如果你现在尝试:
$ ./senderscript likegeeks welcome to shell scripting
惊人的!!有效。再说一次,我不是来编写一个脚本来将消息发送给用户,但主要目标是回顾我们的 shell 脚本知识并使用我们一起学习的所有部分,并了解事情是如何协同工作的。
监控磁盘空间
让我们构建一个脚本来监控最大的前十个目录。
如何编写shell脚本?如果向du 命令添加 -s 选项,它将显示汇总的总数。
$ du -s /var/log/
我们使用 -S 选项来显示子目录总数。
$ du -S /var/log/
你应该使用 sort 命令对 du 命令生成的结果进行排序,以获得最大的目录,如下所示:
$ du -S /var/log/ | sort -rn
-n 数字排序和 -r 选项颠倒顺序,所以它首先显示较大的。
我们使用 N 命令用数字标记每一行:
sed '{11,$D; =}' |
sed 'N; s/\n/ /' |
然后我们可以使用 awk 命令清理输出:
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
然后我们添加一个冒号和一个制表符,这样看起来好多了。
$ du -S /var/log/ |
sort -rn |
sed '{11,$D; =}' |
# pipe the first result for another one to clean it
sed 'N; s/\n/ /' |
# formated printing using printf
awk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
shell脚本编写教程:假设我们有一个名为 MY_DIRECTORIES 的变量,它包含两个文件夹。
MY_DIRECTORIES="/home /var/log"
我们将遍历 MY_DIRECTORIES 变量中的每个目录,并使用 du 命令获取磁盘使用情况。
因此,shell脚本编程示例将如下所示:
#!/bin/bash
MY_DIRECTORIES="/home /var/log"
echo "Top Ten Directories"
for DIR in $MY_DIRECTORIES; do
echo "The $DIR Directory:"
du -S $DIR 2>/dev/empty |
sort -rn |
sed '{11,$D; =}' |
# pipe the first result for another one to clean it
sed 'N; s/\n/ /' |
# formated printing using printf
awk '{printf $1 "\t" "\t" $2 "\t" $3 "\r\n"}'
done
exit
好的!!目录 /home 和 /var/log 都在同一个报告中。
你可以过滤文件,因此无需计算所有文件的消耗量,你可以计算特定扩展名(如 *.log 或其他内容)的消耗量。
在这里我必须提到一件事,在生产系统中,你不能依赖磁盘空间报告;相反,你应该使用磁盘配额。
配额包适用于此,但在这里我们正在学习 bash 脚本的工作原理。
如何编写shell脚本?我们在此处介绍的 shell 脚本是为了向你展示 shell 脚本的工作原理。在 Linux 中有很多方法可以实现任何任务。
我试图减少这个bash shell脚本编程教程长度并使一切尽可能简单,希望你喜欢它。