网上看到一个监控redis内存使用量的脚本,觉得不错,记录一下

#!/bin/sh

USEDMEMORY_77=$(redis-cli -h 192.168.119.77 info memory | grep used_memory_human: | awk -F ':' '{print $2}')
USEDMEMORY_78=$(redis-cli -h 192.168.119.78 info memory | grep used_memory_human: | awk -F ':' '{print $2}')
USEDMEMORY_76=$(redis-cli -h 192.168.119.76 -p 6379 info memory | grep used_memory_human: | awk -F ':' '{print $2}')
USEDMEMORY_117=$(redis-cli -h 192.168.119.118 -p 6379 info memory | grep used_memory_human: | awk -F ':' '{print $2}')
USEDMEMORY_118=$(redis-cli -h 192.168.119.118 -p 7379 info memory | grep used_memory_human: | awk -F ':' '{print $2}')

WARN_COUNT=1
WARM_G=3

MEM_ARR=($USEDMEMORY_77 $USEDMEMORY_78 $USEDMEMORY_76 $USEDMEMORY_117 $USEDMEMORY_118)
IP_ARR=("192.168.119.77:6379" "192.168.119.78:6379" "192.168.119.76:6379" "192.168.119.118:6379" "192.168.119.118:7379")
ARR_LENGTH=${#IP_ARR[@]}

for((i=1;i<$ARR_LENGTH;i++))
do
	data=${MEM_ARR[i]}
	mem_c=$(echo $data |grep 'G'|wc -l)

	if [ "$mem_c" -eq "$WARN_COUNT" ]
	then
		mem=$(echo $data | cut -f 1 -d "G" | cut -f 1 -d ".")
		if [ "$mem" -ge "$WARN_G" ]
		then
                        #这里加入提醒动作
			vmessage="{\"mobile\":[\"134*********\"],\"content\": \"[WARN] redis内存使用量:$mem G , ,Node:${IP_ARR[i]}\"}"
			echo $vmessage
			/opt/monitor/udpclient "*********" "10086" "$vmessage"
		fi
	fi

done

日前看到一个zabbix自动发现tomcat的脚本,发现使用了subprocess模块,遂研究了一番

subprocess是一个用来创建并运行子进程的模块

subprocess.call()
父进程等待子进程完成
返回退出信息(returncode,相当于Linux exit code)

subprocess.check_call()
父进程等待子进程完成
返回0
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性,可用try…except…来检查

subprocess.check_output()
父进程等待子进程完成
返回子进程向标准输出的输出结果
检查退出信息,如果returncode不为0,则举出错误subprocess.CalledProcessError,该对象包含有returncode属性和output属性,output属性为标准输出的输出结果,可用try…except…来检查。

这三个函数的使用方法相类似,下面来以subprocess.call()举例说明:


>>> import subprocess
>>> retcode = subprocess.call(["ls", "-l"])
#和shell中命令ls -a显示结果一样
>>> print retcode
0

将程序名(ls)和所带的参数(-l)一起放在一个表中传递给subprocess.call()

shell默认为False,在Linux下,shell=False时, Popen调用os.execvp()执行args指定的程序;shell=True时,如果args是字符串,Popen直接调用系统的Shell来执行args指定的程序,如果args是一个序列,则args的第一项是定义程序命令字符串,其它项是调用系统Shell时的附加参数。

上面例子也可以写成如下:

>>> retcode = subprocess.call("ls -l",shell=True)

在Windows下,不论shell的值如何,Popen调用CreateProcess()执行args指定的外部程序。如果args是一个序列,则先用list2cmdline()转化为字符串,但需要注意的是,并不是MS Windows下所有的程序都可以用list2cmdline来转化为命令行字符串。

subprocess.Popen()

class Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

实际上,上面的几个函数都是基于Popen()的封装(wrapper)。这些封装的目的在于让我们容易使用子进程。当我们想要更个性化我们的需求的时候,就要转向Popen类,该类生成的对象用来代表子进程。
与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block),举例:

>>> import subprocess
>>> child = subprocess.Popen(['ping','-c','4','blog.linuxeye.com'])
>>> print 'parent process'

从运行结果中看到,父进程在开启子进程之后并没有等待child的完成,而是直接运行print。
对比等待的情况:

>>> import subprocess
>>> child = subprocess.Popen('ping -c4 blog.linuxeye.com',shell=True)
>>> child.wait()
>>> print 'parent process'

从运行结果中看到,父进程在开启子进程之后并等待child的完成后,再运行print。
此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:

child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程

子进程的PID存储在child.pid

二、子进程的文本流控制

子进程的标准输入、标准输出和标准错误如下属性分别表示:

child.stdin
child.stdout
child.stderr

可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),如下2个例子:

>>> import subprocess
>>> child1 = subprocess.Popen(["ls","-l"], stdout=subprocess.PIPE)
>>> print child1.stdout.read(),
#或者child1.communicate()
>>> import subprocess
>>> child1 = subprocess.Popen(["cat","/etc/passwd"], stdout=subprocess.PIPE)
>>> child2 = subprocess.Popen(["grep","0:0"],stdin=child1.stdout, stdout=subprocess.PIPE)
>>> out = child2.communicate()

subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
注意:communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成

其它Popen方法:

Popen.poll()

用于检查子进程是否已经结束。设置并返回returncode属性。

Popen.wait()

等待子进程结束。设置并返回returncode属性。

Popen.send_signal(signal)

向子进程发送信号。

Popen.terminate()

停止(stop)子进程。在windows平台下,该方法将调用Windows API TerminateProcess()来结束子进程。

Popen.kill()

杀死子进程。

Popen.stdin

如果在创建Popen对象是,参数stdin被设置为PIPE,Popen.stdin将返回一个文件对象用于策子进程发送指令。否则返回None。

Popen.stdout

如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。

Popen.stderr

如果在创建Popen对象是,参数stdout被设置为PIPE,Popen.stdout将返回一个文件对象用于策子进程发送指令。否则返回None。

Popen.pid

获取子进程的进程ID。

Popen.returncode

获取进程的返回值。如果进程还没有结束,返回None。

Sysvinit 命令 Systemd 命令 备注
service foo start systemctl start foo.service 用来启动一个服务 (并不会重启现有的)
service foo stop systemctl stop foo.service 用来停止一个服务 (并不会重启现有的)。
service foo restart systemctl restart foo.service 用来停止并启动一个服务。
service foo reload systemctl reload foo.service 当支持时,重新装载配置文件而不中断等待操作。
service foo condrestart systemctl condrestart foo.service 如果服务正在运行那么重启它。
service foo status systemctl status foo.service 汇报服务是否正在运行。
ls /etc/rc.d/init.d/ systemctl list-unit-files –type=service 用来列出可以启动或停止的服务列表。
chkconfig foo on systemctl enable foo.service 在下次启动时或满足其他触发条件时设置服务为启用
chkconfig foo off systemctl disable foo.service 在下次启动时或满足其他触发条件时设置服务为禁用
chkconfig foo systemctl is-enabled foo.service 用来检查一个服务在当前环境下被配置为启用还是禁用。
chkconfig –list systemctl list-unit-files –type=service 输出在各个运行级别下服务的启用和禁用情况
chkconfig foo –list ls /etc/systemd/system/*.wants/foo.service 用来列出该服务在哪些运行级别下启用和禁用。
chkconfig foo –add systemctl daemon-reload 当您创建新服务文件或者变更设置时使用。
telinit 3 systemctl isolate multi-user.target (OR systemctl isolate runlevel3.target OR telinit 3) 改变至多用户运行级别。

TYPE CODE Description Query Error
0 0 Echo Reply——回显应答(Ping应答) x
3 0 Network Unreachable——网络不可达 x
3 1 Host Unreachable——主机不可达 x
3 2 Protocol Unreachable——协议不可达 x
3 3 Port Unreachable——端口不可达 x
3 4 Fragmentation needed but no frag. bit set——需要进行分片但设置不分片比特 x
3 5 Source routing failed——源站选路失败 x
3 6 Destination network unknown——目的网络未知 x
3 7 Destination host unknown——目的主机未知 x
3 8 Source host isolated (obsolete)——源主机被隔离(作废不用) x
3 9 Destination network administratively prohibited——目的网络被强制禁止 x
3 10 Destination host administratively prohibited——目的主机被强制禁止 x
3 11 Network unreachable for TOS——由于服务类型TOS,网络不可达 x
3 12 Host unreachable for TOS——由于服务类型TOS,主机不可达 x
3 13 Communication administratively prohibited by filtering——由于过滤,通信被强制禁止 x
3 14 Host precedence violation——主机越权 x
3 15 Precedence cutoff in effect——优先中止生效 x
4 0 Source quench——源端被关闭(基本流控制)
5 0 Redirect for network——对网络重定向
5 1 Redirect for host——对主机重定向
5 2 Redirect for TOS and network——对服务类型和网络重定向
5 3 Redirect for TOS and host——对服务类型和主机重定向
8 0 Echo request——回显请求(Ping请求) x
9 0 Router advertisement——路由器通告
10 0 Route solicitation——路由器请求
11 0 TTL equals 0 during transit——传输期间生存时间为0 x
11 1 TTL equals 0 during reassembly——在数据报组装期间生存时间为0 x
12 0 IP header bad (catchall error)——坏的IP首部(包括各种差错) x
12 1 Required options missing——缺少必需的选项 x
13 0 Timestamp request (obsolete)——时间戳请求(作废不用) x
14 Timestamp reply (obsolete)——时间戳应答(作废不用) x
15 0 Information request (obsolete)——信息请求(作废不用) x
16 0 Information reply (obsolete)——信息应答(作废不用) x
17 0 Address mask request——地址掩码请求 x
18 0 Address mask reply——地址掩码应答

 

原文:http://www.faqs.org/docs/iptables/icmptypes.html

一直想把站点实现静态化但一直迟迟没动手,天一热就愈发的懒散了

对网站速度是越来越不满意了,今天索性把站点的服务优化了一下,但是感觉没什么效果,于是乎终于下决心用WP Super Cache了,

安装WP Super Cache后提示修改固定连接,但是修改后相关网页404,这是之前网站迁移时留下的小毛病,当时懒没解决,(出来混迟早要还)

是nginx url解析的问题:

#在sever下location之前添加
if (-f $request_filename/index.html){
rewrite (.*) $1/index.html break;
}
if (-f $request_filename/index.php){
rewrite (.*) $1/index.php;
}
if (!-f $request_filename){
rewrite (.*) /index.php;
}

设置完后启用插件,进行如下设置

然后点击更新规则并设置设置过期时间

如果提示“Mod rewrite 模块可能未安装!”
在nginx中添加如下规则

##在 location 下添加
# 如果请求的文件已存在,直接返回
if (-f $request_filename) {
	break;
}
set $supercache_file '';
set $supercache_uri $request_uri;
set $supercache 1;
set $ihttp_host '';
if ($request_method = POST) {
	set $supercache 0;
}
# 仅在访问文章永久链接时使用静态文件,请求中带参数则不使用静态缓存
set $qs 0;
if ($query_string) {
	set $qs 1;
}
# 不过从 twitter, facebook, feedburner 链接点过来的,总是带参数,这些访问仍然可以使用静态文件
if ($query_string ~* "^utm_source=([^&]+)&utm_medium([^&]+)&utm_campaign=([^&]+)(&utm_content=([^&]+))?$") {
	set $qs 0;
	set $supercache_uri $document_uri;
}
#deactivate on high load
if ($qs = 1) {
	set $supercache 0;
}
# 针对已登录用户(发表过评论),可以不静态化。在访问量高峰时可注释掉
if ($http_cookie ~* "comment_author_|wordpress|wp-postpass_" ) {
	set $supercache 0;
}
# 支持移动设备,访问移动版本的网页缓存
if ($http_user_agent ~* '(iphone|ipod|aspen|incognito|webmate|android|dream|cupcake|froyo|blackberry9500|blackberry9520|blackberry9530|blackberry9550|blackberry 9800|webos|s8000|bada)') {
	set $ihttp_host '-mobile';
}
# 指定静态缓存文件的路径
if ($supercache = 0) {
	set $supercache_uri '';
}
if ($supercache_uri ~ ^(.+)$) {
	set $supercache_file /wp-content/cache/supercache/$http_host$1/index${ihttp_host}.html;
}
# 只有当缓存文件存在时,才进行 rewrite
if (-f $document_root$supercache_file) {
	#rewrite ^(.*)$ $supercache_file break;
	rewrite ^ $supercache_file last;
}
# 所有其他请求,转给 wordpress 处理
if (!-e $request_filename) {
	rewrite . /index.php last;
}

OK,完工

停止auditd服务的时候提示失败,有如下提示:

Failed to stop auditd.service: Operation refused, unit auditd.service may be requested by dependency only.
See system logs and ‘systemctl status auditd.service’ for details.

看样子是可能是有依赖关系导致的,查看auditd的服务文件

——————————————————————————————————————————–

[Unit]
Description=Security Auditing Service
DefaultDependencies=no
After=local-fs.target systemd-tmpfiles-setup.service
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
RefuseManualStop=yes
ConditionKernelCommandLine=!audit=0
Documentation=man:auditd(8) https://people.redhat.com/sgrubb/audit/

[Service]
ExecStart=/sbin/auditd -n
## To not use augenrules, copy this file to /etc/systemd/system/auditd.service
## and comment/delete the next line and uncomment the auditctl line.
## NOTE: augenrules expect any rules to be added to /etc/audit/rules.d/
ExecStartPost=-/sbin/augenrules –load
#ExecStartPost=-/sbin/auditctl -R /etc/audit/audit.rules
ExecReload=/bin/kill -HUP $MAINPID
# By default we don’t clear the rules on exit. To enable this, uncomment
# the next line after copying the file to /etc/systemd/system/auditd.service
#ExecStopPost=/sbin/auditctl -R /etc/audit/audit-stop.rules

[Install]
WantedBy=multi-user.target

——————————————————————————————————————————–

发现 “RefuseManualStop=yes”这一行。

嗯,居然还有这种操作……

注释掉关闭服务然后禁用开机启动,或者直接禁用开机启动然后重启

CLOSED: 这个没什么好说的了,表示初始状态。

LISTEN: 这个也是非常容易理解的一个状态,表示服务器端的某个SOCKET处于监听状态,可以接受连接了。

SYN_RCVD: 这个状态表示接受到了SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂,基本 上用netstat你是很难看到这种状态的,除非你特意写了一个客户端测试程序,故意将三次TCP握手过程中最后一个ACK报文不予发送。因此这种状态 时,当收到客户端的ACK报文后,它会进入到ESTABLISHED状态。

SYN_SENT: 这个状态与SYN_RCVD遥想呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,因此也随即它会进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

ESTABLISHED:这个容易理解了,表示连接已经建立了。

FIN_WAIT_1: 这个状态要好好解释一下,其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别 是:FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即 进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马 上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。
FIN_WAIT_2:上面已经详细解释了这种状态,实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你,稍后再关闭连接。
TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
CLOSING: 这种状态比较特殊,实际情况中应该是很少见,属于一种比较罕见的例外状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什 么情况下会出现此种情况呢?其实细想一下,也不难得出结论:那就是如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报 文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。
CLOSE_WAIT: 这种状态的含义其实是表示在等待关闭。怎么理解呢?当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对 方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。
LAST_ACK: 这个状态还是比较容易好理解的,它是被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。

参数选项

-a:尝试将网络和广播地址转换成名称;
-c:数据包数目:收到指定的数据包数目后,就停止进行倾倒操作;
-d:把编译过的数据包编码转换成可阅读的格式,并倾倒到标准输出;
-dd:把编译过的数据包编码转换成C语言的格式,并倾倒到标准输出;
-ddd:把编译过的数据包编码转换成十进制数字的格式,并倾倒到标准输出;
-e:在每列倾倒资料上显示连接层级的文件头;
-f:用数字显示网际网络地址;
-F<表达文件>:指定内含表达方式的文件;
-i<网络界面>:使用指定的网络截面送出数据包;
-l:使用标准输出列的缓冲区;(便于利用管道)
-n:不把主机的网络地址转换成名字;
-nn:指定将每个监听到的数据包中的域名转换成IP、端口从应用名称转换成端口号后显示
-N:不列出域名;
-O:不将数据包编码最佳化;
-p:不让网络界面进入混杂模式;
-q :快速输出,仅列出少数的传输协议信息;
-r<数据包文件>:从指定的文件读取数据包数据;
-s<数据包大小>:设置每个数据包的大小;
-S:用绝对而非相对数值列出TCP关联数;
-t:在每列倾倒资料上不显示时间戳记;
-tt: 在每列倾倒资料上显示未经格式化的时间戳记;
-T:数据包类型:强制将表达方式所指定的数据包转译成设置的数据包类型;
-v:详细显示指令执行过程;
-vv:更详细显示指令执行过程;
-x:用十六进制字码列出数据包资料;
-X:把协议头和包内容都原原本本的显示出来,16进制和ASCII
-w<数据包文件>:把数据包数据写入指定的文件。

示例

tcpdump -i eth1
#指定网络接口,默认第一个
tcpdump -i lo
#抓取回环网口的包
tcpdump -n
#以数字显示主机及端口
tcpdump host 192.168.1.52
#截获所有192.168.1.52 的主机收到的和发出的所有的数据包
tcpdump host 192.168.1.52 and \( 192.168.1.53 or 192.168.1.54 \)
#打印192.168.1.52 与 192.168.4.53 或者与 192.168.1.54 之间通信的数据
tcpdump ip host 192.168.1.52 and not 192.168.1.53
#打印192.168.1.52与任何其他主机之间通信的IP 数据包, 但不包括与192.168.1.53之间的数据包
tcpdump -i eth0 src host hostname
#截获主机hostname发送的所有数据
tcpdump -i eth0 dst host hostname
监视所有送到主机hostname的数据包
tcpdump tcp port 23 host 192.168.1.52
获取主机192.168.1.52接收或发出的telnet包
tcpdump udp port 123
#截获本机udp 123端口数据包

tcpdump过滤语法

具体可查看 man pcap-filter

过滤表达式大体可以分成三种过滤条件,“类型”、“方向”和“协议”,这三种条件的搭配组合就构成了我们的过滤表达式。

关于类型的关键字,主要包括host,net,port, 例如 host 210.45.114.211,指定主机 210.45.114.211,net 210.11.0.0 指明210.11.0.0是一个网络地址,port 21 指明

端口号是21。如果没有指定类型,缺省的类型是host.

关于传输方向的关键字,主要包括src , dst ,dst or src, dst and src ,

这些关键字指明了传输的方向。举例说明,src 210.45.114.211 ,指明ip包中源地址是210.45.114.211, dst net 210.11.0.0 指明目的网络地址是210.11.0.0  。如果没有指明

方向关键字,则缺省是srcor dst关键字。

关于协议的关键字,主要包括 ether,ip,ip6,arp,rarp,tcp,udp等类型。这几个的包的协议内容。如果没有指定任何协议,则tcpdump将会监听所有协议的信息包。

如我们只想抓tcp的包命令为: 

sudo tcpdump -i eth0  -nn -c1 'tcp'

除了这三种类型的关键字之外,其他重要的关键字如下:

gateway, broadcast,less,greater,还有三种逻辑运算,取非运算是 ‘not ‘ ‘! ‘, 与运算是’and’,’&&’;或运算是’or’ ,’||’;

可以利用这些关键字进行组合,从而组合为比较强大的过滤条件。下面举例说明

(1)只想查目标机器端口是21或80的网络包,其他端口的我不关注:

sudo tcpdump -i eth0 -c 10 'dst port 21 or dst port 80'

(2) 想要截获主机172.16.0.11 和主机210.45.123.249或 210.45.123.248的通信,使用命令(注意括号的使用):

sudo tcpdump -i eth0 -c 3 'host 172.16.0.11 and (210.45.123.249 or210.45.123.248)'

(3)想获取使用ftp端口和ftp数据端口的网络包

sudo tcpdump 'port ftp or ftp-data'

这里 ftp、ftp-data到底对应哪个端口? linux系统下 /etc/services这个文件里面,就存储着所有知名服务和传输层端口的对应关系。如果你直接把/etc/services里

的ftp对应的端口值从21改为了3333,那么tcpdump就会去抓端口含有3333的网络包了。

(4) 如果想要获取主机172.16.0.11除了和主机210.45.123.249之外所有主机通信的ip包,使用命令:

sudo tcpdump ip ‘host 172.16.0.11 and ! 210.45.123.249’

(5) 抓172.16.0.11的80端口和110和25以外的其他端口的包

sudo tcpdump -i eth0 ‘host 172.16.0.11 and! port 80 and ! port 25 and ! port 110’

高级用法

下面介绍一些tcpdump中过滤语句比较高级的用法

想获取172.16.10.11和google.com之间建立TCP三次握手中带有SYN标记位的网络包.

命令为:

sudo tcpdump -i eth0 'host 172.16.0.11 andhost google.com and tcp[tcpflags]&tcp-syn!=0' -c 3 -nn

语法:  proto [ expr : size]

Proto即protocol的缩写,它表示这里要指定的是某种协议名称,如ip,tcp,udp等。总之可以指定的协议有十多种,如链路层协议 ether,fddi,tr,wlan,ppp,slip,link,

网络层协议ip,ip6,arp,rarp,icmp传输层协议tcp,udp等。

expr用来指定数据报字节单位的偏移量,该偏移量相对于指定的协议层,默认的起始位置是0;而size表示从偏移量的位置开始提取多少个字节,可以设置为

1、2、4,默认为1字节。如果只设置了expr,而没有设置size,则默认提取1个字节。比如ip[2:2],就表示提取出第3、4个字节;而ip[0]则表示提取ip协议头的

第一个字节。在我们提取了特定内容之后,我们就需要设置我们的过滤条件了,我们可用的“比较操作符”包括:>,<,>=,<=,=,!=,总共有6个。 举例:想截取每个TCP会话的起始和结束报文(SYN 和 FIN 报文), 而且会话方中有一个远程主机. [code lang="shell"]sudo tcpdump 'tcp[13] & 3 != 0 and not(src and dst net 172.16.0.0)' -nn[/code] 如果熟悉tcp首部报文格式可以比较容易理解这句话,因为tcp便宜13字节的位置为2位保留位和6位标志位(URG,ACK,PSH,RST,SYN,FIN), 所以与3相与就可以得出 SYN,FIN其中是否一个置位1. 从上面可以看到在写过滤表达式时,需要我们对协议格式比较理解才能把表达式写对。这个比较有难度的..。为了让tcpdump工具更人性化一些,有一些常用的偏移量, 可以通过一些名称来代替,比如icmptype表示ICMP协议的类型域、icmpcode表示ICMP的code域,tcpflags 则表示TCP协议的标志字段域。 更进一步的,对于ICMP的类型域,可以用这些名称具体指代:icmp-echoreply, icmp-unreach, icmp-sourcequench, icmp-redirect,icmp-echo, icmp-routeradvert, icmp-routersolicit, icmp-timxceed, icmp-paramprob,icmp-tstamp, icmp-tstampreply, icmp-ireq, icmp-ireqreply, icmp-maskreq,icmp-maskreply。 而对于TCP协议的标志字段域,则可以细分为tcp-fin, tcp-syn, tcp-rst, tcp-push, tcp-ack, tcp-urg。 对于tcpdump 只能通过经常操作来熟练这些语句了。也可以把网络包用tcpdump截获保存到指定文件,然后用wireshark等可视化软件分析网络包。

在当前shell执行

dd if=/dev/zero of=/tmp/tmp.test bs=4K count=1000000 oflag=direct

新建shell窗口,执行

watch -n 1 pkill -USR1 -x dd

解释:
watch负责周期性执行一个程序,使用-n可以指定执行的时间间隔。
pkill是根据名称或其他属性来查询进程或给进程发信号的。
dd进程的USR1信号:在标准错误输出中输出I/O数据,并继续复制。也就输出了进度

另外,pkill 使用-x参数为精确匹配(match exactly)等同于使用正则^dd$
当然也可使用kill、killall 命令向dd进程发送USR1信号
或者直接写shell脚本循环代替watch命令

while (ps -ef | grep " dd " | grep -v grep | awk '{print $2}' | while read pid; do kill -USR1 $pid; done); do sleep 5; done