分类: Oracle
2009-10-23 17:32:54
2009 年 5 月发表
在本部分中,您将了解如何通过以下常用命令有效地管理 Linux 环境。
ifconfig 命令用于显示在系统中定义的网络接口的详细信息。最常用的选项为 -a,用于显示所有接口。
# ifconfig -a
以太网主接口名称通常为 eth0。要查看某个特定接口(例如 eth0)的详细信息,可以使用:
# ifconfig eth0
下面显示了输出,并提供了解释:
以下是该输出的一些关键部分:
该命令不仅仅用于检查设置;还用于配置和管理接口。下面简要列出了该命令的参数和选项:
up/down — 启用或禁用特定接口。您可以使用 down 参数关闭一个接口(或禁用该接口):
# ifconfig eth0 down
同样,要开启(或启用)该接口,您可以使用:
# ifconfig eth0 up
media — 设置以太网介质的类型,如 10baseT、10 Base 2 等等。常用的介质参数值为 10base2、10baseT 和 AUI。如果您希望 Linux 自动识别介质,可以指定“auto”,如下所示:
# ifconfig eth0 media auto
add — 为接口设置特定的 IP 地址。要将接口 eth0 的 IP 地址设置为 192.168.1.101,可以执行以下命令:
# ifconfig eth0 add 192.168.1.101
netmask — 设置接口的网络掩码参数。在以下示例中,您可以将 eth0 接口的网络掩码设置为 255.255.255.0
# ifconfig eth0 netmask 255.255.255.0
在 Oracle 真正应用集群环境中,您需要使用该命令以特定方式设置网络掩码。
在一些高级配置中,您可以更改分配给网络接口的 MAC 地址。可以使用 hw 参数完成此操作。一般格式如下:
ifconfighw
# ifconfig eth0 hw ether 12.34.56.78.90.12
当您添加一个新网卡(具有一个新的 MAC 地址)而又不想更改 Linux 相关的配置(如网络接口)时,该命令十分有用。
该命令以及下面描述的 nestat 命令是在管理 Oracle RAC 时使用得最广泛的命令之一。Oracle RAC 的性能很大程度上取决于集群节点间的互联。如果互联已饱和(即,不再承载任何额外流量)或者出现故障,您将看到其性能下降。这种情况下,最好查看 ifconfig 输出是否存在故障。以下是一个典型示例:
# ifconfig eth9
eth9 Link encap:Ethernet HWaddr 00:1C:23:CE:6F:82
inet addr:10.14.104.31 Bcast:10.14.104.255 Mask:255.255.255.0
inet6 addr: fe80::21c:23ff:fece:6f82/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:1204285416 errors:0 dropped:560923 overruns:0 frame:0
TX packets:587443664 errors:0 dropped:623409 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1670104239570 (1.5 TiB) TX bytes:42726010594 (39.7 GiB)
Interrupt:169 Memory:f8000000-f8012100
请注意以红色高亮显示的文本。dropped 数非常高;理想情况下,该数值应为 0 或接近于 0。超过五十万的高数值,听起来像是一个丢弃数据包的故障互联,导致互联重新发送数据包 — 这将是问题诊断中的一个线索。
可以通过 netstat 命令访问通过网络接口的输入或输出状态。该命令可以提供网络接口性能的完整信息,具体到套接字级别。示例如下:
# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 prolin1:31027 prolin1:5500 TIME_WAIT
tcp 4 0 prolin1l:1521 applin1:40205 ESTABLISHED
tcp 0 0 prolin1l:1522 prolin1:39957 ESTABLISHED
tcp 0 0 prolin1l:3938 prolin1:31017 TIME_WAIT
tcp 0 0 prolin1l:1521 prolin1:21545 ESTABLISHED
… and so on …
以上输出显示了所有打开的套接字。简单地说,套接字 类似于两个进程间的连接。[请注意:严格地说,“套接字”和“连接”在技术上是不同的。套接字可在无连接时存在。但是,套接字和连接之间的讨论已超出本文所涉及的范围。因此,我只是用通俗易懂的方式表达了该概念。]毫无疑问,连接需要有源和目标,称为本地 和远程 地址。端点可以在同一台服务器上;也可在不同的服务器上。
大多数情况下,程序将连接到同一台服务器。例如,如果两个进程相互进行通信,本地和远程地址将相同,如第一行所示 — 本地和远程地址都是服务器“prolin1”。然而,通过端口 进行通信的进程,其本地和远程地址将是不同的。该端口显示在主机名旁的“:”(冒号)后。用户程序将需要通过套接字发送的数据发送到一个队列中,然后接收方在远端从该队列中进行读取。以下是输出的列:
从外部和本地地址,特别是从端口号,您可能猜到连接与 Oracle 相关,但是如果能确切知道该信息岂不是很好?当然。-p 选项还将显示进程信息:
# netstat -p
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 prolin1:1521 prolin1:33303 ESTABLISHED 1327/oraclePROPRD1
tcp 0 0 prolin1:1521 applin1:51324 ESTABLISHED 13827/oraclePROPRD1
tcp 0 0 prolin1:1521 prolin1:33298 ESTABLISHED 32695/tnslsnr
tcp 0 0 prolin1:1521 prolin1:32544 ESTABLISHED 15251/oracle+ASM
tcp 0 0 prolin1:1521 prolin1:33331 ESTABLISHED 32695/tnslsnr
最后一列清晰地显示了进程 IP 和进程名称,可以确定其为 Oracle 服务器进程、监听器进程以及 ASM 服务器进程。
netstat 命令可以包含各种选项和参数。以下是一些主要选项和参数:
要查看各种接口的网络统计信息,使用 -i 选项。
# netstat -i
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 6860659 0 0 0 2055833 0 0 0 BMRU
eth8 1500 0 2345 0 0 0 833 0 0 0 BMRU
lo 16436 0 14449079 0 0 0 14449079 0 0 0 LRU
这显示了服务器中的不同接口(eth0、eth8 等等)以及与接口相关联的量度。
下一组列(TX-OK、TX-ERR 等等)显示已发送数据的相关统计信息。
Flg 列是接口属性的一个组合值。每个字母代表一个特定的属性。以下是对每个字母的解释。
B — 广播
M — 多播
R — 运行
U — 开启
O — ARP 关闭
P — 点到点连接
L — 环回
m — 主
s — 从
您可以使用 --interface(注意:有两个 连字符,而不是一个)选项显示特定接口的同一信息。
# netstat --interface=eth0
Kernel Interface table
Iface MTU Met RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 0 277903459 0 0 0 170897632 0 0 0 BMsRU
勿庸置疑,输出范围很广泛,很难一目了然。如果要跨接口进行比较,可以使用表格式输出。如果希望以更加易于阅读的格式查看这些值,可以使用 -e 选项生成扩展输出:
# netstat -i -e
Kernel Interface table
eth0 Link encap:Ethernet HWaddr 00:13:72:CC:EB:00
inet addr:10.14.106.0 Bcast:10.14.107.255 Mask:255.255.252.0
inet6 addr: fe80::213:72ff:fecc:eb00/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:6861068 errors:0 dropped:0 overruns:0 frame:0
TX packets:2055956 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:3574788558 (3.3 GiB) TX bytes:401608995 (383.0 MiB)
Interrupt:169
该输出是不是很眼熟?应该是的;它和 ifconfig 的输出是相同的。
如果希望看到输出显示 IP 地址而不是主机名,使用 -n 选项。
-s 选项显示每个协议的统计信息摘要,而不是显示每个连接的详细信息。可以将其与协议特定标志组合。例如,-u 显示与 UDP 协议相关的统计信息。
# netstat -s -u
Udp:
12764104 packets received
600849 packets to unknown port received.
0 packet receive errors
13455783 packets sent
同样,要查看 tcp 的统计信息,可以使用 -t;要查看 raw 的统计信息,可以使用 -r。
真正有用的一个选项是用于显示路由表的 -r 选项。
# netstat -r
Kernel IP routing table
Destination Gateway Genmask Flags MSS Window irtt Iface
10.20.191.0 * 255.255.255.128 U 0 0 0 bond0
172.22.13.0 * 255.255.255.0 U 0 0 0 eth9
169.254.0.0 * 255.255.0.0 U 0 0 0 eth9
default 10.20.191.1 0.0.0.0 UG 0 0 0 bond0
netstat 输出的第二列 Gateway 显示了路由入口点的网关。如果未使用网关,将用星号来表示。第三列 Genmask 显示了路由的“共性”,即,该路由的网络掩码。如果要为一个给定 IP 地址寻找合适的路由,内核将搜索每个路由表条目,在和路由目标进行比较前对地址和网络掩码采取“按位与”操作。
第四列 Flags 显示描述路由的以下标志:
之后的三列显示 MSS、Window 和 irtt,将应用于通过该路由建立的 TCP 连接。
TCP 协议有一个内置的可靠性检查。如果数据包传输失败,将进行重新传输。该协议跟踪数据到达目标并确认接收所需的时间。如果没有在该时间内收到确认,将重新传输数据包。针对该接口设置一次协议在重新传输前需等待的时间(可以更改),该值称为初始往返时间。该值为 0 表示使用默认值。
最后一个字段显示该路由将使用的网络接口。
网络中每个可访问的主机都应有一个 IP 地址,用以在网络中唯一标识该主机。在互联网这样一个大的网络中,连接可以通过 IP 地址访问运行网站(例如 )的服务器。那么,当一台主机(如客户端)希望使用其名称而非 IP 地址连接到另一台主机(如数据库服务器),客户端浏览器如何知道要连接的 IP 地址?
将主机名转换为 IP 地址的机制称为名称解析。在大多数基础级别中,主机都有一个名为 hosts 的特殊文件,用于存储 IP 地址-主机名对。以下是示例文件:
# cat /etc/hosts
# Do not remove the following line, or various programs
# that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
192.168.1.101 prolin1.proligence.com prolin1
192.168.1.102 prolin2.proligence.com prolin2
以上内容表明将主机名 prolin1.proligence.com 转换为 192.168.1.101。IP 地址为 127.0.0.1 的特定条目称为环回条目,通过一个名为 lo 的特定网络接口(您在之前的 ifconfig 和 netstat 命令中见到过)指回服务器自身。
这样很好,但是您不可能将世界上所有的 IP 地址都放入该文件中。应该还有另一种执行名称解析的机制。一个名为“命名服务器”有特殊用途的服务器将扮演这个角色。它就像电话公司提供的电话号码簿;但 不是您的私人电话号码簿。私人网络的内部或外部可能存在多个可用的命名服务器。主机首先将联系一个命名服务器,获取其要访问的目标主机的 IP 地址,然后尝试连接到该 IP 地址。
主机如何知道这些命名服务器是哪些服务器?它将查看一个名为 /etc/resolv.conf 的特定文件来获取该信息。以下是一个示例 resolv 文件。
; generated by /sbin/dhclient-script
search proligence.com
nameserver 10.14.1.58
nameserver 10.14.1.59
nameserver 10.20.223.108
如何确保特定主机名的名称解析工作正常?换句话说,您希望确保当 Linux 系统尝试访问名为 oracle.com 的主机时,它可以在命名服务器上找到该 IP 地址。nslookup 命令可用于完成此操作。以下是其使用方法:
# nslookup oracle.com
Server: 10.14.1.58
Address: 10.14.1.58#53
Non-authoritative answer:
Name: oracle.com
Address: 141.146.8.66
我们来剖析一下输出。Server 输出是该命名服务器的地址。名称 oracle.com 解析为 IP 地址 141.146.8.66。名称由显示在输出中 Server 一词旁边的命名服务器解析。
如果在浏览器中输入该 IP 地址 — 而不是输入 — 浏览器将转至 oracle.com 站点。
如果您输错了,或者查找的主机不正确:
# nslookup oracle-site.com
Server: 10.14.1.58
Address: 10.14.1.58#53
** server can't find oracle-site.com: NXDOMAIN
消息非常明确:该主机不存在。
现在已不推荐使用 nslookup 命令了。取而代之的是一个新的、更强大的命令 — dig(域信息搜索器)。在一些比较新的 Linux 服务器上,nslookup 命令甚至已不可用。
以下是一个示例;要查看主机 oracle.com 的名称解析,可以使用以下命令:
# dig oracle.com
; <<>> DiG 9.2.4 <<>> oracle.com
;; global options: printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62512
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 8, ADDITIONAL: 8
;; QUESTION SECTION:
;oracle.com. IN A
;; ANSWER SECTION:
oracle.com. 300 IN A 141.146.8.66
;; AUTHORITY SECTION:
oracle.com. 3230 IN NS ns1.oracle.com.
oracle.com. 3230 IN NS ns4.oracle.com.
oracle.com. 3230 IN NS u-ns1.oracle.com.
oracle.com. 3230 IN NS u-ns2.oracle.com.
oracle.com. 3230 IN NS u-ns3.oracle.com.
oracle.com. 3230 IN NS u-ns4.oracle.com.
oracle.com. 3230 IN NS u-ns5.oracle.com.
oracle.com. 3230 IN NS u-ns6.oracle.com.
;; ADDITIONAL SECTION:
ns1.oracle.com. 124934 IN A 148.87.1.20
ns4.oracle.com. 124934 IN A 148.87.112.100
u-ns1.oracle.com. 46043 IN A 204.74.108.1
u-ns2.oracle.com. 46043 IN A 204.74.109.1
u-ns3.oracle.com. 46043 IN A 199.7.68.1
u-ns4.oracle.com. 46043 IN A 199.7.69.1
u-ns5.oracle.com. 46043 IN A 204.74.114.1
u-ns6.oracle.com. 46043 IN A 204.74.115.1
;; Query time: 97 msec
;; SERVER: 10.14.1.58#53(10.14.1.58)
;; WHEN: Mon Dec 29 22:05:56 2008
;; MSG SIZE rcvd: 328
在庞大的输出中,有几点是比较突出的。输出表明该命令向命名服务器发送了一条查询,并且该主机收到了从命名服务器返回的响应。名称解析还在某些其他命名服务器(如 ns1.oracle.com)进行。输出表明该查询用时 97 毫秒。
输出有时并不是全部都有用,您可以使用 +short 选项删除那些冗长的无用输出:
# dig +short oracle.com
141.146.8.66
还可以使用 IP 地址从查找 IP 地址转换到查找主机名。可以使用 -x 选项完成该操作。
# dig -x 141.146.8.66
在一个域内查找一个主机时,可以使用 +domain 参数。例如,如果在 oracle.com 域中查找主机 otn,可以使用:
# dig +short otn.oracle.com
也可以使用 +domain 参数:
# dig +short +tcp +domain=oracle.com otn
.
141.146.8.66
应用服务器和数据库服务器之间的连接已建立。SQL*Net 使用的 TNSNAMES.ORA 文件可能如下所示:
prodb3 =
(description =
(address_list =
(address = (protocol = tcp)(host = prolin3)(port = 1521))
)
(connect_data =
(sid = prodb3)
)
)
应用服务器应该可以解析主机名 prolin3。该主机名应该包含在 /etc/hosts 文件内;或者已在 DNS 中定义主机 prolin3。要确保名称解析正常工作并且指向正确的主机,可以使用 dig 命令。
使用这两个命令,您可以处理 Linux 环境中涉及网络的大部分任务。在本部分的余下章节,您将了解如何有效地管理 Linux 环境。
您刚刚登录到服务器,查看一些任务是否运行正常。可能有些进程或所有进程由于关机已终止。可以使用 uptime 命令查看服务器是否确实已重新启动,而不是猜测。该命令将显示自上次重新启动后服务器运行的时长。
# uptime
16:43:43 up 672 days, 17:46, 45 users, load average: 4.45, 5.18, 5.38
该输出显示了很多有用的信息。第一列显示了命令执行的当前时间。第二部分 — up 672 days, 17:46 — 显示了服务器运行的时长。数字 17:46 指明了小时和分钟。因此,该服务器至今为止已经运行了 672 天 17 小时 46 分钟。
下一项 — 45 users — 显示了当前有多少用户登录到服务器。
输出的最后一部分分别显示了服务器在最近 1 分钟、5 分钟以及 15 分钟内的平均负载。术语“平均负载”是根据 CPU 和 I/O 量度决定系统负载的组合分值。平均负载越高,系统负载越高。它并不限定于一个范围;不像百分比上限为固定数字 100。此外,两个系统的平均负载无法进行比较。它是一个将某个系统上的负载量化的数字,只与该系统有关。该输出显示最近 1 分钟内的平均负载是 4.45,最近 5 分钟内的平均负载是 5.18,以此类推。
除 -V(用于显示命令的版本)以外,该命令没有其他选项也不接受其他参数。
# uptime -V
procps version 3.2.3
该命令没有明确的特定于 Oracle 的用法,但您可以查看系统负载来对一些性能问题进行解释。如果发现数据库的一些性能问题并且发现其造成了高 CPU 或高 I/O 负载,您应该立即使用 uptime 命令查看平均负载。如果发现平均负载很高,下一个操作应该是深入查找根本原因。要深入查找根本原因,您应具备 mpstat、iostat 和 sar(在本系列的本部分中有介绍)等工具。
我们来看看以下输出:
# uptime
21:31:04 up 330 days, 7:16, 4 users, load average: 12.90, 1.03, 1.00
非常有趣的是,最近 1 分钟内的平均负载非常高 (12.90),而最近 5 分钟和 15 分钟内的平均负载非常低,甚至无关紧要,分别为 1.03 和 1.00。这表示什么呢?这表示在不到 5 分钟内,某个进程启动造成最后 1 分钟的平均负载剧增。该进程以前未启动,因为之前的平均负载非常小。该分析使我们可以专注于最近几分钟内启动的进程 — 加快解析流程。
当然,由于它显示了该服务器运行的时长,因此它也解释了该实例当时开始启动的原因。
当前哪些用户已登录系统?这是您可能经常会问到的一个问题,尤其是在您发现有错误用户正在运行消耗过多资源的命令时。
who 命令将回答这个问题。以下是最简单的使用,不包含任何参数。
# who
oracle pts/2 Jan 8 15:57 (10.14.105.139)
oracle pts/3 Jan 8 15:57 (10.14.105.139)
root pts/1 Dec 26 13:42 (:0.0)
root :0 Oct 23 15:32
该命令可以有多个选项。-s 选项为默认选项;它将生成与以上相同的输出。
查看该输出,您可能会用尽全力去记住每列的含义。请放松。可以使用 -H 选项显示标题:
# who -H
NAME LINE TIME COMMENT
oracle pts/2 Jan 8 15:57 (10.14.105.139)
oracle pts/3 Jan 8 15:57 (10.14.105.139)
root pts/1 Dec 26 13:42 (:0.0)
root :0 Oct 23 15:32
现在,这些列的意思很明确。NAME 列显示已登录用户的用户名。LINE 显示终端名称。在 Linux 中,每个连接都使用命名惯例 pts/
如果您只是想要一个名称列表而不是所有这些多余的详细信息该如何操作?可以使用 -q 选项完成此操作。它在一行中按字母顺序显示用户名称。它还在末尾显示用户总数(本例中为 45):
# who -q
ananda ananda jsmith klome oracle oracle root root … and so on for 45 names
# users=45
一些用户可能只是登录,但实际上什么都没做。如果您是老板,您会发现该命令非常有用,通过使用 -u 选项,您可以查看他们闲置的时长。
# who -uH
NAME LINE TIME IDLE PID COMMENT
oracle pts/2 Jan 8 15:57 . 18127 (10.14.105.139)
oracle pts/3 Jan 8 15:57 00:26 18127 (10.14.105.139)
root pts/1 Dec 26 13:42 old 6451 (:0.0)
root :0 Oct 23 15:32 ? 24215
新列 IDLE 以 hh:mm 的格式显示了用户闲置的时长。您看到该列中的值“old”了吗?这表示该用户的闲置时间已超过 1 天。PID 列显示了其 shell 连接的进程 ID。
另一个有用的选项是 -b,该选项将显示系统重新启动的时间。
# who -b
system boot Feb 15 13:31
输出显示系统在 2 月 15 日下午 1:31 进行了重新启动。还记得 uptime 命令吗?它还显示系统运行的时长。您可以减去 uptime 中显示的天数,从而得出启动的日期。who -b 命令使该操作变得更简单;它将直接显示启动时间。
非常重要的警告:who -b 命令仅显示月份和日期,而不显示年份。因此,如果该系统已运行超过一年,该输出将不能反映正确的值。因此,uptime 始终是更受欢迎的方法,即使需要做一些计算。示例如下:
# uptime
21:37:49 up 675 days, 22:40, 1 user, load average: 3.35, 3.08, 2.86
# who -b
system boot Mar 7 22:58
注意,启动时间显示为 3 月 7 日。该时间是 2007 年,而不是 2008 年。uptime 显示了正确的时间 — 它已经运行 675 天。如果您不擅长减法,可以使用简单的 SQL 获取 675 天前的日期:
SQL> select sysdate - 675 from dual;
SYSDATE-6
---------
07-MAR-07
-l 选项显示系统的登录信息:
# who -lH
NAME LINE TIME IDLE PID COMMENT
LOGIN tty1 Feb 15 13:32 4081 id=1
LOGIN tty6 Feb 15 13:32 4254 id=6
要查看已关闭的用户终端,使用 -d 选项:
# who -dH
NAME LINE TIME IDLE PID COMMENT EXIT
Feb 15 13:31 489 id=si term=0 exit=0
Feb 15 13:32 2870 id=l5 term=0 exit=0
pts/1 Oct 10 14:53 31869 id=ts/1 term=0 exit=0
pts/4 Jan 11 00:20 22155 id=ts/4 term=0 exit=0
pts/3 Jun 29 16:01 0 id=/3 term=0 exit=0
pts/2 Oct 4 22:35 8371 id=/2 term=0 exit=0
pts/5 Dec 30 03:15 5026 id=ts/5 term=0 exit=0
pts/4 Dec 30 22:35 0 id=/4 term=0 exit=0
有时,init 进程(系统启动时第一个启动的进程)会启动其他进程。-p 选项显示所有活动的登录。
# who -pH
NAME LINE TIME PID COMMENT
Feb 15 13:32 4083 id=2
Feb 15 13:32 4090 id=3
Feb 15 13:32 4166 id=4
Feb 15 13:32 4174 id=5
Feb 15 13:32 4255 id=x
Oct 4 23:14 13754 id=h1
稍后,您将在本部分中了解到 write 命令,使用它可以实现实时消息传递。您还将了解如何禁止其他人向您的终端写入(mseg 命令)。如果想知道哪些用户允许或不允许其他用户向其终端写入,使用 -T 选项:
# who -TH
NAME LINE TIME COMMENT
oracle + pts/2 Jan 11 12:08 (10.23.32.10)
oracle + pts/3 Jan 11 12:08 (10.23.32.10)
oracle - pts/4 Jan 11 12:08 (10.23.32.10)
root + pts/1 Dec 26 13:42 (:0.0)
root ? :0 Oct 23 15:32
终端名称前的 + 号表示该终端接受来自其他用户的写入命令;“-”号表示该终端不允许。该字段中的“?”表示该终端不支持向其写入,例如,X-window 会话。
系统的当前运行级别可通过 -r 选项获取:
# who -rH
NAME LINE TIME IDLE PID COMMENT
run-level 5 Feb 15 13:31 last=S
通过 -a (all) 选项可以获取更详细的列表。该选项组合了 -b -d -l -p -r -t -T -u 选项。因此,这两个命令生成相同的结果:
# who -bdlprtTu
# who -a
以下是一个示例输出(包括标题,以便您可以更清楚地了解各列):
# who -aH
NAME LINE TIME IDLE PID COMMENT EXIT
Feb 15 13:31 489 id=si term=0 exit=0
system boot Feb 15 13:31
run-level 5 Feb 15 13:31 last=S
Feb 15 13:32 2870 id=l5 term=0 exit=0
LOGIN tty1 Feb 15 13:32 4081 id=1
Feb 15 13:32 4083 id=2
Feb 15 13:32 4090 id=3
Feb 15 13:32 4166 id=4
Feb 15 13:32 4174 id=5
LOGIN tty6 Feb 15 13:32 4254 id=6
Feb 15 13:32 4255 id=x
Oct 4 23:14 13754 id=h1
pts/1 Oct 10 14:53 31869 id=ts/1 term=0 exit=0
oracle + pts/2 Jan 8 15:57 . 18127 (10.14.105.139)
oracle + pts/3 Jan 8 15:57 00:18 18127 (10.14.105.139)
pts/4 Dec 30 03:15 5026 id=ts/4 term=0 exit=0
pts/3 Jun 29 16:01 0 id=/3 term=0 exit=0
root + pts/1 Dec 26 13:42 old 6451 (:0.0)
pts/2 Oct 4 22:35 8371 id=/2 term=0 exit=0
root ? :0 Oct 23 15:32 ? 24215
pts/5 Dec 30 03:15 5026 id=ts/5 term=0 exit=0
pts/4 Dec 30 22:35 0 id=/4 term=0 exit=0
要查看自己的登录信息,使用 -m 选项:
# who -m
oracle pts/2 Jan 8 15:57 (10.14.105.139)
看到 pts/2 值了吗?这是终端编号。可以通过 tty 命令查看自己的终端:
# tty
/dev/pts/2
Linux 中有一个用于显示您自身登录信息的特定命令结构 — who am i。它生成和 -m 选项一样的输出。
# who am i
oracle pts/2 Jan 8 15:57 (10.14.105.139)
其他允许的参数是“am i”和“mom likes”(是的,信不信由您)。二者都会生成相同的输出。
随着即时消息传递或聊天程序的出现,我们似乎已经在不受语音通信影响的前提下,解决了无处不在的实时信息交换问题。但是在精致程序领域中就仅仅如此吗?
即时消息传递或聊天概念在 *nix 上已经形成很长时间了。实际上,您是在 Linux 中构建了一个完善、安全的 IM 系统。它使您可以与任何连接到系统的用户进行安全对话;而无需连接互联网。聊天将通过以下命令启动 — write、mesg、wall 和 talk。我们将依次介绍这些命令。
write 命令可以向用户终端进行写入。如果用户登录多个终端,您可以指定一个特定终端。以下是如何向登录到终端“pts/3”的用户“oracle”写入消息“Beware of the virus”:
# write oracle pts/3
Beware of the virus
ttyl
#
按 Control-D 组合键将结束消息,将 shell 提示符 (#) 返回给用户并发送至用户终端。以上消息发送后,用户“oracle”将在终端 pts/3 上看到消息:
Beware of the virus
ttyl
每行将在发送者在每行后按 ENTER 键后出现。发送者按 Control-D 时,标记该传输的结束,接收方将在屏幕上看到 EOF。无论用户的当前操作是什么,都将显示该消息。如果该用户正在使用 vi 编辑文件,该消息出现,用户可以通过按 Control-L 将消息清除。如果用户处在 SQL*Plus 提示符下,该消息仍然会出现但不会影响用户的键盘输入。
如果您觉得这样有所不便而不希望如此,该如何操作?您不希望任何人向您发送消息 — 与“保持电话通话状态”类似。可以通过 mesg 命令完成此操作。该命令将禁止其他用户向您发送消息。该命令若无任何参数,其功能如下:
# mesg
is y
这表明其他人可以向您发送消息。要关闭该功能:
# mesg n
现在,进行确认:
# mesg
is n
当您尝试向用户终端写入时,可能希望知道哪个终端禁止其他用户向其写入。who -T 命令(本部分前面有描述)将显示这一点:
# who -TH
NAME LINE TIME COMMENT
oracle + pts/2 Jan 11 12:08 (10.23.32.10)
oracle + pts/3 Jan 11 12:08 (10.23.32.10)
oracle - pts/4 Jan 11 12:08 (10.23.32.10)
root + pts/1 Dec 26 13:42 (:0.0)
root ? :0 Oct 23 15:32
终端名称前的 + 号表示其接受来自其他用户的 write 命令;“-”号表示不接受。“?”表示该终端不支持向其进行写入,例如,X-window 会话。
如果您希望向所有已登录用户进行写入该如何操作?请使用 wall 命令,而不必向每个用户键入消息:
# wall
hello everyone
发送后,所有已登录用户的终端上将显示以下消息:
Broadcast message from oracle (pts/2) (Thu Jan 8 16:37:25 2009):
hello everyone
这对于 root 用户来说非常有用。如果您想关闭该系统、卸载文件系统或执行类似的管理功能,可能希望所有用户都注销。这时,可以使用该命令向所有用户发送一条消息。
最后,程序 talk 使您可以进行实时交谈。只需键入以下内容:
# talk oracle pts/2
如果您希望与其他服务器 (prolin2) 上的用户交谈,可以使用:
# talk oracle@prolin2 pts/2
这将在其他终端上打开一个聊天窗口,然后,您可以进行实时交谈。这和您现在使用的“专业”聊天程序有什么区别吗?可能没有。顺便说明的是,要进行交谈,您应该确保 talkd daemon 正在运行,您有可能未安装该程序。
是的,这是一个命令,尽管只有一个字母!命令 w 是 uptime 和 who 命令的组合,先执行 uptime 命令,然后立即执行 who 命令。我们来看一下不带任何参数和选项的常见输出。
# w
17:29:22 up 672 days, 18:31, 2 users, load average: 4.52, 4.54, 4.59
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
oracle pts/1 10.14.105.139 16:43 0.00s 0.06s 0.01s w
oracle pts/2 10.14.105.139 17:26 57.00s 3.17s 3.17s sqlplus as sysdba
… and so on …
输出包含两个不同的部分。第一部分显示了 uptime 命令(本部分前面有描述)的输出,显示了服务器运行的时长、已登录用户数以及最近 1 分钟、5 分钟以及 15 分钟内的平均负载。该部分输出已在 uptime 命令下有所解释。输出的第二部分显示带有 -H 选项的 who 命令的输出(同样在本部分中已有所解释)。同样,这些列也在 who 命令下有所解释。
如果不希望显示标题,可以使用 -h 选项。
# w -h
oracle pts/1 10.14.105.139 16:43 0.00s 0.02s 0.01s w -h
这将从输出中删除标题。这在 shell 脚本(在该脚本中,您希望阅读输出并对输出进行操作,而不会产生跳过标题的额外负担)中很有用。
-s 选项将生成输出的精简(简短)版本,删除了登录时间、JPCU 以及 PCPU 时间。
# w -s
17:30:07 up 672 days, 18:32, 2 users, load average: 5.03, 4.65, 4.63
USER TTY FROM IDLE WHAT
oracle pts/1 10.14.105.139 0.00s w -s
oracle pts/2 10.14.105.139 1:42 sqlplus as sysdba
您可能会发现“FROM”字段没什么用处。它显示的是同一台服务器的 IP 地址,因为所有登录都是本地登录。要节省输出的空间,您可能希望取消该列。-f 选项将禁止打印 FROM 字段:
# w -f
17:30:53 up 672 days, 18:33, 2 users, load average: 4.77, 4.65, 4.63
USER TTY LOGIN@ IDLE JCPU PCPU WHAT
oracle pts/1 16:43 0.00s 0.06s 0.00s w -f
oracle pts/2 17:26 2:28 3.17s 3.17s sqlplus as sysdba
该命令仅接受一个参数:用户名称。默认情况下,w 显示所有用户的进程和登录信息。如果您输入一个用户名,将仅显示该用户的登录信息。例如,要仅显示 root 的登录信息,执行以下命令:
# w -h root
root pts/1 :0.0 26Dec08 13days 0.01s 0.01s bash
root :0 - 23Oct08 ?xdm? 21:13m 1.81s /usr/bin/gnome-session
-h 选项用于取消显示标题。
一个进程正在运行,而您希望终止该进程。您应该做些什么?该进程在后台运行,因此无法进入终端并按下 Control-C;或者该进程属于另一用户(使用相同的用户 ID,如“oracle”),而您希望终止它。kill 命令可以帮助您;它的作用和名字一样 — 它终止进程。最常见的用法是:
# kill
如果您希望终止由用户 oracle 执行的 sqlplus 进程,您需要知道其进程 ID 或 PID:
# ps -aef|grep sqlplus|grep ananda
oracle 8728 23916 0 10:36 pts/3 00:00:00 sqlplus
oracle 8768 23896 0 10:36 pts/2 00:00:00 grep sqlplus
现在,终止 PID 8728:
# kill 8728
就是这样!该进程已终止。当然,您需要以同一用户 (oracle) 身份终止由 oracle 启动的进程。要终止由其他用户启动的进程,您需要是超级用户 root。
有时,您可能只想暂停该进程,而不是终止它。可以使用带选项 -SIGSTOP 的 kill 命令。
# kill -SIGSTOP 9790
# ps -aef|grep sqlplus|grep oracle
oracle 9790 23916 0 10:41 pts/3 00:00:00 sqlplus as sysdba
oracle 9885 23896 0 10:41 pts/2 00:00:00 grep sqlplus
这对于后台作业是很好的方法,但对于前台进程,它仅仅停止该进程并删除该用户的控制。因此,如果您在执行以下命令后再次查看该进程:
# ps -aef|grep sqlplus|grep oracle
oracle 9790 23916 0 10:41 pts/3 00:00:00 sqlplus as sysdba
oracle 10144 23896 0 10:42 pts/2 00:00:00 grep sqlplus
您将看到该进程仍在运行。该进程还没有终止。要终止该进程以及任何拒绝终止的固执进程,您需要传递一个名为 SIGKILL 的新信号。默认信号为 SIGTERM。
# kill -SIGKILL 9790
# ps -aef|grep sqlplus|grep oracle
oracle 10092 23916 0 10:42 pts/3 00:00:00 sqlplus as sysdba
oracle 10198 23896 0 10:43 pts/2 00:00:00 grep sqlplus
注意选项 -SIGSTOP 和 -SIGKILL,它们向该进程传递一个特定信号(分别为停止和终止)。同样,您可以使用多个其他信号。要获取所有可用信号的列表,可以使用 -l(此处为字母“L”,而非数字“1”)选项:
# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1
36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5
40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5
60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1
64) SIGRTMAX
您还可以使用与信号等同的数字名称代替实际信号名称。例如,要终止 -SIGKILL 9790,可以使用 kill -9 9790。
顺便说明的是,这是一个很有趣的命令。记住,通常,几乎所有 Linux 命令都可在 /bin、/sbin/、/user/bin 以及类似目录的可执行文件中找到。PATH 可执行文件决定这些命令文件的位置。某些其他命令实际上是“内置”命令,即,是 shell 本身的一部分。kill 就是这样一个示例。要进行演示,执行以下命令:
# kill -h
-bash: kill: h: invalid signal specification
注意从 bash shell 返回的输出。该使用是不正确的,因为不应该带有 -h 参数。现在,使用以下命令:
# /bin/kill -h
usage: kill [ -s signal | -p ] [ -a ] pid ...
kill -l [ signal ]
啊哈!作为 /bin 目录中可执行文件 的此 版本 kill 命令正确接受了选项 -h。现在,您已了解了 shell 内置命令及其可执行文件形式的同名实用程序间的细微差别。
为什么了解区别如此重要?因为这两种形式的功能区别很大。内置 kill 比其实用程序形式功能要少。执行 kill 命令时,您实际上是在调用其内置形式,而非实用程序形式。要添加其他功能,您需要使用 /bin/kill 实用程序。
kill 实用程序具有多个选项和参数。kill 命令最常使用进程名称而不是 PID 终止进程。以下是一个示例,您希望终止所有名称为 sqlplus 的进程:
# /bin/kill sqlplus
[1] Terminated sqlplus
[2] Terminated sqlplus
[3] Terminated sqlplus
[4] Terminated sqlplus
[5] Terminated sqlplus
[6] Terminated sqlplus
[7]- Terminated sqlplus
[8]+ Terminated sqlplus
有时,您可能希望查看 kill 命令将终止的所有进程 ID。-p 选项可以完成该操作。它将打印所有它将会 终止的 PID,而不会真正 不会终止它们。它将作为操作前的确认:
# /bin/kill -p sqlplus
6798
6802
6803
6807
6808
6812
6813
6817
该输出显示将会终止的进程的 PID。如果您不使用 -p 选项重新执行该命令,将终止所有这些进程。
此时,您可能想了解哪些其他命令内置在 shell 中(而不是作为实用程序)。
# man -k builtin
. [builtins] (1) - bash built-in commands, see bash(1)
: [builtins] (1) - bash built-in commands, see bash(1)
[ [builtins] (1) - bash built-in commands, see bash(1)
alias [builtins] (1) - bash built-in commands, see bash(1)
bash [builtins] (1) - bash built-in commands, see bash(1)
bg [builtins] (1) - bash built-in commands, see bash(1)
… and so on …
有些条目看起来似曾相识 — alias、bg 等等。一些只是内置命令,例如 alias。没有名为 alias 的可执行文件。
终止进程有很多用途 — 最常见的是终止迟滞进程、后台中的进程以及其他已停止对普通关闭命令进行响应的进程。例如,Oracle 数据库实例由于一些内存问题无法关闭。您需要通过终止一个关键进程(如 pmon 或 smon)将其关闭。这不应该是经常执行的操作,而应该仅在您别无选择时执行。
您可能希望使用实用程序 kill 命令终止所有 sqlplus 会话或所有 rman 作业。Oracle 企业管理器进程以 perl 进程的形式运行;或者 DBCA 和 DBUA 进程运行,您可能希望尽快将其终止:
# /bin/kill perl rman perl dbca dbua java
该命令还有一个更常用的用途。当您希望终止 Oracle 数据库中的一个用户会话时,您通常会这样做:
我们来看看当我们希望终止用户 SH 的会话时会发生什么。
SQL> select sid, serial#, status
2 from v$session
3* where username = 'SH';
SID SERIAL# STATUS
---------- ---------- --------
116 5784 INACTIVE
SQL> alter system kill session '116,5784'
2 /
System altered.
It’s killed; but when you check the status of the session:
SID SERIAL# STATUS
---------- ---------- --------
116 5784 KILLED
输出显示为 KILLED,而并非完全消失。出现这样的情况是因为 Oracle 等待用户 SH 进入其会话并尝试进行某些操作,在此期间该用户收到消息“ORA-00028:your session has been killed”。之后,该会话将从 V$SESSION 中消失。
一种更快的终止会话的方法是在 Linux 级别终止相关服务器进程。为此,首先应查看该服务器进程的 PID:
SQL> select spid
2 from v$process
3 where addr =
4 (
5 select paddr
6 from v$session
7 where username = 'SH'
8 );
SPID
------------------------
30986
SPID 是该服务器进程的进程 ID。现在,终止该进程:
# kill -9 30986
现在,如果您查看 V$SESSION,它将会立即消失。该用户将不会立即收到消息;但是,如果其尝试执行数据库查询,将收到:
ERROR at line 1:
ORA-03135: connection lost contact
Process ID: 30986
Session ID: 125 Serial number: 34528
这种方法虽然可以更快地终止会话,但也有一些注意事项。Oracle 数据库需要执行一次会话清理 — 回滚更改等。因此,仅可在会话闲置时执行此方法。或者,您可以使用另外两种方法之一立即终止会话:
alter system disconnect session '125,35447' immediate;
alter system disconnect session '125,35447' post_transaction;
不同于 kill 的双重性质,killall 仅是一个实用程序,即,是 /usr/bin 目录中的一个可执行程序。该命令在功能上和 kill 类似,但不是根据 PID 终止进程,而是将进程名称作为一个参数。例如,要终止所有 sqlplus 进程,可执行:
# killall sqlplus
这将终止所有名为 sqlplus 的进程(当然,您需要有进行终止的权限)。与 kill 内置命令不同,您无需知道要终止进程的进程 ID。
如果该命令未终止进程,或者进程未响应 TERM 信号,您可以使用 -s 选项发送一个您在 kill 命令中看到的显式 SIGKILL 信号。
# killall -s SIGKILL sqlplus
与 kill 一样,您可以使用 -9 选项替代 -s SIGKILL。要获得所有可用信号的列表,可以使用 -l 选项。
# killall -l
HUP INT QUIT ILL TRAP ABRT IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM
STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH IO PWR SYS
UNUSED
要获取 killall 命令的详细输出,可使用 -v 选项:
# killall -v sqlplus
Killed sqlplus(26448) with signal 15
Killed sqlplus(26452) with signal 15
Killed sqlplus(26456) with signal 15
Killed sqlplus(26457) with signal 15
… and so on …
有时,您可能会希望在终止进程前对其进行检查。-i 选项使您能够以交互的方式运行进程。此选项将在您终止进程前对输入进行提示:
# killall -i sqlplus
Kill sqlplus(2537) ? (y/n) n
Kill sqlplus(2555) ? (y/n) n
Kill sqlplus(2555) ? (y/n) y
Killed sqlplus(2555) with signal 15
当您传递了错误的进程名称时会发生什么?
# killall wrong_process
wrong_process: no process killed
运行的进程中没有名为 wrong_process 的进程,因此没有任何进程终止,输出也明确地显示了该信息。要取消警告“no process killed”,可使用 -q 选项。该选项在无法在其中分析输出的 shell 脚本中非常方便。而要捕获从命令返回的代码,可执行:
# killall -q wrong_process
# echo $?
1
返回代码(由 shell 变量 $? 显示)为“1”,而不是“0”,表示失败。您可以查看返回代码以检查 killall 进程是否成功,即,返回代码为“0”。
有趣的是,该命令并不能终止其自身。当然,它可以终止其他位置的 killall 命令,但是不能终止其自身。
与 kill 命令一样,killall 命令也用于终止进程。killall 最大的优点是能够显示进程 ID 和交互性特性。如果您希望终止所有 perl、java、sqlplus、rman 以及 dbca 进程,但是要以交互的形式进行;可以执行:
# killall -i -p perl sqlplus java rman dbca
Kill sqlplus(pgid 7053) ? (y/n) n
Kill perl(pgid 31233) ? (y/n) n
... and so on ...
这使您在能够终止进程前查看其 PID,这可能会非常有用。
在本部分中,您了解了以下命令(以字母顺序显示)。
dig |
nslookup 的更新版本 |
ifconfig |
显示有关网络接口的信息 |
kill |
终止特定进程 |
killall |
终止匹配某个模式的特定进程、一组进程以及名称 |
mesg |
打开或关闭其他用户向该终端显示消息的功能。 |
netstat |
显示网络接口使用的统计信息以及其他量度 |
nslookup |
使用主机名查询其 IP 地址或以 IP 地址查询其 DNS 上的主机名 |
talk |
在两个用户之间建立一个即时消息系统以进行实时交谈 |
uptime |
显示系统运行时长及其最近 1 分钟、5 分钟和 15 分钟内的平均负载 |
w |
uptime 和 who 的组合 |
wall |
在所有已登录用户的终端上显示文本信息 |
who |
显示登录到系统的用户及其动态 |
write |
在特定用户的终端会话上即时显示信息 |
正如本文前面所述,我的目的并不是让您了解 Linux 系统中每个可用命令。您只需精通一组能够有效管理系统的命令,而本系列将向您介绍这些最重要的命令。在您的环境中进行练习以熟练掌握这些命令(以及其参数 和选项)。在下一部分也是最后一部分中,您将了解如何在常用设备、虚拟机以及云计算环境中管理 Linux 环境。