Linux shell 脚本编程-实战篇(三)

继: Linux shell 脚本编程-实战篇(二)

 

3. 一些小有意思的脚本


 


3.1 发送消息


 


3.1.1 功能分析


对于这种简单的脚本,需要的功能不多。涉及的一些命令很常见,下面了解脚本所需的几个命令。


3.1.1.1 确定系统中都有谁


要用到的第一个工具就是 who命令。该命令可以输出当前系统中所有的登录用户。

示例:
    [devalone@devalone 25]$ who
    devalone pts/0        2018-07-17 11:10 (192.168.1.101)
    user1    pts/1        2018-07-17 16:01 (192.168.1.101)

发送消息所需要的所有信息都可以在这部分输出的信息列表中找到。who 命令默认给出的是可用信息的简略版本。这些信息包括:

    □ 用户名
    □ 用户所在终端
    □ 用户登入系统的时间
    
如果要发送消息,只需使用前两项信息。用户名和用户当前终端是必须要用到的。


3.1.1.2 启用消息功能
-----------------------------------------------------------------------------------------------------------------------------------------
用户可以禁止他人使用 mesg 工具向自己发送消息。因此在打算发送消息前,最好先检查一下是否允许发送消息。这只需要输入命令 mesg 就行了:

    [devalone@devalone 25]$ mesg
    是 n

结果中显示的 is n 表明消息发送功能被关闭了。如果结果是 y,表明允许发送消息。

要查看别人的消息状态,还可以使用who命令。记住,这只检查当前已登入用户的消息状态。
使用 who命令的 -T选项:

    [devalone@devalone shell-script]$ who -T
    devalone + pts/0        2018-07-17 11:10 (192.168.1.101)
    user1    + pts/1        2018-07-17 16:01 (192.168.1.101)

用户名后面的破折号(-)表示这些用户的消息功能已经关闭。如果启用的话,看到的是加号(+)。

如果要接收消息,需要使用 mesg 命令的 y 选项:

    [devalone@devalone shell-script]$ whoami
    devalone
    [devalone@devalone shell-script]$ mesg y
    [devalone@devalone shell-script]$ mesg
    是 y

当发出 mesg y 命令后,用户 devalone 的消息功能就启用了。可以使用 mesg 命令来检查用户的消息状态。毫无疑问,命令的结果是 y,这说明该用户可
以接收消息。

要想进行双向通信,其他用户也必须启用消息功能。在这个例子中,用户 user1 也启用了他的消息功能。


3.1.1.3 向其他用户发送消息
-----------------------------------------------------------------------------------------------------------------------------------------
我们的脚本用到的主要工具是 write命令。只要消息功能启用,就可以使用 write 命令通过其他登录用户的用户名和当前终端向其发送消息。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    只能使用 write 命令向登录到虚拟控制台终端的用户成功发送消息。登入图形化环境的用户是无法接收到消息的。

在下面的例子中,用户 devalone 向登录在终端 pts/1 上的用户 user1 发送了一条消息。在 devalone 的终端上,会话过程看起来如下:

    [devalone@devalone shell-script]$ write user1 pts/1
    Hello user1

消息的接收方会看到如下信息:
    [email protected] 从 pts/0 上在 16:14 发来消息...
    Hello user1

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    接收到消息之后,接收方经常需要按回车键来重新获得命令行提示符。
    
    
    
3.1.2 创建脚本
-----------------------------------------------------------------------------------------------------------------------------------------
使用脚本发送消息有助于解决一些潜在的问题。如果系统中有很多用户,要找出想发送消息的那个用户可是个苦差事!还得确定这个用户是否启用了消息功能。
另外,脚本还能够提高效率,可以一步就把消息快速发送给特定的用户。


3.1.2.1 检查用户是否登录
-----------------------------------------------------------------------------------------------------------------------------------------
第一个问题就是得让脚本知道要给谁发送消息。这一点很容易实现,只需要在执行脚本是加上一个参数就行了。对于确定特定用户是否登录的问题,可以利用
who 命令,脚本代码如下:

    # Determine if user is logged on:
    #
    logged_on=$(who | grep -i -m 1 $1 | gawk '{print $1}')
    #

