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

消息的接收方会看到如下信息:
    devalone@devalone.sansovo.org 从 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!

在接收端:
    devalone@devalone.sansovo.org 从 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

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

    <html xmlns:fb="http://ogp.me/ns/fb#">
    <head>
            <title>Quotes of the Day - The Quotations Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" >
    <meta name="MSSmartTagsPreventParsing" content="TRUE">
    <LINK REL="shortcut icon" HREF="/favicon.ico" TYPE="image/x-icon">
    <LINK REL="stylesheet" type="text/css" HREF="/qp.css">
    <script type="text/javascript">
      var _gaq = _gaq || [];

    ...


脚本可以使用 sed 和 gawk 工具提取出需要的格言。不过在使用脚本之前,需要对 wget 工具的输入和输出施加一点控制。

可以使用一个变量来保存页面地址(URL)。然后把这个变量作为参数传递给 wget 就行了:

    [devalone@devalone 26]$ url=www.quotationspage.com/qotd.html
    [devalone@devalone 26]$ wget $url
    --2018-07-17 17:07:41--  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.1”

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

    2018-07-17 17:07:47 (47.1 KB/s) - “qotd.html.1” 已保存 [13395]


每日格言脚本最终会通过 cron 或其他的脚本自动化工具设置成每天执行一次。所以 wget 命令的会话输出到 STDOUT是不合适的。可以使用 -o 选项将会话
输出保存在日志文件中,随后再浏览:

    [devalone@devalone 26]$ wget -o quote.log $url
    [devalone@devalone 26]$
    [devalone@devalone 26]$ cat quote.log
    --2018-07-17 17:10:17--  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.2”

         0K .......... ...                                         49.4K=0.3s

    2018-07-17 17:10:24 (49.4 KB/s) - “qotd.html.2” 已保存 [13395]

现在,当 wget 检索到 Web 页面信息时,它会将会话输出保存在日志文件中。


    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    出于各种原因,可能不希望 wget 生成日志文件或显示会话输出。可以使用 -q 选项,wget 命令会安安静静地完成它的任务。


要控制 Web 页面信息保存的位置,可以使用 wget 命令的 -O 选项。这样就可以自己指定文件名,而不是非得使用 Web 页面的名字作为文件名:

    [devalone@devalone 26]$ wget -o quote.log -O daily_quote.html $url
    [devalone@devalone 26]$
    [devalone@devalone 26]$ cat daily_quote.html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

    <html xmlns:fb="http://ogp.me/ns/fb#">
    <head>
            <title>Quotes of the Day - The Quotations Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" >
    <meta name="MSSmartTagsPreventParsing" content="TRUE">
    <LINK REL="shortcut icon" HREF="/favicon.ico" TYPE="image/x-icon">
    <LINK REL="stylesheet" type="text/css" HREF="/qp.css">

    ...

-O 选项允许将 Web 页面数据保存在指定的文件 daily_quote.html中。


3.2.1.2 测试 Web 地址
-----------------------------------------------------------------------------------------------------------------------------------------
Web 地址会发生变化。这些地址有时候似乎每天都在变。所以在脚本中测试地址的有效性就非常重要。可以使用 wget 工具的 --spider 选项完成这项任务:

    [devalone@devalone 26]$ wget --spider $url
    打开 Spider 模式。检查是否存在远程文件。
    --2018-07-17 17:18:09--  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]
    存在远程文件且该文件可能含有更深层的链接,
    但不能进行递归操作 -- 无法获取。

命令输出表明指定的 URL 是有效的,但就是输出的内容太多了。可以加上 -nv(代表 non-verbose)选项来精简输出信息:

    [devalone@devalone 26]$ wget -nv --spider $url
    2018-07-17 17:19:41 URL: http://www.quotationspage.com/qotd.html 200 OK

-nv 选项只显示出 Web 地址的状态,这种输出要容易理解得多。行尾的 OK 并不是说 Web地址是有效的,而是表明返回的 Web地址和发送的地址是一样的。

