Linux shell 脚本编程-实战篇(二)
继: Linux shell 脚本编程-实战篇(一)2. 创建与数据库、Web及电子邮件相关的脚本2.1 MySQL 数据库 2.1.1 MySQL 数据库安装到 http://repo.mysql.com/ 找到合适的 MySQL 版本的 YUM 库 rpm 安装包,复制下载地址,然后执行下面指令安装 YUM 库: [devalone@devalone mys...
2. 创建与数据库、Web及电子邮件相关的脚本
2.1 MySQL 数据库
2.1.1 MySQL 数据库安装
到 http://repo.mysql.com/ 找到合适的 MySQL 版本的 YUM 库 rpm 安装包,复制下载地址,然后执行下面指令安装 YUM 库:
[devalone@devalone mysql]$ sudo dnf install -y http://repo.mysql.com/mysql57-community-release-fc24.rpm
检验 YUM 库已成功安装:
[devalone@devalone mysql]$ cat /etc/yum.repos.d/mysql-community.repo
[mysql-connectors-community]
name=MySQL Connectors Community
baseurl=http://repo.mysql.com/yum/mysql-connectors-community/fc/$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-tools-community]
name=MySQL Tools Community
baseurl=http://repo.mysql.com/yum/mysql-tools-community/fc/$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
# Enable to use MySQL 5.6
[mysql56-community]
name=MySQL 5.6 Community Server
enabled=0
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/fc/$releasever/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql57-community]
name=MySQL 5.7 Community Server
enabled=1
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/fc/$releasever/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql80-community]
name=MySQL 8.0 Community Server
baseurl=http://repo.mysql.com/yum/mysql-8.0-community/fc/$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql-tools-preview]
name=MySQL Tools Preview
baseurl=http://repo.mysql.com/yum/mysql-tools-preview/fc/$releasever/$basearch/
enabled=0
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
确认:
[mysql57-community]
name=MySQL 5.7 Community Server
enabled=1
其它项目: enabled=0
执行以下指令安装 MySQL 服务器:
[devalone@devalone mysql]$ sudo dnf install mysql-community-server
上次元数据过期检查:0:16:05 前,执行于 Mon Jul 16 11:33:57 2018。
依赖关系解决。
==================================================================================================================================
Package 架构 版本 仓库 大小
==================================================================================================================================
安装:
mecab x86_64 0.996-1.fc24.4 fedora 386 k
mecab-ipadic x86_64 2.7.0.20070801-12.fc24.1 fedora 11 M
mysql-community-client x86_64 5.7.19-1.fc24 mysql57-community 25 M
mysql-community-common x86_64 5.7.19-1.fc24 mysql57-community 277 k
mysql-community-libs x86_64 5.7.19-1.fc24 mysql57-community 2.2 M
mysql-community-server x86_64 5.7.19-1.fc24 mysql57-community 135 M
事务概要
==================================================================================================================================
安装 6 软件包
总下载:174 M
安装大小:788 M
确定吗?[y/N]: y
输入 y 回车开始安装服务器...
安装完之后启动 mysqld 并配置自启动服务:
[devalone@devalone mysql]$ sudo systemctl start mysqld.service
[devalone@devalone mysql]$ sudo systemctl enable mysqld.service
[devalone@devalone mysql]$ sudo systemctl status mysqld.service
● mysqld.service - MySQL Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since 一 2018-07-16 12:11:27 CST; 4s ago
Docs: man:mysqld(8)
http://dev.mysql.com/doc/refman/en/using-systemd.html
Process: 3544 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/S
Process: 3465 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
Main PID: 3547 (mysqld)
Tasks: 27 (limit: 512)
CGroup: /system.slice/mysqld.service
└─3547 /usr/sbin/mysqld --daemonize --pid-file=/var/run/mysqld/mysqld.pid
首次启动后,查看 MySQL 日志找到 root 账户的临时密码:
[devalone@devalone mysql]$ sudo grep 'temporary password' /var/log/mysqld.log
2018-07-16T04:11:08.456975Z 1 [Note] A temporary password is generated for root@localhost: 0I#ClXjke4F8
以 root 临时密码登录:
[devalone@devalone mysql]$ mysql -uroot -p
Enter password:
输入查找到的临时密码登录到 MySQL 系统。登录之后第一件事就是修改 root 账户密码:
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '1235678';
Query OK, 0 rows affected (0.00 sec)
退出 mysql,以新密码重新登录:
mysql> exit
Bye
[devalone@devalone mysql]$ mysql -uroot -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.7.19 MySQL Community Server (GPL)
2.1.2 使用 MySQL 数据库
-----------------------------------------------------------------------------------------------------------------------------------------
mysql 客户端程序允许通过用户账户和密码连到网络中任何地方的 MySQL 数据库服务器。默认情况下,如果在命令行上输入 mysql,且不加任何参数,它会
试图用 Linux 登录用户名连接运行在本地 Linux 系统上的 MySQL服务器。
通常还是创建一个应用程序专用的账户比较安全,不要用 MySQL 服务器上的 root 用户账户。这样可以针对应用程序用户实施访问限制,即便应用程序出现
问题,在必要时也可以删除或重建。可以使用 -u 参数指定登录用户名。
创建用户:
mysql> CREATE USER 'devalone'@'%' IDENTIFIED BY '12345678' ;
Query OK, 0 rows affected (0.00 sec)
2.1.2.1 mysql命令
-----------------------------------------------------------------------------------------------------------------------------------------
mysql 程序使用两种不同类型的命令:
□ 特殊的mysql命令
□ 标准SQL语句
mysql 程序使用它自有的一组命令,方便用户控制环境和提取关于 MySQL 服务器的信息。这些命令要么是全名(例如 status),要么是简写形式(例如\s)。
可以从 mysql 命令提示符中直接使用命令的完整形式或简形式。
示例:
mysql> \s
--------------
mysql Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using EditLine wrapper
Connection id: 5
Current database:
Current user: root@localhost
SSL: Not in use
Current pager: stdout
Using outfile: ''
Using delimiter: ;
Server version: 5.7.19 MySQL Community Server (GPL)
Protocol version: 10
Connection: Localhost via UNIX socket
Server characterset: latin1
Db characterset: latin1
Client characterset: utf8
Conn. characterset: utf8
UNIX socket: /var/lib/mysql/mysql.sock
Uptime: 34 min 19 sec
Threads: 1 Questions: 13 Slow queries: 0 Opens: 112 Flush tables: 1 Open tables: 105 Queries per second avg: 0.006
--------------
mysql 程序实现了 MySQL 服务器支持的所有标准SQL(Structured Query Language,结构化查询语言)命令。mysql程序实现的一条 SQL 命令 SHOW,可以
利用这条命令提取 MySQL 服务器的相关信息,如创建的数据库和表:
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> USE mysql;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> SHOW TABLES;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| engine_cost |
| event |
| func |
| general_log |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| ndb_binlog_index |
| plugin |
| proc |
| procs_priv |
| proxies_priv |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
31 rows in set (0.00 sec)
在这个例子中,用 SQL 命令 SHOW 来显示当前在 MySQL 服务器上配置过的数据库,然后用 SQL 命令 USE 来连接到单个数据库。mysql 会话一次只能连一个
数据库。
在每个命令后面都加一个分号。在 mysql 程序中,分号(或者 \g)表明命令的结束。如果不用分号,它会提示输入更多数据。
在处理长命令时,这个功能很有用。可以在一行输入命令的一部分,按下回车键,然后在下一行继续输入。这样一条命令可以占任意多行,直到用分号表明
命令结束。
2.1.2.2 创建数据库
-----------------------------------------------------------------------------------------------------------------------------------------
MySQL 服务器将数据组织成数据库。数据库通常保存着单个应用程序的数据,与用这个数据库服务器的其他应用互不相关。为每个 shell 脚本应用创建一个
单独的数据库有助于避免数据混用。
创建一个新的数据库要用如下 SQL 语句:
CREATE DATABASE name;
示例:
mysql> CREATE DATABASE mytest;
Query OK, 1 row affected (0.01 sec)
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| mytest |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
2.1.2.3 创建用户账户
-----------------------------------------------------------------------------------------------------------------------------------------
一直以 root 管理员账户连接到 MySQL 服务器。这个账户可以完全控制所有的 MySQL 服务器对象。在普通应用中使用 MySQL 的 root 账户是极其危险的。
如果有安全漏洞或有人弄到了 root 用户账户的密码,各种糟糕事情都可能发生在系统(以及数据)上。
为了阻止这种情况的发生,明智的做法是在 MySQL 上创建一个仅对应用中所涉及的数据库有权限的独立用户账户。可以用 GRANT SQL 语句来完成对已创建
账户的授权,也可以一次性完成创建用户及授权。
授权:
GRANT privileges ON databasename.tablename TO 'username'@'host'
创建账户并授权:
GRANT privileges ON databasename.tablename TO 'username'@'host' IDENTIFIED BY 'password'
示例:
mysql> GRANT CREATE,SELECT,INSERT,DELETE,UPDATE ON mytest.* TO 'devalone'@'%';
Query OK, 0 rows affected (0.00 sec)
第一部分定义了用户账户对数据库有哪些权限。这条语句允许用户查询数据库数据(select权限)、插入新的数据记录以及删除和更新已有数据记录。
test.* 项定义了权限作用的数据库和表。通过下面的格式指定:
database.table
在指定数据库和表时可以使用通配符。这种格式会将指定的权限作用在名为 test 的数据库中的所有表上。
最后,你可以指定这些权限应用于哪些用户账户。grant 命令的便利之处在于,如果用户账户不存在,它会创建。IDENTIFIED BY 部分允许为新用户账户设定
默认密码。
可以直接在 mysql 程序中测试新用户账户:
[devalone@devalone mysql]$ mysql mytest -u devalone -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 5.7.19 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
第一个参数指定使用的默认数据库(mytest),-u 选项定义了登录的用户,-p 用来提示输入密码。输入 devalone 用户账户的密码后,就连到了服务器。
2.1.2.4 创建数据表
-----------------------------------------------------------------------------------------------------------------------------------------
MySQL 是一种关系数据库(relational database)。在关系数据库中,数据按照字段、记录和表进行组织。数据字段是信息的单个组成部分,比如员工的姓
或工资。记录是相关数据字段的集合,比如员工ID号、姓、名、地址和工资。每条记录都代表一组数据字段。
表含有保存相关数据的所有记录。可以用一个 Employees 表来保存每个员工的记录:
要在数据库中新建一张新表,使用 SQL 的 CREATE TABLE 命令:
mysql> CREATE TABLE employees (
-> empid int not null,
-> lastname varchar(30),
-> firstname varchar(30),
-> salary float,
-> primary key (empid));
Query OK, 0 rows affected (0.25 sec)
mysql> SHOW TABLES ;
+------------------+
| Tables_in_mytest |
+------------------+
| employees |
+------------------+
1 row in set (0.00 sec)
2.1.2.5 插入和删除数据
-----------------------------------------------------------------------------------------------------------------------------------------
使用 SQL 命令 INSERT 语句向表中插入新的记录。每条 INSERT 语句都必须指定数据字段值来供 MySQL 服务器接受该记录。
INSERT 语句格式如下:
INSERT INTO table VALUES (...)
每个数据字段的值都用逗号分开。
mysql> INSERT INTO employees VALUES (1, 'Blum', 'Rich', 25000.00);
Query OK, 1 row affected (0.06 sec)
要从表中删除数据,可以用 SQL 命令 DELETE 语句:
DELETE FROM table;
其中 table 指定了要从中删除记录的表。这个命令有个小问题:它会删除该表中所有记录。
要想只删除其中一条或多条数据行,必须用 WHERE 子句。WHERE 子句允许创建一个过滤器来指定删除哪些记录。
示例:
mysql> DELETE FROM employees WHERE empid = 2;
Query OK, 1 row affected (0.04 sec)
2.1.2.6 查询数据
-----------------------------------------------------------------------------------------------------------------------------------------
所有查询都是用 SQL 命令 SELECT 语句来完成。SELECT命令非常强大,但用起来也很复杂。
SELECT 语句的基本格式如下:
SELECT datafields FROM table
datafields 参数是一个用逗号分开的数据字段名称列表,指明了希望查询返回的字段。如果要提取所有的数据字段值,可以用星号*作通配符。
示例:
mysql> SELECT * FROM employees;
+-------+----------+------------+--------+
| empid | lastname | firstname | salary |
+-------+----------+------------+--------+
| 1 | Blum | Rich | 25000 |
| 2 | Blum | Barbara | 45000 |
| 3 | Blum | Katie Jane | 34500 |
| 4 | Blum | Jessica | 52340 |
+-------+----------+------------+--------+
4 rows in set (0.00 sec)
可以用一个或多个修饰符定义数据库服务器如何返回查询数据。下面列出了常用的修饰符:
□ WHERE :显示符合特定条件的数据行子集。
□ ORDER BY :以指定顺序显示数据行。
□ LIMIT :只显示数据行的一个子集。
WHERE 子句是最常用的 SELECT 语句修饰符。它允许你指定查询结果的过滤条件。
示例:
mysql> SELECT * FROM employees WHERE salary > 40000;
+-------+----------+-----------+--------+
| empid | lastname | firstname | salary |
+-------+----------+-----------+--------+
| 2 | Blum | Barbara | 45000 |
| 4 | Blum | Jessica | 52340 |
+-------+----------+-----------+--------+
2 rows in set (0.00 sec)
MySQL 作为成功的典型开源关系型数据库系统,具有丰富数据管理能力,详细信息参考其官网专业文档:
https://dev.mysql.com/doc/
2.1.3 在脚本中使用数据库
-----------------------------------------------------------------------------------------------------------------------------------------
现在已经有了一个可以正常工作的数据库,可以将精力放回 shell 脚本编程了。
2.1.3.1 登录到服务器
-----------------------------------------------------------------------------------------------------------------------------------------
如果为自己的 shell 脚本在 MySQL 中创建了一个特定的用户账户,需要使用 mysql命令,以该用户的身份登录。实现的方法有好几种,其中一种是使用 -p
选项,在命令行中加入密码:
mysql mytest -u devalone –p 12345678
不过这并不是一个好做法。所有能够访问脚本的人都会知道数据库的用户账户和密码。
要解决这个问题,可以借助 mysql 程序所使用的一个特殊配置文件。mysql 程序使用 $HOME/.my.cnf 文件来读取特定的启动命令和设置。其中一项设置是
用户启动的 mysql 会话的默认密码。
[devalone@devalone ~]$ cat .my.cnf
[client]
password = 12345678
[devalone@devalone ~]$ chmod 400 .my.cnf
可以使用 chmod 命令将 .my.cnf文件限制为只能由本人浏览。
测试登录:
[devalone@devalone ~]$ mysql mytest -u test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
...
这样就不用在 shell 脚本中将密码写在命令行上了。
2.1.3.2 向服务器发送命令
-----------------------------------------------------------------------------------------------------------------------------------------
在建立起到服务器的连接后,接着就可以向数据库发送命令进行交互。有两种实现方法:
□ 发送单个命令并退出;
□ 发送多个命令。
要发送单个命令,必须将命令作为 mysql 命令行的一部分。对于 mysql 命令,可以用 -e 选项。
示例:
[devalone@devalone 25]$ cat mtest1.sh
#!/bin/bash
# send a command to the MySQL server
MYSQL=$(which mysql)
$MYSQL mytest -u devalone -p -e 'select * from employees'
运行:
[devalone@devalone 25]$ ./mtest1.sh
Enter password:
+-------+----------+------------+--------+
| empid | lastname | firstname | salary |
+-------+----------+------------+--------+
| 1 | Blum | Rich | 25000 |
| 2 | Blum | Barbara | 45000 |
| 3 | Blum | Katie Jane | 34500 |
| 4 | Blum | Jessica | 52340 |
+-------+----------+------------+--------+
数据库服务器会将 SQL 命令的结果返回给 shell 脚本,脚本会将它们显示在 STDOUT 中。
如果需要发送多条 SQL 命令,可以利用文件重定向。要在 shell 脚本中重定向多行内容,就必须定义一个结束(end of file)字符串。结束字符串指明了
重定向数据的开始和结尾。
示例:
[devalone@devalone 25]$ cat mtest2.sh
#!/bin/bash
# sending multiple commands to MySQL
MYSQL=$(which mysql)
$MYSQL mytest -u devalone -p <<EOF
show tables;
select * from employees where salary > 40000;
EOF
运行:
[devalone@devalone 25]$ ./mtest2.sh
Enter password:
Tables_in_mytest
employees
empid lastname firstname salary
2 Blum Barbara 45000
4 Blum Jessica 52340
shell 会将 EOF分隔符之间的所有内容都重定向给 mysql 命令。mysql 命令会执行这些命令行,就像你在提示符下亲自输入的一样。用了这种方法,可以
根据需要向 MySQL 服务器发送任意多条命令。
可以在脚本中使用任何类型的 SQL 命令,如 INSERT 语句。
示例:
[devalone@devalone 25]$ cat mtest3.sh
#!/bin/bash
# send data to the table in the MySQL database
MYSQL=$(which mysql)
if [ $# -ne 4 ]
then
echo "Usage: mtest3 empid lastname firstname salary"
else
statement="INSERT INTO employees VALUES ($1, '$2', '$3', $4)"
$MYSQL mytest -u devalone -p << EOF
$statement
EOF
if [ $? -eq 0 ]
then
echo Data successfully added
else
echo Problem adding data
fi
fi
运行:
[devalone@devalone 25]$ ./mtest3.sh
Usage: mtest3 empid lastname firstname salary
[devalone@devalone 25]$ ./mtest3.sh 5 Blum Jasper 100000
Enter password:
Data successfully added
这个例子演示了使用这种方法的一些注意事项。在指定结束字符串时,它必须是该行唯一的内容,并且该行必须以这个字符串开头。如果将 EOF 文本缩进
以和其余的 if-then 缩进对齐,它就不会起作用了。
注意,在 INSERT语句里,在文本值周围用了单引号,在整个 INSERT 语句周围用了双引号。一定不要弄混引用字符串值的引号和定义脚本变量文本的引号。
还有,使用 $? 特殊变量来测试 mysql 程序的退出状态码的。它有助于判断命令是否成功执行。
2.1.3.3 格式化数据
-----------------------------------------------------------------------------------------------------------------------------------------
mysql 命令的标准输出并不太适合提取数据。如果要对提取到的数据进行处理,需要做一些特别的操作。
提取数据库数据的第一步是将 mysql 命令的输出重定向到一个环境变量中。可以在其他命令中使用输出信息。
示例:
[devalone@devalone 25]$ cat mtest4.sh
#!/bin/bash
# redirecting SQL output to a variable
MYSQL=$(which mysql)
dbs=$($MYSQL mytest -u devalone -p -Bse 'show databases')
for db in $dbs
do
echo $db
done
运行:
[devalone@devalone 25]$ ./mtest4.sh
Enter password:
information_schema
mytest
这个例子在 mysql 程序的命令行上用了两个额外参数。-B 选项指定 mysql 程序工作在批处理模式运行,-s(silent)选项用于禁止输出列标题和格式化
符号。
通过将 mysql 命令的输出重定向到一个变量,此例可以逐步输出每条返回记录里的每个值。
mysql 程序还支持另外一种可扩展标记语言(Extensive Markup Language,XML)的流行格式。这种语言使用和 HTML类似的标签来标识数据名和值。
对于 mysql 程序,可以用 -X 命令行选项来输出。
示例:
[devalone@devalone 25]$ mysql mytest -u devalone -p -X -e 'SELECT * FROM employees WHERE empid=1'
Enter password:
<?xml version="1.0"?>
<resultset statement="SELECT * FROM employees WHERE empid=1
" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<row>
<field name="empid">1</field>
<field name="lastname">Blum</field>
<field name="firstname">Rich</field>
<field name="salary">25000</field>
</row>
</resultset>
2.2 使用 Web
-----------------------------------------------------------------------------------------------------------------------------------------
作为一款于1992年由堪萨斯大学的学生编写的基于文本的浏览器,Lynx 程序的历史几乎和互联网一样悠久。因为该浏览器是基于文本的,所以它可以直接从
终端会话中访问网站,只不过 Web 页面上的那些漂亮图片被替换成了 HTML 文本标签。这样就可以在几乎所有类型的 Linux 终端上浏览互联网了。
Lynx 使用标准键盘按键浏览网页。链接会在Web页面上以高亮文本的形式出现。使用向右方向键可以跟随一个链接到下一个Web页面。
Lynx程序还提供了一个功能,允许将 Web 页面的文本内容转储到 STDOUT 中。这个功能非常适合用来挖掘 Web 页面中包含的数据。
多个知名的搜索引擎利用 lynx 协助工作,如下所示(2014-1-10 统计):
□ Ask.com
□ Baidu (Chinese)
□ Bing
□ Dogpile
□ goo (Japanese)
□ Google
□ Hakia
□ IceRocket
□ Indeed
□ Lexxe
□ Rambler (Russian)
□ Search.com
□ WebCrawler
□ Yahoo!
可见,lynx 的实用价值是非常高的。
2.2.1 安装 Lynx
-----------------------------------------------------------------------------------------------------------------------------------------
尽管 Lynx 程序有点古老,但它的开发仍然很活跃。Lynx 的最新版本是 2018 年7月8日发布的 v2.8.9,新版本 2.9.0 正在研发中。其主页网址:
http://lynx.invisible-island.net/
鉴于 Lynx 在 shell 脚本程序员中十分流行,许多 Linux 发行版都将它作为默认程序安装。如果未安装,使用当前系统的包管理器安装。
下面是 Fedora 24 的安装指令:
[devalone@devalone ~]$ sudo dnf install lynx
2.2.2 lynx 命令行
-----------------------------------------------------------------------------------------------------------------------------------------
lynx 命令行命令极其擅长从远程网站上提取信息。当用浏览器查看 Web页面时,只是看到了传送到浏览器中信息的一部分。Web页面由三种类型的数据组成:
□ HTTP头部
□ cookie
□ HTML内容
HTTP 头部提供了连接中传送的数据类型、发送数据的服务器以及采用的连接安全类型的相关信息。如果发送的是特殊类型的数据,比如视频或音频剪辑,
服务器会将其在 HTTP 头部中标示出来。Lynx 程序允许查看 Web 页面会话中发送的所有 HTTP 头部。
网站用 cookie 存储有关网站的访问数据,以供将来使用。每个站点都能存储信息,但只能访问它自己设置的信息。lynx 命令提供了一些选项来查看 Web
服务器发送的 cookie,还可以接受或拒绝服务器发过来的特定 cookie。
Lynx 程序支持三种不同的格式来查看 Web 页面实际的 HTML 内容:
□ 在终端会话中利用 curses 图形库显示文本图形;
□ 文本文件,文件内容是从 Web 页面中转储的原始数据;
□ 文本文件,文件内容是从 Web 页面中转储的原始 HTML 源码。
对于 shell脚本,原始数据或 HTML 源码可是一座金山。一旦获得了从网站上检索到的信息,就能轻松地从中提取每一条信息。
Lynx 程序将它的本职工作发挥到了极致。但随之而来的是复杂性,尤其是对命令行参数来说。Lynx 程序是 Linux 世界中较复杂的程序之一。
lynx 命令的基本格式如下:
lynx options [URL | File]
其中 URL 是要连接的 HTTP 或 HTTPS 地址,options 则是一个或多个选项。这些选项可以在 Lynx 与远程网站交互时改变它的行为。许多命令行参数定义
了 Lynx 的行为,可以用来控制全屏模式下的 Lynx,允许在浏览 Web 页面时对其进行定制。
通过 lynx -help 命令获取更完整的帮助信息:
[devalone@devalone wpan123.com]$ lynx -help
USAGE: lynx [options] [file]
Options are:
- receive options and arguments from stdin
-accept_all_cookies
accept cookies without prompting if Set-Cookie handling
is on (off)
-anonymous apply restrictions for anonymous account,
see also -restrictions
-assume_charset=MIMEname
charset for documents that don't specify it
-assume_local_charset=MIMEname
charset assumed for local files
-assume_unrec_charset=MIMEname
use this instead of unrecognized charsets
-auth=id:pw authentication information for protected documents
-base prepend a request URL comment and BASE tag to text/html
outputs for -source dumps
-bibhost=URL local bibp server (default http://bibhost/)
-book use the bookmark page as the startfile (off)
-buried_news toggles scanning of news articles for buried references (on)
-cache=NUMBER NUMBER of documents cached in memory
-case enable case sensitive user searching (off)
-center toggle center alignment in HTML TABLE (off)
-cfg=FILENAME specifies a lynx.cfg file other than the default
-child exit on left-arrow in startfile, and disable save to disk
-child_relaxed exit on left-arrow in startfile (allows save to disk)
-cmd_log=FILENAME log keystroke commands to the given file
-cmd_script=FILENAME
read keystroke commands from the given file
(see -cmd_log)
-connect_timeout=N
set the N-second connection timeout (18000)
-cookie_file=FILENAME
specifies a file to use to read cookies
-cookie_save_file=FILENAME
specifies a file to use to store cookies
-cookies toggles handling of Set-Cookie headers (on)
-core toggles forced core dumps on fatal errors (off)
-crawl with -traversal, output each page to a file
with -dump, format output as with -traversal, but to stdout
-curses_pads uses curses pad feature to support left/right shifting (on)
-debug_partial incremental display stages with MessageSecs delay (off)
-default_colors use terminal default foreground/background colors (on)
-delay=NNN set NNN-second delay at statusline message (0.000)
-display=DISPLAY set the display variable for X exec'ed programs
-display_charset=MIMEname
charset for the terminal output
-dont_wrap_pre inhibit wrapping of text in <pre> when -dump'ing and
-crawl'ing, mark wrapped lines in interactive session (off)
-dump dump the first file to stdout and exit
-editor=EDITOR enable edit mode with specified editor
-emacskeys enable emacs-like key movement (off)
-enable_scrollback
toggles compatibility with comm programs' scrollback
keys (may be incompatible with some curses packages) (off)
-error_file=FILE write the HTTP status code here
-force_empty_hrefless_a
force HREF-less 'A' elements to be empty (close them as
soon as they are seen) (off)
-force_html forces the first document to be interpreted as HTML (off)
-force_secure toggles forcing of the secure flag for SSL cookies (off)
-forms_options toggles forms-based vs old-style options menu (on)
-from toggle transmission of From headers (on)
-ftp disable ftp access (off)
-get_data user data for get forms, read from stdin,
terminated by '---' on a line
-head send a HEAD request (off)
-help print this usage message
-hiddenlinks=[option]
hidden links: options are merge, listonly, or ignore
-historical toggles use of '>' or '-->' as terminator for comments (off)
-homepage=URL set homepage separate from start page
-html5_charsets toggles use of HTML5 charset replacements (off)
-image_links toggles inclusion of links for all images (off)
-index=URL set the default index file to URL
-ismap toggles inclusion of ISMAP links when client-side
MAPs are present (off)
-justify do justification of text (off)
-link=NUMBER starting count for lnk#.dat files produced by -crawl (0)
-list_inline with -dump, forces it to show links inline with text (off)
-listonly with -dump, forces it to show only the list of links (off)
-localhost disable URLs that point to remote hosts (off)
-lss=FILENAME specifies a lynx.lss file other than the default
-mime_header include mime headers and force source dump
-minimal toggles minimal versus valid comment parsing (on)
-newschunksize=NUMBER
number of articles in chunked news listings
-newsmaxchunk=NUMBER
maximum news articles in listings before chunking
-nobold disable bold video-attribute
-nobrowse disable directory browsing
-nocc disable Cc: prompts for self copies of mailings (off)
-nocolor turn off color support
-nofilereferer disable transmission of Referer headers for file URLs (on)
-nolist disable the link list feature in dumps (off)
-nolog disable mailing of error messages to document owners (on)
-nomargins disable the right/left margins in the default
style-sheet (off)
-nomore disable -more- string in statusline messages
-nonrestarting_sigwinch
make window size change handler non-restarting (off)
-nonumbers disable the link/form numbering feature in dumps (off)
-nopause disable forced pauses for statusline messages
-noprint disable some print functions, like -restrictions=print (off)
-noredir don't follow Location: redirection (off)
-noreferer disable transmission of Referer headers (off)
-noreverse disable reverse video-attribute
-nostatus disable the miscellaneous information messages (off)
-notitle disable the title at the top of each page (off)
-nounderline disable underline video-attribute
-number_fields force numbering of links as well as form input fields (off)
-number_links force numbering of links (off)
-partial toggles display partial pages while downloading (on)
-partial_thres [=NUMBER]
number of lines to render before repainting display
with partial-display logic (-1)
-passive-ftp toggles passive ftp connection (on)
-pauth=id:pw authentication information for protected proxy server
-popup toggles handling of single-choice SELECT options via
popup windows or as lists of radio buttons (off)
-post_data user data for post forms, read from stdin,
terminated by '---' on a line
-preparsed show parsed text/html with -source and in source view
to visualize how lynx behaves with invalid HTML (off)
-prettysrc do syntax highlighting and hyperlink handling in source
view (off)
-print enable print functions (DEFAULT), opposite of -noprint (on)
-pseudo_inlines toggles pseudo-ALTs for inlines with no ALT string (on)
-raw toggles default setting of 8-bit character translations
or CJK mode for the startup character set (off)
-realm restricts access to URLs in the starting realm (off)
-read_timeout=N set the N-second read-timeout (18000)
-reload flushes the cache on a proxy server
(only the first document affected) (off)
-restrictions=[options]
use -restrictions to see list
-resubmit_posts toggles forced resubmissions (no-cache) of forms with
method POST when the documents they returned are sought
with the PREV_DOC command or from the History List (off)
-rlogin disable rlogins (off)
-scrollbar toggles showing scrollbar (off)
-scrollbar_arrow toggles showing arrows at ends of the scrollbar (on)
-selective require .www_browsable files to browse directories
-session=FILENAME resumes from specified file on startup and
saves session to that file on exit
-sessionin=FILENAME
resumes session from specified file
-sessionout=FILENAME
saves session to specified file
-short_url enables examination of beginning and end of long URL in
status line (off)
-show_cfg Show `LYNX.CFG' setting (off)
-show_cursor toggles hiding of the cursor in the lower right corner (on)
-show_rate toggles display of transfer rate (on)
-soft_dquotes toggles emulation of the old Netscape and Mosaic
bug which treated '>' as a co-terminator for
double-quotes and tags (off)
-source dump the source of the first file to stdout and exit
-stack_dump disable SIGINT cleanup handler (off)
-startfile_ok allow non-http startfile and homepage with -validate (off)
-stderr write warning messages to standard error when -dump
or -source is used (off)
-stdin read startfile from standard input (off)
-tagsoup use TagSoup rather than SortaSGML parser (off)
-telnet disable telnets (off)
-term=TERM set terminal type to TERM
-tlog toggles use of a Lynx Trace Log for the current
session (on)
-tna turn on "Textfields Need Activation" mode (off)
-trace turns on Lynx trace mode (off)
-trace_mask customize Lynx trace mode (0)
-traversal traverse all http links derived from startfile
-trim_input_fields
trim input text/textarea fields in forms (off)
-underline_links toggles use of underline/bold attribute for links (off)
-underscore toggles use of _underline_ format in dumps (off)
-unique_urls toggles use of unique-urls setting for -dump and -listonly options (off)
-use_mouse turn on mouse support (off)
-useragent=Name set alternate Lynx User-Agent header
-validate accept only http URLs (meant for validation)
implies more restrictions than -anonymous, but
goto is allowed for http and https (off)
-verbose toggles [LINK], [IMAGE] and [INLINE] comments
with filenames of these images (on)
-version print Lynx version information
-vikeys enable vi-like key movement (off)
-width=NUMBER screen width for formatting of dumps (default is 80)
-with_backspaces emit backspaces in output if -dumping or -crawling
(like 'man' does) (off)
-xhtml-parsing enable XHTML 1.0 parsing (off)
2.2.3 Lynx 配置文件
-----------------------------------------------------------------------------------------------------------------------------------------
在正常的浏览环境中,通常会发现有几组命令行参数非常有用。不用每次使用 Lynx 时都在命令行上将这些参数输入一遍,Lynx 提供了一个通用配置文件来
定义 Lynx 的基本行为。
lynx 命令会从配置文件中读取大量的参数设置。默认情况下, 这个文件位于 /usr/local/lib/lynx.cfg,不过有许多 Linux发行版将其改放到了/etc目录
下(/etc/lynx.cfg)(Ubuntu 发行版将 lynx.cfg 放到了 /etc/lynx-curl 目录中)。
使用命令行搜索:
[devalone@devalone ~]$ whereis lynx.cfg
lynx: /usr/bin/lynx /etc/lynx.lss /etc/lynx.cfg /usr/share/man/man1/lynx.1.gz
当前系统 Fedora 24 位于 /etc/lynx.cfg
lynx.cfg 配置文件将相关的参数分组到不同的区域中,这样更容易找到参数。配置文件中条目的格式为:
PARAMETER:value
其中 PARAMETER 是参数的全名(通常都是用大写字母,但也不总是如此),value 是跟参数关联的值。
浏览一下这个文件,会发现许多参数都跟命令行参数类似,比如 ACCEPT_ALL_COOKIES 参数就等同于设置了 -accept_all_cookies 命令行参数。
还有一些配置参数功能类似,但名称不同。FORCE_SSL_COOKIES_SECURE 配置文件参数设置可以用 -force_secure 命令行参数将其覆盖掉。
还有少数配置参数并没有对应的命令行参数。这些值只能在配置文件中设定。
最常见的不能在命令行上设置的配置参数是代理服务器。有些网络(尤其是公司网络)使用代理服务器作为客户端浏览器和目标网站的桥梁。客户端浏览器
不能直接向远程 Web 服务器发送 HTTP 请求,而是必须将它们的请求发到代理服务器上,然后由代理服务器将请求转发给远程 Web服务器,获取结果,再将
结果回传给客户端浏览器。
用来定义代理服务器的配置参数有:
http_proxy:http://some.server.dom:port/
https_proxy:http://some.server.dom:port/
ftp_proxy:http://some.server.dom:port/
gopher_proxy:http://some.server.dom:port/
news_proxy:http://some.server.dom:port/
newspost_proxy:http://some.server.dom:port/
newsreply_proxy:http://some.server.dom:port/
snews_proxy:http://some.server.dom:port/
snewspost_proxy:http://some.server.dom:port/
snewsreply_proxy:http://some.server.dom:port/
nntp_proxy:http://some.server.dom:port/
wais_proxy:http://some.server.dom:port/
finger_proxy:http://some.server.dom:port/
cso_proxy:http://some.server.dom:port/
no_proxy:host.domain.dom
可以为任何 Lynx 支持的网络协议定义不同的代理服务器。NO_PROXY 参数是逗号分隔的网站列表。对于列表中的这些网站,不使用代理服务器而是直接访问。
2.2.4 从 Lynx 中获取数据
-----------------------------------------------------------------------------------------------------------------------------------------
在 shell 脚本中使用 Lynx 时,大多数情况下只是要提取 Web页面中的某条(或某几条)特定信息。完成这个任务的方法称作屏幕抓取(screen scraping)。
在屏幕抓取过程中,要尝试通过编程寻找图形化屏幕上某个特定位置的数据,这样才能获取它并在脚本中使用。
用 lynx 进行屏幕抓取的最简单办法是用 -dump 选项。这个选项不会在终端屏幕上显示 Web 页面。相反,它会将 Web 页面文本数据直接显示在STDOUT上。
示例: 查看 lynx 帮助主页面
[devalone@devalone ~]$ lynx -dump http://lynx.invisible-island.net/lynx_help/lynx_help_main.html
__________________________________________________________________
[1]https://lynx.invisible-island.net/[2]lynx_help/
__________________________________________________________________
* [3](top)
* [4]Lynx Users Guide
* [5]Key-stroke Commands
* [6]Line Editor
* [7]Supported URLs
* About
+ [8]Lynx
+ [9]Lynx-Dev
* Configuration
+ [10]by Category
+ [11]by Names
The Lynx Help Page – quick-links and detailed documentation
Lynx help files (usually in your local directories):
These Lynx documents are part of your local configuration:
* [12]Lynx Users Guide — complete account of all Lynx features
* [13]Key-stroke Commands — quick outline of what various keys do
* [14]Line Editor — when entering URLs etc
* [15]Supported URLs — how Lynx handles various types of URL
* [16]About Lynx — credits, copyright etc
* [17]About Lynx-Dev — the developers & how to contact them
Other sources of Lynx help:
The Lynx configuration guide may also be local.
* [18]lynx.cfg options — a reference for advanced configurations
* [19]lynx documentation — supplementary documentation
* [20]Lynx Help for Beginners — quick help on many common problems
* [21]Blynx — Speech-Friendly Help for the visually impaired
World Wide Web Consortium documents:
* HTML — [22]5.1 — [23]4.0 — [24]3.2 — [25]3.0 — [26]2.0
* HTTP — [27]1.1 — [28]1.0
* XHTML — [29]1.0
* [30]Web Naming & Addressing Overview: URIs, URLs etc
* [31]HTML Internationalization
* [32]WWW Consortium: home page
Help with HTML:
* [33]HTML 4.0 Reference
* [34]W3Schools
* [35]HTML Goodies
* [36]HTML Code Tutorial
* [37]HTML Cheat Sheet – A Simple Guide to HTML
HTML validation services:
* [38]W3C HTML Validation Service
* [39]WDG HTML Validator
Other browsing software:
* [40]GNU wget — powerful & flexible non-interactive downloader
* [41]Pavuk — powerful & an even more-featured downloader
* [42]cURL — non-interactive downloader which supports HTTPS
* [43]snarf — small simple 1-file non-interactive downloader
Historical interest
* [44]NCSA Mosaic
Search engines:
These work with Lynx as of 2014/01/10:
* [45]Ask.com
* [46]Baidu (Chinese)
* [47]Bing
* [48]Dogpile
* [49]goo (Japanese)
* [50]Google
* [51]Hakia
* [52]IceRocket
* [53]Indeed
* [54]Lexxe
* [55]Rambler (Russian)
* [56]Search.com
* [57]WebCrawler
* [58]Yahoo!
References
Visible links
1. http://lynx.invisible-island.net/
2. http://lynx.invisible-island.net/lynx_help/lynx_help_main.html
3. http://lynx.invisible-island.net/lynx_help/lynx_help_main.html
4. http://lynx.invisible-island.net/lynx_help/Lynx_users_guide.html
5. http://lynx.invisible-island.net/lynx_help/keystrokes/keystroke_help.html
6. http://lynx.invisible-island.net/lynx_help/keystrokes/edit_help.html
7. http://lynx.invisible-island.net/lynx_help/lynx_url_support.html
8. http://lynx.invisible-island.net/lynx_help/about_lynx.html
9. http://lynx.invisible-island.net/lynx_help/lynx-dev.html
10. http://lynx.invisible-island.net/lynx_help/cattoc.html
11. http://lynx.invisible-island.net/lynx_help/alphatoc.html
12. http://lynx.invisible-island.net/lynx_help/Lynx_users_guide.html
13. http://lynx.invisible-island.net/lynx_help/keystrokes/keystroke_help.html
14. http://lynx.invisible-island.net/lynx_help/keystrokes/edit_help.html
15. http://lynx.invisible-island.net/lynx_help/lynx_url_support.html
16. http://lynx.invisible-island.net/lynx_help/about_lynx.html
17. http://lynx.invisible-island.net/lynx_help/lynx-dev.html
18. http://lynx.invisible-island.net/lynx_help/cattoc.html
19. http://lynx.invisible-island.net/lynx_doc/
20. http://www.chass.utoronto.ca/~purslow/lhfb.html
21. http://leb.net/blinux/blynx/
22. http://www.w3.org/TR/html51/
23. http://www.w3.org/TR/REC-html40/
24. http://www.w3.org/TR/REC-html32
25. http://www.w3.org/MarkUp/html3/Contents.html
26. http://www.w3.org/MarkUp/html-spec/html-spec_toc.html
27. http://www.w3.org/Protocols/
28. http://www.isi.edu/in-notes/rfc1945.txt
29. http://www.w3.org/TR/xhtml1/
30. http://www.w3.org/Addressing/
31. http://www.w3.org/International/
32. http://www.w3.org/
33. http://www.htmlhelp.com/reference/html40/
34. http://www.w3schools.com/html/default.asp
35. http://www.htmlgoodies.com/primers/html/
36. http://www.htmlcodetutorial.com/
37. http://www.simplehtmlguide.com/cheatsheet.php
38. http://validator.w3.org/
39. http://www.htmlhelp.com/tools/validator/
40. http://wget.addictivecode.org/
41. http://www.pavuk.org/
42. http://curl.haxx.se/
43. http://www.xach.com/snarf/
44. http://web.archive.org/web/2005050785333/http://archive.ncsa.uiuc.edu/SDG/Software/Mosaic/MetaIndex.html
45. http://www.ask.com/
46. http://www.baidu.com/
47. http://www.bing.com/
48. http://www.dogpile.com/
49. http://labs.goo.ne.jp/
50. http://www.google.com/
51. http://hakia.com/
52. http://www.icerocket.com/
53. http://www.indeed.com/
54. http://www.lexxe.com/
55. http://www.rambler.ru/
56. http://www.search.com/
57. http://www.webcrawler.com/
58. http://www.yahoo.com/
Hidden links:
60. http://lynx.invisible-island.net/lynx_help/lynx_help_main.html
每个链接都由一个标号标定,Lynx 在 Web 页面数据后显示了所有标号所指向的 URL 地址。这正是搜索引擎喜欢 lynx 的原因,有了 URL 列表,抓取内容
就好了。
从 Web页面中获得了所有文本数据之后,可以利用 sed 编辑器和 gawk 程序来提取数据。
首先,找一些有意思的数据来收集。Yahoo!天气页面是找出全世界任何地区当前气候的不错来源。每个位置都用一个单独的 URL 来显示该城市的天气信息
(可以在浏览器中打开该站点并输入你的城市信息来获取所在地的特定 URL)。查看伊利诺伊州芝加哥市的天气情况的 lynx 命令如下:
lynx -dump http://weather.yahoo.com/united-states/illinois/chicago-2379574/ >weather-chicago.txt
这条命令会从页面中转储出很多的数据。第一步是找到需要的准确信息。要做到这点,需将 lynx 命令的输出重定向到一个文件中,本例重定向到文本文件
weather-chicago.txt,然后在文件中查找数据。
查看文件: 利用 cat -n 选项打印出行号,便于处理
[devalone@devalone 25]$ cat -n weather-chicago.txt
1 * Home
2 * [1]Mail
3 * [2]Tumblr
4 * [3]News
5 * [4]Sports
6 * [5]Finance
7 * [6]Entertainment
8 * [7]Lifestyle
9 * [8]Answers
10 * [9]Groups
11 * [10]Mobile
12 * [11]More
13
14 [12]Yahoo
15 Search
16 ____________________
17
18 (BUTTON) Search
19 *
20 *
21
22 The forecast is beautiful
23 Get the App
24
25 My Locations
26
27 Click star button to save cities
28
29 Around the World
30
31 * [13]New York
32 * [14]Los Angeles
33 * [15]Chicago
34 * [16]Houston
35 * [17]Philadelphia
36 * [18]San Francisco
37 * [19]Mexico City
38 * [20]Tokyo
39 * [21]Sao Paulo
40 * [22]London
41 * [23]Paris
42 * [24]Venice
43
44 Chicago
45
46 United States
47 (BUTTON)
48 (BUTTON)
49 Change location
50 Fair Mostly Clear
51 86°
52 67°
53 72°
54 (BUTTON) F (BUTTON) C
55 [25]© by teekay72 on
56
57 Forecast
58
59 [Temperature__]
60 * 12 AM Fair 72°
61 * 1 AM Clear 71°
62 * 2 AM Clear 71°
63 * 3 AM Clear 70°
64 * 4 AM Clear 70°
65 * 5 AM Clear 70°
66 * 6 AM Sunny 71°
67 * 7 AM Sunny 72°
68 * 8 AM Fair 74°
69 * 9 AM Fair 74°
70 * 10 AM Partly Cloudy 75°
71 * 11 AM Partly Cloudy 76°
72 * 12 PM Partly Cloudy 76°
73 * 1 PM Partly Cloudy 76°
74 * 2 PM Fair 76°
75 * 3 PM Fair 75°
76 * 4 PM Sunny 75°
77 * 5 PM Sunny 74°
78 * 6 PM Sunny 73°
79 * 7 PM Sunny 72°
80 * 8 PM Sunny 71°
81 * 9 PM Clear 70°
82 * 10 PM Clear 69°
83 * 11 PM Clear 68°
84 * 12 AM Clear 68°
85
86 Monday
87 Thunderstorms Precipitation: 100% 100%86°67°Night - Clear. Winds
88 variable at 7 to 11 mph (11.3 to 17.7 kph). The overnight low will be
89 70 °F (21.1 °C).Partly cloudy with a high of 76 °F (24.4 °C). Winds
90 variable at 9 to 11 mph (14.5 to 17.7 kph).
91 Tuesday
92 Sunny Precipitation: 0% 0%76°68°Sunny today with a high of 76 °F (24.4
93 °C) and a low of 68 °F (20.0 °C).
94 Wednesday
95 Fair Precipitation: 0% 0%74°66°Mostly sunny today with a high of 74 °F
96 (23.3 °C) and a low of 66 °F (18.9 °C).
97 Thursday
98 Mostly Cloudy Precipitation: 15% 15%80°66°Mostly cloudy today with a
99 high of 80 °F (26.7 °C) and a low of 66 °F (18.9 °C).
100 Friday
101 Thunderstorms Precipitation: 25% 25%80°71°Thunderstorms today with a
102 high of 80 °F (26.7 °C) and a low of 71 °F (21.7 °C). There is a 25%
103 chance of precipitation.
104 Saturday
105 Partly Cloudy Precipitation: 15% 15%77°69°Partly cloudy today with a
106 high of 77 °F (25.0 °C) and a low of 69 °F (20.6 °C).
107 Sunday
108 Partly Cloudy Precipitation: 10% 10%75°69°Partly cloudy today with a
109 high of 75 °F (23.9 °C) and a low of 69 °F (20.6 °C).
110 Monday
111 Partly Cloudy Precipitation: 5% 5%75°69°Partly cloudy today with a high
112 of 75 °F (23.9 °C) and a low of 69 °F (20.6 °C).
113 Tuesday
114 Partly Cloudy Precipitation: 5% 5%81°68°Partly cloudy today with a high
115 of 81 °F (27.2 °C) and a low of 68 °F (20.0 °C).
116 Wednesday
117 Partly Cloudy Precipitation: 5% 5%75°67°Partly cloudy today with a high
118 of 75 °F (23.9 °C) and a low of 67 °F (19.4 °C).
119 (BUTTON) 5 day (BUTTON) 10 day
120
121 Precipitation
122
123 Overnight
124 Early Morning
125 Morning
126 Afternoon
127 Precipitation: 0% 0%
128 Precipitation: 0% 0%
129 Precipitation: 0% 0%
130 Precipitation: 0% 0%
131
132 Wind & Pressure
133
134 Wind
135
136 4 mph NW
137 Barometer
138
139 29.4 inches
140
141 Details
142
143 Fair
144 * Feels like
145 77°
146 * Humidity
147 85%
148 * Visibility
149 10.00 miles
150 * UV Index
151 0 (Low)
152
153 Tonight - Clear. Winds variable at 7 to 11 mph (11.3 to 17.7 kph). The
154 overnight low will be 70 °F (21.1 °C).
155
156 Today - Partly cloudy with a high of 76 °F (24.4 °C). Winds variable at
157 9 to 11 mph (14.5 to 17.7 kph).
158
159 Sun & Moon
160
161 Waxing Crescent
162 Waxing Crescent
163 5:29 AM8:24 PM
164
165 Map
166
167 Satellite
168 (BUTTON) [spaceball.gif] (BUTTON) [spaceball.gif] (BUTTON)
169 [spaceball.gif]
170 [26]View interactive map
171
172 References
173
174 Visible links
175 1. https://mail.yahoo.com/?.intl=us&.lang=en-US
176 2. https://www.tumblr.com/
177 3. https://www.yahoo.com/news/
178 4. http://sports.yahoo.com/
179 5. http://finance.yahoo.com/
180 6. https://www.yahoo.com/entertainment/
181 7. https://www.yahoo.com/lifestyle/
182 8. https://answers.yahoo.com/
183 9. https://groups.yahoo.com/
184 10. https://mobile.yahoo.com/
185 11. https://everything.yahoo.com/
186 12. https://www.yahoo.com/news/
187 13. https://www.yahoo.com/news/weather/united-states/new-york/new-york-2459115
188 14. https://www.yahoo.com/news/weather/united-states/california/los-angeles-2442047
189 15. https://www.yahoo.com/news/weather/united-states/illinois/chicago-2379574
190 16. https://www.yahoo.com/news/weather/united-states/texas/houston-2424766
191 17. https://www.yahoo.com/news/weather/united-states/pennsylvania/philadelphia-2471217
192 18. https://www.yahoo.com/news/weather/united-states/california/san-francisco-2487956
193 19. https://www.yahoo.com/news/weather/mexico/distrito-federal/mexico-city-116545
194 20. https://www.yahoo.com/news/weather/japan/tokyo-prefecture/tokyo-1118370
195 21. https://www.yahoo.com/news/weather/brazil/sao-paulo/sao-paulo-455827
196 22. https://www.yahoo.com/news/weather/united-kingdom/england/london-44418
197 23. https://www.yahoo.com/news/weather/france/île-de-france/paris-615702
198 24. https://www.yahoo.com/news/weather/italy/veneto/venice-725746
199 25. https://www.flickr.com/photos/42198058@N04/10901600376
200 26. http://weather.com/weather/radar/interactive/l/41.88,-87.63
201
202 Hidden links:
203 28. https://www.yahoo.com/
204 29. https://mail.yahoo.com/?.intl=us&.lang=en-US&.partner=none&.src=weather
205 30. https://mobile.yahoo.com/weather/
其中:
44 Chicago
45
46 United States
47 (BUTTON)
48 (BUTTON)
49 Change location
50 Fair Mostly Clear
51 86°
52 67°
53 72°
是当前的气温和最高最低值,华氏温度值。
下面内容为详细信息:
141 Details
142
143 Fair
144 * Feels like
145 77°
146 * Humidity
147 85%
148 * Visibility
149 10.00 miles
150 * UV Index
151 0 (Low)
这都是需要的关于当前天气的所有信息。但这段输出中有个小问题。数字都是在标题下面一行的。只提取单独的数字有些困难。
解决这一问题的关键是先写一个能查找数据标题的 sed 脚本。找到之后,就可以到正确的行中提取数据了。这个例子中所需要的数据就是那些文本行。只用
sed 脚本就能解决了。如果在同一行中还有其他文本,就需要使用 gawk 工具来过滤出我们需要的数据。
创建一个 sed 脚本打印描述当前天气状况的文本(51,53)。输出芝加哥天气的脚本如下:
[devalone@devalone 25]$ cat sedcond.sed
51,53p
下一步,需要一段 sed 脚本来查找文本Feels Like,并打印出下一行的温度:
[devalone@devalone 25]$ cat sedtemp.sed
145p
现在可以在 shell 脚本中用这两个 sed 脚本。首先将 Web 页面的 lynx 输出放入一个临时文件中,然后对 Web 页面数据使用这两个sed脚本,提取所需的
数据:
[devalone@devalone 25]$ cat weather.sh
#!/bin/bash
# extract the current weather for Chicago, IL
URL="http://weather.yahoo.com/united-states/illinois/chicago-2379574/"
LYNX=$(which lynx)
TMPFILE=$(mktemp tmpXXXXXX)
$LYNX -dump $URL > $TMPFILE
addr=$(cat $TMPFILE | sed -n '44p')
conditions=$(cat $TMPFILE | sed -n -f sedcond.sed)
temp=$(cat $TMPFILE | sed -n -f sedtemp.sed)
rm -f $TMPFILE
echo
echo "Address: $addr"
echo "Current conditions: "
echo "$conditions"
echo The current temp outside is: $temp
运行:
[devalone@devalone 25]$ sh weather.sh
Address: Chicago
Current conditions:
76°
63°
63°
The current temp outside is: 63°
weather.sh 脚本连接到指定城市的Yahoo!天气页面,将 Web 页面保存到一个文件中,提取对应的文本,删除临时文件,然后显示天气信息。这么做的好处
在于,一旦从网站上提取到了数据,就可以随心所欲地处理它,比如创建一个温度表。可以创建一个每天运行的 cron 任务来跟踪当天的温度。
lynx 是一个非常值得深入研究的工具,详细信息访问其官方主页:
http://lynx.invisible-island.net/lynx.html
NOTE:
-------------------------------------------------------------------------------------------------------------------------------------
互联网无时不刻不在发生变化。如果花费了几个小时找到了 Web 页面上数据的精确位置,而几个星期后却发现数据已经不在了,脚本也没法工作了,
不必感到惊讶。重要的是要知道从 Web 页面提取数据的过程。这样就可以将原理运用到任何情形中。
2.3 使用电子邮件
-----------------------------------------------------------------------------------------------------------------------------------------
可用来从 shell 脚本中发送电子邮件的主要工具是 Mailx 程序。不仅可以用它交互地读取和发送消息,还可以用命令行参数指定如何发送消息。
系统上的 mail 命令实际上是 mailx 的符号链接:
[devalone@devalone 25]$ which mail
/usr/bin/mail
[devalone@devalone 25]$ ll /usr/bin/mail
lrwxrwxrwx. 1 root root 5 2月 4 2016 /usr/bin/mail -> mailx
Mailx 程序发送消息的命令行的格式为:
mail [-eIinv] [-a header] [-b addr] [-c addr] [-s subj] to-addr
Mailx 命令行参数
+-------+-----------------------------------------------------------------------------
| 参 数 | 描 述
+-------+-----------------------------------------------------------------------------
| -a | 指定额外的SMTP头部行
+-------+-----------------------------------------------------------------------------
| -b | 给消息增加一个BCC:收件人
+-------+-----------------------------------------------------------------------------
| -c | 给消息增加一个CC:收件人
+-------+-----------------------------------------------------------------------------
| -e | 如果消息为空,不要发送消息
+-------+-----------------------------------------------------------------------------
| -i | 忽略TTY中断信号
+-------+-----------------------------------------------------------------------------
| -I | 强制Mailx以交互模式运行
+-------+-----------------------------------------------------------------------------
| -n | 不要读取/etc/mail.rc启动文件
+-------+-----------------------------------------------------------------------------
| -s | 指定一个主题行
+-------+-----------------------------------------------------------------------------
| -v | 在终端上显示投递细节
+-------+-----------------------------------------------------------------------------
完全可以使用命令行参数来创建整个电子邮件消息。唯一需要添加的就是消息正文。
需要将文本重定向给 mail命令。下面这个简单的例子演示了如何直接在命令行上创建和发送电子邮件消息:
[devalone@devalone 25]$ echo "This is a test message" | mailx -s "Test message" devalone
Mailx 程序将来自 echo 命令的文本作为消息正文发送。这提供了一个从 shell 脚本发送消息的简单途径。
[devalone@devalone 25]$ cat factmail.sh
#!/bin/bash
# mailing the answer to a factorial
MAIL=$(which mailx)
factorial=1
counter=1
read -p "Enter the number: " value
while [ $counter -le $value ]
do
factorial=$[$factorial * $counter]
counter=$[$counter + 1]
done
echo The factorial of $value is $factorial | $MAIL -s "Factorial answer" $USER
echo "The result has been mailed to you."
这段脚本不会假定 Mailx 程序位于标准位置。它使用 which 命令来确定 mail程序在哪里。
在计算出阶乘函数的结果后,shell 脚本使用 mail 命令将这个消息发送到用户自定义的 $USER 环境变量,这应该是运行这个脚本的人。
运行:
[devalone@devalone 25]$ ./factmail.sh
Enter the number: 5
The result has been mailed to you.
在消息正文中只发送一行文本有时会不方便。通常,需要将整个输出作为电子邮件消息发送。这种情况总是可以将文本重定向到临时文件中,然后用 cat
命令将输出重定向给 mail程序。
diskmail 程序用 date命令(采用了特殊格式)得到了当前日期,找到 Mailx程序的位置后创建了一个临时文件。接着用 df 命令显示了当前磁盘空间的
统计信息,并将输出重定向到了那个临时文件。
然后使用第一个命令行参数作为目的地地址,使用当前日期作为邮件主题,将临时文件重定向到 mail命令。在运行这个脚本时,不会看到任何命令行输出。
[devalone@devalone 25]$ ./diskmail.sh devalone
可以通过 mail 命令查看当前用户的邮件,非本文关注内容,此处不做演示。
系列目录:
-----------------------------------------------------------------------------------------------------------------------------------------
参考:
《Linux 命令行与 shell 脚本编程大全》 第 3 版 —— 2016.8(美)Richard Blum Cristine Bresnahan
更多推荐
所有评论(0)