在上面的代码中,who 命令的结果被管接入 grep 命令。grep 命令使用选项 -i 来忽略大小写,用户名使用大小写字母都可以。grep 命令中还包含了选项
-m 1,这是为了防止用户多次登入系统。grep 命令要么什么都不输出(如果用户还没有登录),要么生成用户首次登录的信息。输出的信息被传给gawk命令。
gawk 命令只返回第一个字段,要么为空,要么是用户名。该命令最终的输出结果被保存在变量 logged_on 中。

变量 logged_on 中可能什么都没有(如果用户没有登录),也可能包含用户名,可以对变量内容进行测试,并根据测试结果进行相应的处理。

    #
    if [ -z $logged_on ]
    then
        echo "$1 is not logged on."
        echo "Exiting script..."
        exit
    fi
    #

利用 if 语句和 test 命令来测试变量 logged_on 是否为空。如果变量为空,通过 echo 命令提醒脚本用户指定的用户尚未登录系统,然后使用 exit命令
退出脚本。如果指定用户已经登入系统,则变量 logged_on 中包含了该用户的用户名,脚本继续执行。


3.1.2.2 检查用户是否接受消息
-----------------------------------------------------------------------------------------------------------------------------------------
下一个重要事项是确定登录用户是否接受消息:

    # Determine if user allows messaging:
    #
    allowed=$(who -T | grep -i -m 1 $1 | gawk '{print $2}')
    #
    if [ $allowed != "+" ]
    then
        echo "$1 does not allowing messaging."
        echo "Exiting script..."
        exit
    fi
    #

这次使用 who 命令的 -T 选项。如果允许接收消息的话,这会在用户名后显示 +,否则会显示一个 -。who命令的结果通过管道接入 grep 和 gawk,只提取
出消息接收人,并将其存储在变量 allowed 中。最后使用 if 语句测试消息接收人是否被设置了+。如果没有设置+,则提示脚本用户并退出脚本。如果消息
接收人能够接收消息,脚本继续向下执行。


3.1.2.3 检查是否包含要发送的消息
-----------------------------------------------------------------------------------------------------------------------------------------
待发送的消息会被作为脚本参数。因此,还要检查脚本是否将消息作为了参数:

    # Determine if a message was included:
    #
    if [ -z $2 ]
    then
        echo "No message parameter included."
        echo "Exiting script..."
        exit
    fi
    #


3.1.2.4 发送简单的消息
-----------------------------------------------------------------------------------------------------------------------------------------
在发送消息前,必须识别并将用户当前终端保存在变量中:

    # Send message to user:
    #
    uterminal=$(who | grep -i -m 1 $1 | gawk '{print $2}')
    #

要发送消息,需要使用 echo 和 write:

    #
    echo $2 | write $logged_on $uterminal
    #

write 是一个交互式命令,所以它必须从管道中接收消息,这样脚本才能正常工作。echo 命令用来将保存在 $2 中的消息发送到 STDOUT,然后再通过管道
传给 write 命令。logged_on 变量保存了用户名,uterminal 变量保存了用户当前的终端。


3.1.2.5 发送长消息
-----------------------------------------------------------------------------------------------------------------------------------------
由于 bash shell 使用空格来区分不同的参数。如果消息中有空格,消息中的每个单词都被视为一个不同的参数。必须修改脚本来解决这个问题。对此,
shift 命令和 while 循环可助其一臂之力:

    # Determine if there is more to the message:
    #
    shift
    #
    while [ -n "$1" ]
    do
        whole_message=$whole_message' '$1
        shift
    done
    #

shift 命令允许在不知道参数总数的情况下处理各种脚本参数。该命令会将下一个参数移动到 $1。一开始必须在 while 循环前使用一次 shift,因为消息
是从 $2 参数开始的,而非 $1。

进入 while 循环后,它接着获取消息中的每个单词,并将单词添加到变量 whole_message 中,然后使用 shift 命令移动到下一个参数。处理完最后一个
参数后,while循环退出,完整的消息就被保存在了变量 whole_message 中。

