如何编写实用的shell脚本?bash编程教程

2021年9月16日02:42:36 发表评论 976 次浏览

在上一篇文章中,我们谈到了正则表达式,我们看到了如何在 sed 和 awk 中使用它们进行文本处理,我们之前讨论过Linux sed命令awk 命令。在这个shell脚本编写教程中,我们写了一些小的 shell 脚本,但我们并没有混淆,我认为我们应该更进一步,编写一个有用的 shell 脚本。

那么,如何编写shell脚本呢?这篇文章中的脚本将帮助你增强你的脚本编写技巧,其中包括详细的shell脚本编程示例

bash shell脚本编程教程目录

  • 发送消息
  • 写命令
  • 创建发送脚本
    • 检查用户是否接受消息
    • 检查消息是否包含在内
    • 获取当前终端
    • 发送长消息
  • 监控磁盘空间

发送消息

我们将构建一个 bash 脚本,该脚本将向登录 Linux 系统的用户发送消息。

对于这个简单的 shell 脚本,我们只需要几个函数。我们将使用我们之前介绍的一些基本命令;你可以查看以前的帖子。

首先,我们需要知道登录的用户。你可以使用 who 命令执行此操作,该命令会检索所有登录用户。

$ who
如何编写实用的shell脚本?bash编程教程

要发送消息,你需要用户名和他当前的终端。

然后,你需要知道用户是否允许使用 mesg 命令发送消息。

$ mesg
如何编写实用的shell脚本?bash编程教程

如果结果显示“is y”,则表示用户允许消息。如果结果显示“is n”,则表示相反。

要检查任何记录的用户消息状态,请使用带有 -T 选项的 who 命令。

$ who -T

如果你看到破折号 (-),则表示用户关闭了消息,如果你看到加号 (+),则表示相反。

要允许消息,请键入带有“y”选项的 mesg 命令,如下所示:

$ mesg y
如何编写实用的shell脚本?bash编程教程

果然,它显示“is y”,这意味着该用户可以发送消息。

当然,我们需要另一个用户才能与他通信,所以在我的情况下,我将使用 SSH 从另一台 PC 连接到我的 PC,并且我已经和我的用户一起在系统上,所以我们有两个用户登录系统。

让我们看看如何发送消息。

write命令

你可以使用 write 命令在使用用户名和当前终端的用户之间发送消息。

对于登录图形环境(KDE、Gnome、Cinnamon 或任何)的用户,他们无法接收消息。用户必须登录到终端。

我们将从我的用户 likegeeks 向 testuser 用户发送一条消息,如何编写shell脚本?如下的shell脚本编程示例

$ write testuser pts/1
如何编写实用的shell脚本?bash编程教程

键入 write 命令,后跟用户和终端,然后按 Enter。

当你按 Enter 键时,你可以开始输入消息。完成消息后,可以通过按Ctrl+D组合键发送消息,这是文件结束信号。我建议你查看有关信号和工作的帖子。

如何编写实用的shell脚本?bash编程教程

接收者可以识别哪个用户在哪个终端上发送消息。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。

如何编写实用的shell脚本?bash编程教程

我们测试了记录的变量以检查它是否为零。

如果为零,脚本将打印消息,然后脚本终止。

如果用户已登录,则记录的变量包含用户名。

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
如何编写实用的shell脚本?bash编程教程

请注意,我们将 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 窗口:

如何编写实用的shell脚本?bash编程教程

好的!你现在可以发送简单的单字消息。

发送长消息

如果你尝试发送多个单词:

$ ./senderscript likegeeks welcome to shell scripting
如何编写实用的shell脚本?bash编程教程

它没有用。只有我们发送了消息的第一个字。

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脚本?bash编程教程

惊人的!!有效。再说一次,我不是来编写一个脚本来将消息发送给用户,但主要目标是回顾我们的 shell 脚本知识并使用我们一起学习的所有部分,并了解事情是如何协同工作的。

监控磁盘空间

让我们构建一个脚本来监控最大的前十个目录。

如何编写shell脚本?如果向du 命令添加 -s 选项,它将显示汇总的总数。

$ du -s /var/log/

我们使用 -S 选项来显示子目录总数。

$ du -S /var/log/
如何编写实用的shell脚本?bash编程教程

你应该使用 sort 命令对 du 命令生成的结果进行排序,以获得最大的目录,如下所示:

$ du -S /var/log/ | sort -rn
如何编写实用的shell脚本?bash编程教程

-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脚本?bash编程教程

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
如何编写实用的shell脚本?bash编程教程

好的!!目录 /home 和 /var/log 都在同一个报告中。

你可以过滤文件,因此无需计算所有文件的消耗量,你可以计算特定扩展名(如 *.log 或其他内容)的消耗量。

在这里我必须提到一件事,在生产系统中,你不能依赖磁盘空间报告;相反,你应该使用磁盘配额。

配额包适用于此,但在这里我们正在学习 bash 脚本的工作原理。

如何编写shell脚本?我们在此处介绍的 shell 脚本是为了向你展示 shell 脚本的工作原理。在 Linux 中有很多方法可以实现任何任务。

我试图减少这个bash shell脚本编程教程长度并使一切尽可能简单,希望你喜欢它。

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: