&:将命令放到后台运行:
[root@www ~]# tar -zpcf /tmp/etc.tar.gz /etc &
[1] 8400 <== [job number] PID
[root@www ~]# tar: Removing leading `/' from member names
# 在中括号内的号码为工作号码 (job number),该号码与 bash 的控制有关。
# 后续的 8400 则是这个工作在系统中的 PID。至於后续出现的数据是 tar 运行的数据流,
# 由於我们没有加上数据流重导向,所以会影响画面!不过不会影响前景的操作喔!
但是这样的话stdout 及 stderr都会输出到屏幕上,所以需要数据流重定向:
[root@www ~]# tar -zpcvf /tmp/etc.tar.gz /etc > /tmp/log.txt 2>&1 &
[1] 8429
[root@www ~]#
ctrl-z:将『目前』的工作丢到后台中『暂停』:
[root@www ~]# vi ~/.bashrc
# 在 vi 的一般模式下,按下 [ctrl]-z 这两个按键
[1]+ Stopped vim ~/.bashrc
[root@www ~]# <==顺利取得了前景的操控权!
[root@www ~]# find / -print
....(输出省略)....
# 此时萤幕会非常的忙碌!因为萤幕上会显示所有的档名。请按下 [ctrl]-z 暂停
[2]+ Stopped find / -print
jobs:查看目前后台工作情况:
[root@www ~]# jobs [-lrs]
选项与参数:
-l :除了列出 job number 与命令串之外,同时列出 PID 的号码;
-r :仅列出正在背景 run 的工作;
-s :仅列出正在背景当中暂停 (stop) 的工作。
范例一:观察目前的 bash 当中,所有的工作,与对应的 PID
[root@www ~]# jobs -l
[1]- 10314 Stopped vim ~/.bashrc
[2]+ 10833 Stopped find / -print
其中 + 代表最近被放到背景的工作号码, - 代表最近最后第二个被放置到背景中的工作号码。 而超过最后第三个以后的工作,就不会有 +/- 符号存在了!
fg:将后台工作拿到前台来:
[root@www ~]# fg %jobnumber
选项与参数:
%jobnumber :jobnumber 为工作号码(数字)。注意,那个 % 是可有可无的!
范例一:先以 jobs 观察工作,再将工作取出:
[root@www ~]# jobs
[1]- 10314 Stopped vim ~/.bashrc
[2]+ 10833 Stopped find / -print
[root@www ~]# fg <==默认取出那个 + 的工作,亦即 [2]。立即按下[ctrl]-z
[root@www ~]# fg %1 <==直接规定取出的那个工作号码!再按下[ctrl]-z
[root@www ~]# jobs
[1]+ Stopped vim ~/.bashrc
[2]- Stopped find / -print
bg:让工作在后台下的状态变成运行中:
范例一:一运行 find / -perm +7000 > /tmp/text.txt 后,立刻丢到背景去暂停!
[root@www ~]# find / -perm +7000 > /tmp/text.txt
# 此时,请立刻按下 [ctrl]-z 暂停!
[3]+ Stopped find / -perm +7000 > /tmp/text.txt
范例二:让该工作在背景下进行,并且观察他!!
[root@www ~]# jobs ; bg %3 ; jobs
[1]- Stopped vim ~/.bashrc
[2] Stopped find / -print
[3]+ Stopped find / -perm +7000 > /tmp/text.txt
[3]+ find / -perm +7000 > /tmp/text.txt & <==用 bg%3 的情况!
[1]+ Stopped vim ~/.bashrc
[2] Stopped find / -print
[3]- Running find / -perm +7000 > /tmp/text.txt &
kill:管理后台中的工作(reload、删除等):
[root@www ~]# kill -signal %jobnumber
[root@www ~]# kill -l
选项与参数:
-l :这个是 L 的小写,列出目前 kill 能够使用的讯号 (signal) 有哪些?
signal :代表给予后面接的那个工作什么样的指示罗!用 man 7 signal 可知:
-1 :重新读取一次参数的配置档 (类似 reload);
-2 :代表与由键盘输入 [ctrl]-c 同样的动作;
-9 :立刻强制删除一个工作;
-15:以正常的程序方式终止一项工作。与 -9 是不一样的。
范例一:找出目前的 bash 环境下的背景工作,并将该工作『强制删除』。
[root@www ~]# jobs
[1]+ Stopped vim ~/.bashrc
[2] Stopped find / -print
[root@www ~]# kill -9 %2; jobs
[1]+ Stopped vim ~/.bashrc
[2] Killed find / -print
# 再过几秒你再下达 jobs 一次,就会发现 2 号工作不见了!因为被移除了!
范例:找出目前的 bash 环境下的背景工作,并将该工作『正常终止』掉。
[root@www ~]# jobs
[1]+ Stopped vim ~/.bashrc
[root@www ~]# kill -SIGTERM %1
# -SIGTERM 与 -15 是一样的!您可以使用 kill -l 来查阅!
nohup:上述用&的方法其实是放到shell的后台中,如果这个shell连接断了,工作也就没了。所以如果想把工作放到系统的后台,则需要使用nohup...&:
# 1. 先编辑一支会『睡著 500 秒』的程序:
[root@www ~]# vim sleep500.sh
#!/bin/bash
/bin/sleep 500s
/bin/echo "I have slept 500 seconds."
# 2. 丢到背景中去运行,并且立刻注销系统:
[root@www ~]# chmod a+x sleep500.sh
[root@www ~]# nohup ./sleep500.sh &
[1] 5074
[root@www ~]# nohup: appending output to ‘nohup.out’ <==会告知这个信息!
[root@www ~]# exit
ps -l:仅观察自己的 bash 相关程序:
范例一:将目前属於您自己这次登陆的 PID 与相关资讯列示出来(只与自己的 bash 有关)
[root@www ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 13639 13637 0 75 0 - 1287 wait pts/1 00:00:00 bash
4 R 0 13700 13639 0 77 0 - 1101 - pts/1 00:00:00 ps
各字段解释:
F:代表这个程序旗标 (process flags),说明这个程序的总结权限,常见号码有:
* 若为 4 表示此程序的权限为 root ;
* 若为 1 则表示此子程序仅进行[复制(fork)而没有实际运行(exec)](http://cn.linux.vbird.org/linux_basic/0440processcontrol_3.php#fork_and_exec)。
S:代表这个程序的状态 (STAT),主要的状态有:
R (Running):该程序正在运行中;
S (Sleep):该程序目前正在睡眠状态(idle),但可以被唤醒(signal)。
D :不可被唤醒的睡眠状态,通常这支程序可能在等待 I/O 的情况(ex>列印)
T :停止状态(stop),可能是在工作控制(背景暂停)或除错 (traced) 状态;
Z (Zombie):僵尸状态,程序已经终止但却无法被移除至内存外。
UID/PID/PPID:代表『此程序被该 UID 所拥有/程序的 PID 号码/此程序的父程序 PID 号码』
C:代表 CPU 使用率,单位为百分比;
PRI/NI:Priority/Nice 的缩写,代表此程序被 CPU 所运行的优先顺序,数值越小代表该程序越快被 CPU 运行。详细的 PRI 与 NI 将在[下一小节](http://cn.linux.vbird.org/linux_basic/0440processcontrol_3.php#priority)说明。
ADDR/SZ/WCHAN:都与内存有关,ADDR 是 kernel function,指出该程序在内存的哪个部分,如果是个 running 的程序,一般就会显示『 - 』 / SZ 代表此程序用掉多少内存 / WCHAN 表示目前程序是否运行中,同样的, 若为 - 表示正在运行中。
TTY:登陆者的终端机位置,若为远程登陆则使用动态终端介面 (pts/n);
TIME:使用掉的 CPU 时间,注意,是此程序实际花费 CPU 运行的时间,而不是系统时间;
CMD:就是 command 的缩写,造成此程序的触发程序之命令为何。
ps aux:观察系统所有程序:
范例二:列出目前所有的正在内存当中的程序:
[root@www ~]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 2064 616 ? Ss Mar11 0:01 init [5]
root 2 0.0 0.0 0 0 ? S< Mar11 0:00 [migration/0]
root 3 0.0 0.0 0 0 ? SN Mar11 0:00 [ksoftirqd/0]
.....(中间省略).....
root 13639 0.0 0.2 5148 1508 pts/1 Ss 11:44 0:00 -bash
root 14232 0.0 0.1 4452 876 pts/1 R+ 15:52 0:00 ps aux
root 18593 0.0 0.0 2240 476 ? Ss Mar14 0:00 /usr/sbin/atd
各字段解释:
USER:该 process 属於那个使用者帐号的?
PID :该 process 的程序识别码。
%CPU:该 process 使用掉的 CPU 资源百分比;
%MEM:该 process 所占用的实体内存百分比;
VSZ :该 process 使用掉的虚拟内存量 (Kbytes)
RSS :该 process 占用的固定的内存量 (Kbytes)
TTY :该 process 是在那个终端机上面运行,若与终端机无关则显示 ?,另外, tty1-tty6 是本机上面的登陆者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。
STAT:该程序目前的状态,状态显示与 ps -l 的 S 旗标相同 (R/S/T/Z)
START:该 process 被触发启动的时间;
TIME :该 process 实际使用 CPU 运行的时间。
COMMAND:该程序的实际命令为何?
如果你发现在某个程序的 CMD 后面还接上<defunct> 时,就代表该程序是僵尸程序:
apache 8683 0.0 0.9 83384 9992 ? Z 14:33 0:00 /usr/sbin/httpd <defunct>
top:相对于 ps 是截取一个时间点的程序状态, top 则可以持续侦测程序运行的状态:
范例一:每两秒钟升级一次 top ,观察整体资讯:
[root@www ~]# top -d 2 #下面的数据会两秒刷新一次
top - 17:03:09 up 7 days, 16:16, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 80 total, 1 running, 79 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.5%us, 0.5%sy, 0.0%ni, 99.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 742664k total, 681672k used, 60992k free, 125336k buffers
Swap: 1020088k total, 28k used, 1020060k free, 311156k cached
<==如果加入 k 或 r 时,就会有相关的字样出现在这里喔!
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
14398 root 15 0 2188 1012 816 R 0.5 0.1 0:00.05 top
1 root 15 0 2064 616 528 S 0.0 0.1 0:01.38 init
2 root RT -5 0 0 0 S 0.0 0.0 0:00.00 migration/0
3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
top -p:通过PID指定观察某程序:
范例三:我们自己的 bash PID 可由 $$ 变量取得,请使用 top 持续观察该 PID
[root@www ~]# echo $$
13639 <==就是这个数字!他是我们 bash 的 PID
[root@www ~]# top -d 2 -p 13639
top - 17:31:56 up 7 days, 16:45, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 1 total, 0 running, 1 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.0%sy, 0.0%ni,100.0%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 742664k total, 682540k used, 60124k free, 126548k buffers
Swap: 1020088k total, 28k used, 1020060k free, 311276k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13639 root 15 0 5148 1508 1220 S 0.0 0.2 0:00.18 bash
pstree:以程序树的形式展示程序之间的相关性:
[root@www ~]# pstree [-A|U] [-up]
选项与参数:
-A :各程序树之间的连接以 ASCII 字节来连接;
-U :各程序树之间的连接以万国码的字节来连接。在某些终端介面下可能会有错误;
-p :并同时列出每个 process 的 PID;
-u :并同时列出每个 process 的所属帐号名称。
范例一:列出目前系统上面所有的程序树的相关性:
[root@www ~]# pstree -A
init-+-acpid
|-atd
|-auditd-+-audispd---{audispd} <==这行与底下一行为 auditd 分出来的子程序
| `-{auditd}
|-automount---4*[{automount}] <==默认情况下,相似的程序会以数字显示
....(中间省略)....
|-sshd---sshd---bash---pstree <==就是我们命令运行的那个相依性!
....(底下省略)....
# 注意一下,为了节省版面,所以鸟哥已经删去很多程序了!
范例二:承上题,同时秀出 PID 与 users
[root@www ~]# pstree -Aup
init(1)-+-acpid(4555)
|-atd(18593)
|-auditd(4256)-+-audispd(4258)---{audispd}(4261)
| `-{auditd}(4257)
|-automount(4536)-+-{automount}(4537) <==程序相似但 PID 不同!
| |-{automount}(4538)
| |-{automount}(4541)
| `-{automount}(4544)
....(中间省略)....
|-sshd(4586)---sshd(16903)---bash(16905)---pstree(16967)
....(中间省略)....
|-xfs(4692,xfs) <==因为此程序拥有者并非运行 pstree 者!所以列出帐号
....(底下省略)....
# 在括号 () 内的即是 PID 以及该程序的 owner 喔!不过,由於我是使用
# root 的身份运行此一命令,所以属於 root 的程序就不会显示出来啦!
可以发现,所有的程序都是依附在 init 这支程序底下的。 这支程序的 PID 是一号,因为他是由 Linux 核心所主动呼叫的第一支程序。重新启动 init 就是 reboot 。
之前我们使用了kill命令对进程传递信号,但是需要获取GID或者后台工作的ID。可以使用killall加上 [ 下达命令的名称 ] 完成类似的任务:
[root@www ~]# killall [-iIe] [command name]
选项与参数:
-i :interactive 的意思,互动式的,若需要删除时,会出现提示字节给使用者;
-e :exact 的意思,表示『后面接的 command name 要一致』,但整个完整的命令
不能超过 15 个字节。
-I :命令名称(可能含参数)忽略大小写。
范例一:给予 syslogd 这个命令启动的 PID 一个 SIGHUP 的讯号
[root@www ~]# killall -1 syslogd
# 如果用 ps aux 仔细看一下,syslogd 才是完整的命令名称。但若包含整个参数,
# 则 syslogd -m 0 才是完整的呢!
范例二:强制终止所有以 httpd 启动的程序
[root@www ~]# killall -9 httpd
范例三:依次询问每个 bash 程序是否需要被终止运行!
[root@www ~]# killall -i -9 bash
Kill bash(16905) ? (y/N) n <==这个不杀!
Kill bash(17351) ? (y/N) y <==这个杀掉!
# 具有互动的功能!可以询问你是否要删除 bash 这个程序。要注意,若没有 -i 的参数,
# 所有的 bash 都会被这个 root 给杀掉!包括 root 自己的 bash 喔! ^_^
之前的ps命令中提到两个字段:PRI和NI
[root@www ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 18625 18623 2 75 0 - 1514 wait pts/1 00:00:00 bash
4 R 0 18653 18625 0 77 0 - 1102 - pts/1 00:00:00 ps
两者用来衡量程序的优先级,在每次更新时一般有如下关系:
PRI(new) = PRI(old) + nice
PRI 值越低代表越优先的意思。但是无法直接调节PRI值,只能调节nice值:
nice 值可调整的范围为 -20 ~ 19 ;
root 可随意调整自己或他人程序的 Nice 值,且范围为 -20 ~ 19 ;
一般使用者仅可调整自己程序的 Nice 值,且范围仅为 0 ~ 19 (避免一般用户抢占系统资源);
一般使用者仅可将 nice 值越调越高,例如本来 nice 为 5 ,则未来仅能调整到大於 5;
nice:新运行的命令即给予新的 nice 值:
[root@www ~]# nice [-n 数字] command
选项与参数:
-n :后面接一个数值,数值的范围 -20 ~ 19。
范例一:用 root 给一个 nice 值为 -5 ,用於运行 vi ,并观察该程序!
[root@www ~]# nice -n -5 vi &
[1] 18676
[root@www ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 18625 18623 0 75 0 - 1514 wait pts/1 00:00:00 bash
4 T 0 18676 18625 0 72 -5 - 1242 finish pts/1 00:00:00 vi
4 R 0 18678 18625 0 77 0 - 1101 - pts/1 00:00:00 ps
# 原本的 bash PRI 为 75 ,所以 vi 默认应为 75。不过由於给予 nice 为 -5 ,
# 因此 vi 的 PRI 降低了!但并非降低到 70 ,因为核心还会动态调整!
[root@www ~]# kill -9 %1 <==测试完毕将 vi 关闭
renice:已存在程序的 nice 重新调整
[root@www ~]# renice [number] PID
选项与参数:
PID :某个程序的 ID 啊!
范例一:找出自己的 bash PID ,并将该 PID 的 nice 调整到 10
[root@www ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 18625 18623 0 75 0 - 1514 wait pts/1 00:00:00 bash
4 R 0 18712 18625 0 77 0 - 1102 - pts/1 00:00:00 ps
[root@www ~]# renice 10 18625
18625: old priority 0, new priority 10
[root@www ~]# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 18625 18623 0 85 10 - 1514 wait pts/1 00:00:00 bash
4 R 0 18715 18625 0 87 10 - 1102 - pts/1 00:00:00 ps
注意上述例子:nice 值是可以在父程序 --> 子程序之间传递。
free:观察内存使用情况
uname -a:查阅系统与核心相关信息
netstat:网络监控相关:
[root@www ~]# netstat -[atunlp]
选项与参数:
-a :将目前系统上所有的连线、监听、Socket 数据都列出来
-t :列出 tcp 网络封包的数据
-u :列出 udp 网络封包的数据
-n :不以程序的服务名称,以埠号 (port number) 来显示;
-l :列出目前正在网络监听 (listen) 的服务;
-p :列出该网络服务的程序 PID
范例一:列出目前系统已经创建的网络连线与 unix socket 状态
[root@www ~]# netstat
Active Internet connections (w/o servers) <==与网络较相关的部分
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 132 192.168.201.110:ssh 192.168.:vrtl-vmf-sa ESTABLISHED
Active UNIX domain sockets (w/o servers) <==与本机的程序自己的相关性(非网络)
Proto RefCnt Flags Type State I-Node Path
unix 20 [ ] DGRAM 9153 /dev/log
unix 3 [ ] STREAM CONNECTED 13317 /tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 13233 /tmp/.X11-unix/X0
unix 3 [ ] STREAM CONNECTED 13208 /tmp/.font-unix/fs7100
....(中间省略)....
各字段解释:
与网络相关:
* Proto :网络的封包协议,主要分为 TCP 与 UDP 封包,相关数据请参考[服务器篇](http://cn.linux.vbird.org/linux_server);
* Recv-Q:非由使用者程序连结到此 socket 的复制的总 bytes 数;
* Send-Q:非由远程主机传送过来的 acknowledged 总 bytes 数;
* Local Address :本地端的 IP:port 情况
* Foreign Address:远程主机的 IP:port 情况
* State :连线状态,主要有创建(ESTABLISED)及监听(LISTEN);
与本机相关:
Proto :一般就是 unix 啦;
RefCnt:连接到此 socket 的程序数量;
Flags :连线的旗标;
Type :socket 存取的类型。主要有确认连线的 STREAM 与不需确认的 DGRAM 两种;
State :若为 CONNECTED 表示多个程序之间已经连线创建。
Path :连接到此 socket 的相关程序的路径!或者是相关数据输出的路径。
查找网络后门:
范例二:找出目前系统上已在监听的网络连线及其 PID
[root@www ~]# netstat -tlnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 4566/hpiod
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN 4328/portmap
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN 4597/cupsd
tcp 0 0 0.0.0.0:728 0.0.0.0:* LISTEN 4362/rpc.statd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 4629/sendmail:
tcp 0 0 127.0.0.1:2207 0.0.0.0:* LISTEN 4571/python
tcp 0 0 :::22 :::* LISTEN 4586/sshd
# 除了可以列出监听网络的介面与状态之外,最后一个栏位还能够显示此服务的
# PID 号码以及程序的命令名称喔!例如最后一行的 4586 就是该 PID
范例三:将上述的本地端 127.0.0.1:631 那个网络服务关闭的话?
[root@www ~]# kill -9 4597
[root@www ~]# killall -9 cupsd
dmesg:分析内核产生的信息
/proc/*:其中存储的是内存中的数据:
[root@www ~]# ll /proc
dr-xr-xr-x 5 root root 0 Mar 11 08:46 1
dr-xr-xr-x 5 root root 0 Mar 11 00:46 10
dr-xr-xr-x 5 root root 0 Mar 11 00:46 11
....(中间省略)....
-r--r--r-- 1 root root 0 Mar 20 12:11 uptime
-r--r--r-- 1 root root 0 Mar 20 12:11 version
-r--r--r-- 1 root root 0 Mar 20 12:11 vmstat
-r--r--r-- 1 root root 0 Mar 20 12:11 zoneinfo
各个程序的 PID 都是以目录的型态存在於 /proc 当中。 举例来说,我们启动所运行的第一支程序 init 他的 PID 是 1 , 这个 PID 的所有相关资讯都写入在 /proc/1/*当中:
[root@www ~]# ll /proc/1
dr-xr-xr-x 2 root root 0 Mar 12 11:04 attr
-r-------- 1 root root 0 Mar 17 14:32 auxv
-r--r--r-- 1 root root 0 Mar 17 14:32 cmdline <==就是命令串
-rw-r--r-- 1 root root 0 Mar 17 14:32 coredump_filter
-r--r--r-- 1 root root 0 Mar 17 14:32 cpuset
lrwxrwxrwx 1 root root 0 Mar 17 14:32 cwd -> /
-r-------- 1 root root 0 Mar 17 14:32 environ <==一些环境变量
lrwxrwxrwx 1 root root 0 Mar 17 14:32 exe -> /sbin/init <==实际运行的命令
....(以下省略)....
lsof:列出被程序所开启的文件档名
[root@www ~]# lsof [-aUu] [+d]
选项与参数:
-a :多项数据需要『同时成立』才显示出结果时!
-U :仅列出 Unix like 系统的 socket 文件类型;
-u :后面接 username,列出该使用者相关程序所开启的文件;
+d :后面接目录,亦即找出某个目录底下已经被开启的文件!
范例一:列出目前系统上面所有已经被开启的文件与装置:
[root@www ~]# lsof
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 3,2 4096 2 /
init 1 root rtd DIR 3,2 4096 2 /
init 1 root txt REG 3,2 38620 1426405 /sbin/init
....(底下省略)....
# 注意到了吗?是的,在默认的情况下, lsof 会将目前系统上面已经开启的
# 文件全部列出来~所以,画面多的吓人啊!您可以注意到,第一个文件 init 运行的
# 地方就在根目录,而根目录,嘿嘿!所在的 inode 也有显示出来喔!
范例二:仅列出关於 root 的所有程序开启的 socket 文件
[root@www ~]# lsof -u root -a -U
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
udevd 400 root 3u unix 0xedd4cd40 1445 socket
auditd 4256 root 7u unix 0xedd4c380 9081 socket
audispd 4258 root 0u unix 0xedd4c1e0 9080 socket
# 注意到那个 -a 吧!如果你分别输入 lsof -u root 及 lsof -U ,会有啥资讯?
# 使用 lsof -u root -U 及 lsof -u root -a -U ,呵呵!都不同啦!
# -a 的用途就是在解决同时需要两个项目都成立时啊! ^_^
范例三:请列出目前系统上面所有的被启动的周边装置
[root@www ~]# lsof +d /dev
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root 10u FIFO 0,16 1147 /dev/initctl
udevd 400 root 0u CHR 1,3 1420 /dev/null
udevd 400 root 1u CHR 1,3 1420 /dev/null
udevd 400 root 2u CHR 1,3 1420 /dev/null
# 看吧!因为装置都在 /dev 里面嘛!所以罗,使用搜寻目录即可啊!
范例四:秀出属於 root 的 bash 这支程序所开启的文件
[root@www ~]# lsof -u root | grep bash
bash 20639 root cwd DIR 3,2 4096 648321 /root
bash 20639 root rtd DIR 3,2 4096 2 /
bash 20639 root txt REG 3,2 735004 1199424 /bin/bash
bash 20639 root mem REG 3,2 46680 64873 /lib/libnss_files-2.5.so
....(底下省略)....
pidof:找出某支正在运行的程序的 PID
[root@www ~]# pidof [-sx] program_name
选项与参数:
-s :仅列出一个 PID 而不列出所有的 PID
-x :同时列出该 program name 可能的 PPID 那个程序的 PID
范例一:列出目前系统上面 init 以及 syslogd 这两个程序的 PID
[root@www ~]# pidof init syslogd
1 4286
# 理论上,应该会有两个 PID 才对。上面的显示也是出现了两个 PID 喔。
# 分别是 init 及 syslogd 这两支程序的 PID 啦。
DAC:自主式存取控制,就是依据程序的拥有者与文件资源的 rwx 权限来决定有无存取的能力,其存在的问题为:
root 具有最高的权限:如果不小心某支程序被有心人士取得, 且该程序属於 root 的权限,那么这支程序就可以在系统上进行任何资源的存取!真是要命!
使用者可以取得程序来变更文件资源的存取权限:如果你不小心将某个目录的权限配置为 777 ,由於对任何人的权限会变成 rwx ,因此该目录就会被任何人所任意存取!
MAC:委任式存取控制,即使你是 root ,那么在使用不同的程序时,你所能取得的权限并不一定是 root , 而得要看当时该程序的配置而定。如此一来,我们针对控制的『主体』变成了『程序』而不是使用者。这是SELinux所使用的。
/etc/services:让服务于端口号对应的文件:
[root@www ~]# cat /etc/services
....(前面省略)....
ftp 21/tcp
ftp 21/udp fsp fspd
ssh 22/tcp # SSH Remote Login Protocol
ssh 22/udp # SSH Remote Login Protocol
....(中间省略)....
http 80/tcp www www-http # WorldWideWeb HTTP
http 80/udp www www-http # HyperText Transfer Protocol
....(底下省略)....
# 这个文件的内容是以底下的方式来编排的:
# <daemon name> <port/封包协议> <该服务的说明>
与daemon相关的文件:
/etc/init.d/ :启动脚本放置处
系统上几乎所有的服务启动脚本都放置在这里!事实上这是公认的目录,我们的 CentOS 实际上放置在 /etc/rc.d/init.d/ 啦! 不过还是有配置连结档到 /etc/init.d/ 的!既然这是公认的目录,因此建议您记忆这个目录即可!
/etc/sysconfig/ :各服务的初始化环境配置文件
几乎所有的服务都会将初始化的一些选项配置写入到这个目录下,举例来说,登录档的 syslog 这支 daemon 的初始化配置就写入在 /etc/sysconfig/syslog 这里呢!而网络的配置则写在 /etc/sysconfig/network 这个文件中。 所以,这个目录内的文件也是挺重要的;
etc/xinetd.conf, /etc/xinetd.d/ :super daemon 配置文件
super daemon 的主要配置文件 (其实是默认值) 为 /etc/xinetd.conf ,不过我们上面就谈到了, super daemon 只是一个统一管理的机制,他所管理的其他 daemon 的配置则写在 /etc/xinetd.d/* 里头喔!
/etc/:各服务各自的配置文件
/var/lib/ :各服务产生的数据库
一些会产生数据的服务都会将他的数据写入到 /var/lib/ 目录中。举例来说,数据库管理系统 MySQL 的数据库默认就是写入 /var/lib/mysql/ 这个目录下啦!
/var/run/ :各服务的程序之 PID 记录处
之前提到可以使用讯号 (signal) 来管理程序, 既然 daemon 是程序,所以当然也可以利用 kill 或 killall 来管理啦!不过为了担心管理时影响到其他的程序, 因此 daemon 通常会将自己的 PID 记录一份到 /var/run/ 当中!例如登录文件的 PID 就记录在 /var/run/syslogd.pid 这个文件中。如此一来, /etc/init.d/syslog 就能够简单的管理自己的程序啰。
启动Stand alone的daemon的方法:
可以通过/etc/init.d/*进行启动:
[root@www ~]# /etc/init.d/syslog
用法: /etc/init.d/syslog {start|stop|status|restart|condrestart}
# 什么参数都不加的时候,系统会告诉你可以用的参数有哪些,如上所示。
范例一:观察 syslog 这个 daemon 目前的状态
[root@www ~]# /etc/init.d/syslog status
syslogd (pid 4264) 正在运行...
klogd (pid 4267) 正在运行...
# 代表 syslog 管理两个 daemon ,这两个 daemon 正在运行中啦!
范例二:重新让 syslog 读取一次配置文件
[root@www ~]# /etc/init.d/syslog restart
正在关闭核心记录器: [ 确定 ]
正在关闭系统记录器: [ 确定 ]
正在启动系统记录器: [ 确定 ]
正在启动核心记录器: [ 确定 ]
[root@www ~]# /etc/init.d/syslog status
syslogd (pid 4793) 正在运行...
klogd (pid 4796) 正在运行...
# 因为重新启动过,所以 PID 与第一次观察的值就不一样了!这样了解乎?
也可以用通过service进行启动:
[root@www ~]# service [service name] (start|stop|restart|...)
[root@www ~]# service --status-all
选项与参数:
service name:亦即是需要启动的服务名称,需与 /etc/init.d/ 对应;
start|... :亦即是该服务要进行的工作。
--status-all:将系统所有的 stand alone 的服务状态通通列出来
范例三:重新启动 crond 这支 daemon :
[root@www ~]# service crond restart
[root@www ~]# /etc/init.d/crond restart
# 这两种方法随便你用哪一种来处理都可以!不过鸟哥比较喜欢使用 /etc/init.d/*
范例四:显示出目前系统上面所有服务的运行状态
[root@www ~]# service --status-all
acpid (pid 4536) 正在运行...
anacron 已停止
atd (pid 4694) 正在运行...
....(底下省略)....
启动Super daemon 的方法:
其实 Super daemon 本身也是一支 stand alone 的服务,所以 Super daemon 自己启动的方式与 stand alone 是相同的。但是他所管理的其他 daemon 就不是这样做的。必须要在配置文件中配置为启动该 daemon 才行。配置文件就是 /etc/xinetd.d/* 的所有文件。
首先查看super daemon 所管理的服务是否有启动:
[root@www ~]# grep -i 'disable' /etc/xinetd.d/*
....(前面省略)....
/etc/xinetd.d/rsync: disable = yes
/etc/xinetd.d/tcpmux-server: disable = yes
/etc/xinetd.d/time-dgram: disable = yes
/etc/xinetd.d/time-stream: disable = yes
假设我想要启动如上的 rsync 这个服务:
# 1. 先修改配置文件成为启动的模样:
[root@www ~]# vim /etc/xinetd.d/rsync
# 请将 disable 那一行改成如下的模样 (原本是 yes 改成 no 就对了)
service rsync
{
disable = no
....(后面省略)....
# 2. 重新启动 xinetd 这个服务
[root@www ~]# /etc/init.d/xinetd restart
正在停止 xinetd: [ 确定 ]
正在激活 xinetd: [ 确定 ]
# 3. 观察启动的端口
[root@www ~]# grep 'rsync' /etc/services <==先看看端口是哪一号
rsync 873/tcp # rsync
rsync 873/udp # rsync
[root@www ~]# netstat -tnlp | grep 873
tcp 0 0 0.0.0.0:873 0.0.0.0:* LISTEN 4925/xinetd
# 注意看!启动的服务并非 rsync 喔!而是 xinetd ,因为他要控管 rsync 嘛!
# 若有疑问,一定要去看看图 1.1.1 才行!
也就是说,你先修改 /etc/xinetd.d/底下的配置文件,然后再重新启动 xinetd 就对了!而 xinetd (super daemon)是一个 stand alone 启动的服务!
基本上只要一个服务受到 xinetd 管理,或者是该服务的程序支持 TCP Wrappers 函式的功能时,都可以透过 /etc/hosts.allow, /etc/hosts.deny 来配置防火墙。
TCP Wrappers:是一个基于主机的网络访问控制表。
如何得知一个服务的程序有没有支持 TCP Wrappers :
范例一:测试一下达成 sshd 及 httpd 这两个程序有无支持 TCP Wrappers 的功能
[root@www ~]# ldd $(which sshd httpd)
/usr/sbin/sshd:
libwrap.so.0 => /usr/lib64/libwrap.so.0 (0x00002abcbfaed000)
libpam.so.0 => /lib64/libpam.so.0 (0x00002abcbfcf6000)
....(中间省略)....
/usr/sbin/httpd:
libm.so.6 => /lib64/libm.so.6 (0x00002ad395843000)
libpcre.so.0 => /lib64/libpcre.so.0 (0x00002ad395ac6000)
....(底下省略)....
# 重点在于软件有没有支持 libwrap.so 那个函式库啰
ldd (library dependency discovery) 这个命令可以查询某个程序的动态函式库支持状态。
在此基础上可以配置/etc/hosts.allow,/etc/hosts.deny,格式如下:
<service(program_name)> : <IP, domain, hostname> : <action>
<服务 (亦即程序名称)> : <IP 或领域 或主机名> : < 动作 >
# 上头的 < > 是不存在于配置文件中的喔!
比如限制两个ip的访问rsync服务:
[root@www ~]# vim /etc/hosts.deny
rsync : 127.0.0.100 : deny
rsync : 127.0.0.200 : deny
观察系统启动的网络服务:
范例一:找出目前系统开启的『网络服务』有哪些?
[root@www ~]# netstat -tulp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 www.vbird.tsai:2208 *:* LISTEN 4575/hpiod
tcp 0 0 *:737 *:* LISTEN 4371/rpc.statd
tcp 0 0 *:sunrpc *:* LISTEN 4336/portmap
tcp 0 0 www.vbird.tsai:ipp *:* LISTEN 4606/cupsd
tcp 0 0 www.vbird.tsai:smtp *:* LISTEN 4638/sendmail: acce
tcp 0 0 *:ssh *:* LISTEN 4595/sshd
udp 0 0 *:filenet-tms *:* 4755/avahi-daemon:
....(底下省略)....
# 看一下上头, Local Address 的地方会出现主机名与服务名称的,要记得的是,
# 可以加上 -n 来显示 port number ,而服务名称与 port 对应则在 /etc/services
范例二:找出所有的有监听网络的服务 (包含 socket 状态):
[root@www ~]# netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:2208 0.0.0.0:* LISTEN 4575/hpiod
....(中间省略)....
Active UNIX domain sockets (only servers)
Proto RefCnt Flags Type State I-Node PID/Program name Path
....(中间省略)....
unix 2 [ ACC ] STREAM LISTENING 10624 4701/xfs /tmp/.font-unix/fs7100
unix 2 [ ACC ] STREAM LISTENING 12824 5015/Xorg /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 12770 4932/gdm-binary /tmp/.gdm_socket
....(以下省略)....
# 仔细的瞧一瞧啊,除了原有的网络监听 port 之外,还会有 socket 显示在上面,
# 我们可以清楚的知道有哪些服务被启动呢!
范例三:观察所有的服务状态
[root@www ~]# service --status-all
# 这个命令有趣喔!本章之前有谈过这命令,自行查询啰!
linux常见的登陆文件:
/var/log/cron:
你的 crontab 排程有没有实际被进行? 进行过程有没有发生错误?你的 /etc/crontab 是否撰写正确?在这个登录文件内查询看看。/var/log/dmesg:
记录系统在启动的时候核心侦测过程所产生的各项资讯。由於 CentOS 默认将启动时核心的硬件侦测过程取消显示, 因此额外将数据记录一份在这个文件中;/var/log/lastlog:
可以记录系统上面所有的帐号最近一次登陆系统时的相关资讯。lastlog命令就是利用这个文件的记录资讯来显示的。/var/log/maillog或/var/log/mail/*:
记录邮件的往来资讯,其实主要是记录 sendmail (SMTP 协议提供者) 与 dovecot (POP3 协议提供者) 所产生的信息啦。 SMTP 是发信所使用的通讯协议, POP3 则是收信使用的通讯协议。 sendmail 与 dovecot 则分别是两套达成通讯协议的软件。/var/log/messages:
这个文件相当的重要,几乎系统发生的错误信息 (或者是重要的资讯) 都会记录在这个文件中; 如果系统发生莫名的错误时,这个文件是一定要查阅的登录文件之一。/var/log/secure:
基本上,只要牵涉到『需要输入帐号口令』的软件,那么当登陆时 (不管登陆正确或错误) 都会被记录在此文件中。 包括系统的 login 程序、图形介面登陆所使用的 gdm 程序、 su, sudo 等程序、还有网络连线的 ssh, telnet 等程序, 登陆资讯都会被记载在这里;/var/log/wtmp, /var/log/faillog:
这两个文件可以记录正确登陆系统者的帐号资讯 (wtmp) 与错误登陆时所使用的帐号资讯 (faillog) !last就是读取 wtmp 来显示的, 这对于追踪一般帐号者的使用行为很有帮助!/var/log/httpd/*, /var/log/news/*, /var/log/samba/*:
不同的网络服务会使用它们自己的登录文件来记载它们自己产生的各项信息!上述的目录内则是个别服务所制订的登录文件。
登陆文件的产生:
基本上有两种方式,一种是由软件开发商自行定义写入的登录文件与相关格式, 例如 WWW 软件 apache 就是这样处理的。另一种则是由 Linux distribution 提供的登录文件管理服务来统一管理。 你只要将信息丢给这个服务后,他就会自己分门别类的将各种信息放置到相关的登录文件去。syslogd 这个服务来统一管理登录文件。还有一个klogd是专门记录核心信息的登录文件服务。logrotate (登录文件轮替) 则是用来自动化处理登录文件容量与升级的问题。
syslogd:主要登录系统与网络等服务的信息;
klogd:主要登录核心产生的各项资讯;
logrotate:主要在进行登录文件的轮替功能。
查看syslogd服务是否启动:
[root@www ~]# ps aux | grep syslog
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 4294 0.0 0.0 1716 568 ? Ss Mar31 0:00 syslogd -m 0
# 瞧!确实有启动的!
[root@www ~]# chkconfig --list syslog
syslog 0:off 1:off 2:on 3:on 4:on 5:on 6:off
# 默认情况下,文字介面与图形介面 (3, 5) 都有启动喔!
syslogd的配置文件:/etc/rsyslog.conf 格式如下:
服务名称[.=!]信息等级 信息记录的档名或装置或主机
# 底下以 mail 这个服务产生的 info 等级为例:
mail.info /var/log/maillog_info
# 这一行说明:mail 服务产生的大於等於 info 等级的信息,都记录到
# /var/log/maillog_info 文件中的意思。
可以看到CentOS 5.x 默认的 /etc/rsyslog.conf:
# 来自 CentOS 5.x 的相关数据
[root@www ~]# vim /etc/syslog.conf
1 #kern.* /dev/console
2 *.info;mail.none;news.none;authpriv.none;cron.none /var/log/messages
3 authpriv.* /var/log/secure
4 mail.* -/var/log/maillog
5 cron.* /var/log/cron
6 *.emerg *
7 uucp,news.crit /var/log/spooler
8 local7.* /var/log/boot.log
9 news.=crit /var/log/news/news.crit
10 news.=err /var/log/news/news.err
11 news.notice /var/log/news/news.notice
为了防止登陆文件被黑客删除,可以使用-a属性:
[root@www ~]# chattr +a /var/log/messages
[root@www ~]# lsattr /var/log/messages
-----a------- /var/log/messages
加入了这个属性之后,你的 /var/log/messages 登录文件从此就仅能被添加,而不能被删除,直到 root 以chattr -a /var/log/messages 取消这个 -a 的参数之后,才能被删除或移动。
如何将登陆文件传递到登陆文件服务器上:
服务器端(syslog开启在514端口):
# 1. Server 端:修改 syslogd 的启动配置档,通常在 /etc/sysconfig 内!
[root@www ~]# vim /etc/sysconfig/syslog
# 找到底下这一行:
SYSLOGD_OPTIONS="-m 0"
# 改成底下这样子!
SYSLOGD_OPTIONS="-m 0 -r"
# 2. 重新启动与观察 syslogd 喔!
[root@www ~]# /etc/init.d/syslog restart
[root@www ~]# netstat -lunp | grep syslog
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:514 0.0.0.0:* 13981/syslogd
# 嘿嘿!你的登录文件主机已经配置妥当罗!很简单吧!
客户端在 /etc/syslog.conf 里面新增这样的一行:
[root@www ~]# vim /etc/syslog.conf
*.* @192.168.1.100 #192.168.1.100表示登录文件服务器ip
最后再重启syslog即可。
登陆文件的轮替logrotate是一个cron,在/etc/cron.daily/底下:
$ cd /etc/cron.daily/
$ ls
logrotate
其配置文件在/etc/logrotate.conf和/etc/logrotate.d/中。logrotate.conf 才是主要的参数文件,至于logrotate.d 是一个目录, 该目录里面的所有文件都会被主动的读入 /etc/logrotate.conf 当中来进行。
系统启动的过程:
1. [加载 BIOS 的硬件资讯与进行自我测试,并依据配置取得第一个可启动的装置;](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#process_1)
2. [读取并运行第一个启动装置内 MBR 的 boot Loader (亦即是 grub, spfdisk 等程序);](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#process_2)
3. [依据 boot loader 的配置加载 Kernel ,Kernel 会开始侦测硬件与加载驱动程序;](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#process_3)
4. [在硬件驱动成功后,Kernel 会主动呼叫 init 程序,而 init 会取得 run-level 资讯;](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#startup_init)
5. [init 运行 /etc/rc.d/rc.sysinit 文件来准备软件运行的作业环境 (如网络、时区等);](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#startup_sysinit)
6. [init 运行 run-level 的各个服务之启动 (script 方式);](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#startup_runlevel)
7. [init 运行 /etc/rc.d/rc.local 文件;](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#startup_local)
8. [init 运行终端机模拟程序 mingetty 来启动 login 程序,最后就等待使用者登陆啦;](http://cn.linux.vbird.org/linux_basic/0510osloader_1.php#startup_term)
linux上软件的安装与升级大概分为两类:
直接以原始码透过编译来安装与升级;
直接以编译好的 binary program 来安装与升级。
前者举例:以安装一个软件的Tarball为例:
将 Tarball 由厂商的网页下载下来;
将 Tarball 解开,产生很多的原始码文件;
开始以 gcc 进行原始码的编译 (会产生目标档 object files);
然后以 gcc 进行函式库、主、副程序的连结,以形成主要的 binary file;
将上述的 binary file 以及相关的配置档安装至自己的主机上面。
#上面第 3, 4 步骤当中,我们可以透过 make 这个命令的功能来简化
后者则是通过yum,apt等完成。
md5sum/sha1sum:检查软件/文件的指纹:
[root@www ~]# md5sum/sha1sum [-bct] filename
[root@www ~]# md5sum/sha1sum [--status|--warn] --check filename
选项与参数:
-b :使用 binary 的读档方式,默认为 Windows/DOS 文件型态的读取方式;
-c :检验文件指纹;
-t :以文字型态来读取文件指纹。
范例一:将刚刚的文件下载后,测试看看指纹码
[root@www ~]# wget \
> http://ftp.twaren.net/Linux/CentOS/5.3/isos/i386/CentOS-5.3-i386-netinstall.iso
[root@www ~]# md5sum CentOS-5.3-i386-netinstall.iso
6ae4077a9fc2dcedca96013701bd2a43 CentOS-5.3-i386-netinstall.iso
[root@www ~]# sha1sum CentOS-5.3-i386-netinstall.iso
a0c640ae0c68cc0d9558cf4f8855f24671b3dadb CentOS-5.3-i386-netinstall.iso
# 看!显示的编码是否与上面相同呢?赶紧测试看看!