将 URL 变量的内容修改成一个错误的 Web 地址,看看 wget 是如何显示的。使用错误地址重新发出 wget 命令:

    [devalone@devalone 26]$ url=http://www.quotationspage.com/bad_url.html
    [devalone@devalone 26]$ wget -nv --spider $url
    2018-07-17 17:23:41 URL: http://www.quotationspage.com/error404.html 200 OK

注意,输出的最后仍然是 OK。但是Web地址的结尾是 error404.html。这才表示 Web 地址是无效的。

使用必要的 wget 命令抓取励志格言的 Web 页面,并能够测试页面地址的有效性,现在可以来动手编写脚本了。


3.2.2 创建脚本
-----------------------------------------------------------------------------------------------------------------------------------------
要在脚本编写过程中进行测试,需要将一个包含网站 URL 的参数传递给脚本。在脚本中,变量 qutoe_url 包含了传入参数的值。

    #
    quote_url=$1
    #


3.2.2.1 检查所传递的 URL
-----------------------------------------------------------------------------------------------------------------------------------------
在脚本中多做检查总是没错的。要检查的第一件事就是确保每日励志格言脚本所使用的网站 URL 是有效的。

脚本使用 wget和 --spider 选项来检查 Web 地址的有效性。但是结果必须保存到变量中,以便随后使用 if 语句进行检查。

要保存输出结果,需要在命令上使用标准的$()语法。除此之外,还得重定向 STDERR 和 STDOUT。这可以通过在 wget 命令后使用 2>&1 来实现:

    #
    check_url=$(wget -nv --spider $quote_url 2>&1)
    #

现在网站 URL 的状态消息被保存在了变量 check_url中。要从变量中找出错误指示 error404,需要使用参数扩展和 echo命令:

    #
    bad_url=$(echo ${check_url/*error404*/error404})
    #

在这个例子中,字符串参数扩展(string parameter expansion)允许对保存在 check_url 中的字符串进行搜索。可以把字符串参数扩展视为 sed的另一
种简单快速的替代形式。在搜索关键词周围加上通配符(*error404*),这样可以搜索整个字符串。如果找到了,echo 命令会使得字符串 error404被保存
在 bad_url 变量中。要是没有找到,bad_url 变量中包含的就是 check_url 变量中的内容。

现在可以使用 if 语句检查 bad_url 变量中的字符串了。如果从中找到了 error404,则显示一条消息,然后退出脚本。

    #
    if [ "$bad_url" = "error404" ]
    then
        echo "Bad web address"
        echo "$quote_url invalid"
        echo "Exiting script..."
        exit
    fi
    #

还有一种更简洁易行的方法。这种方法完全不需要使用字符串参数扩展和 bad_url 变量。if 语句的双方括号可以对变量 check_url 进行搜索。

    if [[ $check_url == *error404* ]]
    then
        echo "Bad web address"
        echo "$quote_url invalid"
        echo "Exiting script..."
        exit
    fi

if 结构中的 test 语句搜索变量 check_url 中的字符串。如果从中找到了子串 error404,则显示提示信息并退出脚本。要是没有发现错误,脚本继续执行。
这条语句可谓省时省力,不需要使用任何的字符串参数扩展,甚至连 bad_url变量都用不着。

现在检查工作已经就绪了,可以用一个无效的 Web 地址来测试一下脚本。将 url 变量设置成一个错误的 URL,作为参数传给 get_quote.sh 脚本。

 

3.2.2.2 获取 Web 页面信息
-----------------------------------------------------------------------------------------------------------------------------------------
抓取每日励志格言的页面数据很简单。可以在脚本中使用 wget 命令。将日志文件和包含页面信息的 HTML 文件保存在 /tmp 目录中。

    #
    wget -o /tmp/quote.log -O /tmp/quote.html $quote_url
    #

    NOTE:
    -------------------------------------------------------------------------------------------------------------------------------------
    如果在获取网站信息时不需要 cookie, 可以加入 wget 命令的 --no-cookies选 项。默认情况下是不会存储 cookie 的。
    
    
下一个任务是从下载好的 Web 页面文件的 HTML 代码中找出每日励志格言。这需要借助 sed 工具和 gawk 工具。