还要对脚本进行另一处修改。脚本需要将变量 whole_message 发送给 write,而不是发送参数 $2:

    # Send message to user:
    #
    uterminal=$(who | grep -i -m 1 $1 | gawk '{print $2}')
    #
    echo $whole_message | write $logged_on $uterminal
    #

在脚本中使用 shift 命令时,参数 $1 中的内容被删除了。要解决这个问题,需要使用一个变量 muser 来保存参数 $1 的内容。

    # Save the username parameter
    #
    muser=$1
    #

现在变量 muser 中保存了用户名。grep 和 echo 命令中涉及使用参数 $1 的地方都可以使用 muser来替换。

最终脚本代码如下:

    [devalone@devalone 26]$ cat mu.sh
    #!/bin/bash
    #
    #mu.sh - Send a Message to a particular user
    #############################################
    #
    # Save the username parameter
    #
    muser=$1
    #
    # Determine if user is logged on:
    #
    logged_on=$(who | grep -i -m 1 $muser | gawk '{print $1}')
    #
    if [ -z $logged_on ]
    then
            echo "$muser is not logged on."
            echo "Exiting script..."
            exit
    fi
    #
    # Determine if user allows messaging:
    #
    allowed=$(who -T | grep -i -m 1 $muser | gawk '{print $2}')
    #
    if [ $allowed != "+" ]
    then
            echo "$muser does not allowing messaging."
            echo "Exiting script..."
            exit
    fi
    #
    # Determine if a message was included:
    #
    if [ -z $2 ]
    then
            echo "No message parameter included."
            echo "Exiting script..."
            exit
    fi
    #
    # Determine if there is more to the message:
    #
    shift
    #
    while [ -n "$1" ]
    do
            whole_message=$whole_message' '$1
            shift
    done
    #
    # Send message to user:
    #
    uterminal=$(who | grep -i -m 1 $muser | gawk '{print $2}')
    #
    echo $whole_message | write $logged_on $uterminal
    #
    exit


运行:
    [devalone@devalone 26]$ ./mu.sh user1 This is a test mesg script!

在接收端:
    [email protected] 从 pts/0 上在 16:54 发来消息...
    This is a test mesg script!
    EOF

 

3.2 获取格言
-----------------------------------------------------------------------------------------------------------------------------------------


3.2.1 功能分析
-----------------------------------------------------------------------------------------------------------------------------------------
有一些不错的网站可以获得每日格言。打开你惯用的搜索引擎,可以找到很多这类网站。找到之后,需要使用工具来下载这些格言。对于这种用途的脚本,
正是 wget 工具发挥用途之处。


3.2.1.1 学习 wget
-----------------------------------------------------------------------------------------------------------------------------------------
wget 是一款非常灵活的工具,它能够将 Web 页面下载到本地 Linux 系统中。

wget 是 GNU 项目,访问主页获取详细信息:

    http://www.gnu.org/software/wget/

要通过 wget下载 Web 页面,只需要使用 wget 命令和网站的地址就行了:

    [devalone@devalone 26]$ wget www.quotationspage.com/qotd.html
    --2018-07-17 17:02:45--  http://www.quotationspage.com/qotd.html
    正在解析主机 www.quotationspage.com (www.quotationspage.com)... 74.208.47.119
    正在连接 www.quotationspage.com (www.quotationspage.com)|74.208.47.119|:80... 已连接。
    已发出 HTTP 请求,正在等待回应... 200 OK
    长度:未指定 [text/html]
    正在保存至: “qotd.html”

    qotd.html                            [  <=>                                                    ]  13.08K  50.4KB/s    in 0.3s

    2018-07-17 17:02:52 (50.4 KB/s) - “qotd.html” 已保存 [13395]

网站的信息被存储在与 Web 页面同名的文件中。在这个例子中,文件名就是 qotd.html,这个文件中都是 HTML 代码。

[devalone@devalone 26]$ cat qotd.html

    

    
    
            Quotes of the Day - The Quotations Page
    
    
    
    
    

你可能感兴趣的:(Linux,操作系统,CentOS7,Fedora)