3.2.2.3 解析出需要的信息
-----------------------------------------------------------------------------------------------------------------------------------------
脚本首先从保存着 Web 页面信息的 /tmp/quote.html 文件中删除所有的 HTML标签。sed 工具能够完成这项任务:

    #
    sed 's/<[^>]*//g' /tmp/quote.html
    #

需要的格言正好位于当前日期的右边。由于系统日期与网站日期有时差和语言的可能不同的关系,选择日期行开始的两个相对固定的单词 "Selected from",
作为脚本搜索关键字。

这里需要用到 grep 命令、$()以及 date 命令。sed 命令的输出通过管道传入 grep 命令。grep 命令搜索关键字 "Selected from"。找到文本之后,使用
-A2 选项提取出另外两行文本。

    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    #

尽管输出的信息量已经大为降低,但是文本仍然太杂乱。多余的 > 符号可以很轻松的使用 sed 工具删除掉。在脚本中,grep命令的输出通过管道连接到sed
工具中,后者用来移除 > 符号。

    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    sed 's/>//g'
    #

在输出中有不止一条格言,在这个网站上,这种情况偶有发生:有时是一条,有时是两条或更多。所以脚本需要找到一种方法只提取第一条格言。

使用 sed 工具的 next 命令和 delete命令,先定位字符串 &nbsp,找到之后,移动并删除下一行文本。

    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    sed 's/>//g' |
    sed '/&nbsp;/{n ; d}'
    #

多余的格言被删掉,留下来的那条还需要继续清理。在格言的末尾仍然有一个字符串 &nbsp;。脚本可以使用另一条 sed 命令来解决这个麻烦,不过出于多
样性的考虑,这次使用 gawk 命令:

    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    sed 's/>//g' |
    sed '/&nbsp;/{n ; d}' |
    gawk 'BEGIN{FS="&nbsp;"} {print $1}'
    #

在上面的代码中,gawk 命令使用了输入字段分隔符 FS。这个字段分隔符被设置成字符串 &nbsp;,这样会使得 gawk 从输出中把它丢弃掉。

脚本要做的最后一步是将格言保存到文件中。这里使用 tee 命令:

    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    sed 's/>//g' |
    sed '/&nbsp;/{n ; d}' |
    gawk 'BEGIN{FS="&nbsp;"} {print $1}' |
    tee /tmp/daily_quote.txt > /dev/null
    #

提取出的格言被保存在 /tmp/daily_quote.txt 中,gawk 命令生成的所有输出被重定向到 /dev/null 中。

下面是最终的每日励志格言脚本:

    [devalone@devalone 26]$ cat get_quote.sh
    #!/bin/bash
    #
    # Get a Daily Inspirational Quote
    #####################################
    #
    # Script Variables ####
    #
    quote_url=www.quotationspage.com/qotd.html
    #
    # Check url validity ###
    #
    check_url=$(wget -nv --spider $quote_url 2>&1)
    #
    if [[ $check_url == *error404* ]]
    then
            echo "Bad web address"
            echo "$quote_url invalid"
            echo "Exiting script..."
            exit
    fi
    #
    # Download Web Site's Information
    #
    wget -o /tmp/quote.log -O /tmp/quote.html $quote_url
    #
    # Extract the Desired Data
    #
    sed 's/<[^>]*//g' /tmp/quote.html |
    grep "Selected from" -A2 |
    sed 's/>//g' |
    sed '/&nbsp;/{n ; d}' |
    gawk 'BEGIN{FS="&nbsp;"} {print $1}' |
    tee /tmp/daily_quote.txt > /dev/null
    #
    exit

运行:
    [devalone@devalone 26]$ sh get_quote.sh
    [devalone@devalone 26]$
    [devalone@devalone 26]$ cat /tmp/daily_quote.txt
    Selected from Michael Moncur's Collection of Quotations - July 17, 2018
    To me a lush carpet of pine needles or spongy grass is more welcome than the most luxurious Persian rug. Helen Keller (1880 - 1968)


    
                                                       (本篇完)

 

系列目录:

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

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

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

 

-----------------------------------------------------------------------------------------------------------------------------------------
参考:

    《Linux 命令行与 shell 脚本编程大全》 第 3 版 —— 2016.8(美)Richard Blum  Cristine Bresnahan

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值