1. grep 常用方法与参数
· grep "关键字" 文件名
· grep "关键字" 文件名1 文件名2 ..... //在指定的多个文件中查找关键字
· grep "关键字" * //表示在当前目录下的所有文件中查找
· grep "关键字" * -R //表示在当前目录下查找,如果有子目录则进入到子目录中查找
· grep "正则表达式" * //在文件中按正则表达式查找关键字
· grep -n "关键字" * //显示出关键字在文件中的行号
· grep -c "关键字" * //只打印匹配的行数,不显示匹配的内容。
· grep -v "关键字" 文件名 //选择那些不匹配搜索条件的行
· grep -i "关键字" 文件名 //忽略关键字的大小写
· grep -l "关键字" * //只显示查找到的文件,不显示关键字
2. sed
参考: http://blog.chinaunix.net/u/6889/showart.php?id=1962658
(一)基本知识
·sed -e '编辑指令1' -e '编辑指令2' ... 文件档 //基本格式
一、 -e 表式后边跟的是编辑命令
二、 编辑命令由两部分组成. [address1[,address2]]function[argument] 其中, 位址参数 address1 、address2 为行数或 regular expression 字串 , 表示所执行编辑的资料行 ; 函数参
数 function[argument] 为 sed 的内定函数 , 表示执行的编辑动作。
(二)sed选项
- -n 不打印;s e d不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑)。p命令可以用来打印编辑行。
- -f 如果正在调用s e d脚本文件,使用此选项。此选项通知s e d一个脚本文件支持所有的s e d命令,例如:sed -f myscript.sed input_file,这里m y s c r i p t . s e d即为支持s e d命令的文件。
- -c 下一命令是编辑命令。使用多项编辑时加入此选项。如果只用到一条s e d命令,此选项无用,但指定它也没有关系。
- -i 编辑原文件(此选项慎用,如果使用则原文件就会被修改,无法恢复)。
·sed -e '10d' filename //删除档内第 10 行资料 , 则指令为 10d。
·sed -e '/man/d filename //删除含有 "man" 字串的资料行时 , 则指令为 /man/d。
·sed -e '1,3d' //删除档内第 1 行到第 3 行资料, 则指令为 1,3d。
·sed -e '1,/man/d' filename //删除档内第 1 行到含 "man" 字串的资料行
·sed -e '/man/, 3d' filename //删除档内含 "man"行到第 3 的资料行
·sed -e '/man1/,/man2/d' filename //删除档内第含"man1"行到含 ”man2" 的资料行
(三)编辑命令
- p 打印匹配行
- = 显示文件行号
- a\ 在定位行号后附加新文本信息
- i\ 在定位行号后插入新文本信息
- d 删除定位行
- c\ 用新文本替换定位文本
- s 使用替换模式替换相应模式
- r 从另一个文件中读文本
- w 写文本到一个文件
- q 第一个模式匹配完成后推出或立即推出
- l 显示与八进制A S C I I代码等价的控制字符
- { } 在定位行执行的命令组
- n 从另一个文件中读文本下一行,并附加在下一行
- g 将模式2粘贴到/pattern n/
- y 传送字符
- n 延续到下一输入行;允许跨行的模式匹配语句
·sed -e '5c\
Those must often wipe a bloody nose.
' filename
//将第5行替换为 Those must often wipe a bloody nose. ,其中c后边的"\"是连字符。
·sed -e '1,100c\
How are you?\
data be deleted!
' filename
//将文件中 1 至 100 行的资料区 , 替换成输入的两行。
·sed -e '/man/w filename2' filename1 //搜索man所在行,写到 filename2中
·sed -e '/man/r filename2' filename1 //将filename2中的内容读到man所在行
·sed -i "s/查找的关键字/替换的词/g" 文件名 将文件名中所有关键字替换成指定字符串
3. awk
awk 用法:awk ‘ pattern {action} ‘
變量名 含義
ARGC 命令行變元個數
ARGV 命令行變元數組
FILENAME 當前輸入文件名
FNR 當前文件中的記錄號
FS 輸入域分隔符,默認爲一個空格
RS 輸入記錄分隔符
NF 當前記錄裏域個數
NR 到目前爲止記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
1、
awk ‘/101/’ file 顯示文件file中包含101的匹配行。
awk ‘/101/,/105/’ file
awk ‘$1 == 5′ file
awk ‘$1 == “CT”‘ file 注意必須帶雙引號
awk ‘$1 * $2 >100 ‘ file
awk ‘$2 >5 && $2<=15' file
2、
awk '{print NR,NF,$1,$NF,}' file 顯示文件file的當前記錄號、域數和每一行的第一個和最後一個域。
awk '/101/ {print $1,$2 + 10}' file 顯示文件file的匹配行的第一、二個域加10。
awk '/101/ {print $1$2}' file
awk '/101/ {print $1 $2}' file 顯示文件file的匹配行的第一、二個域,但顯示時域中間沒有分隔符。
3、
df | awk '$4>1000000 ‘ 通過管道符獲得輸入,如:顯示第4個域滿足條件的行。
4、
awk -F “|” ‘{print $1}’ file 按照新的分隔符“|”進行操作。
awk ‘BEGIN { FS=”[: \t|]” } {print $1,$2,$3}’ file 通過設置輸入分隔符(FS=”[: \t|]”)修改輸入分隔符。
Sep=”|”
awk -F $Sep ‘{print $1}’ file 按照環境變量Sep的值做爲分隔符。
awk -F ‘[ :\t|]’ ‘{print $1}’ file 按照正則表達式的值做爲分隔符,這裏代表空格、:、TAB、|同時做爲分隔符。
awk -F ‘[][]’ ‘{print $1}’ file 按照正則表達式的值做爲分隔符,這裏代表[、]
5、
awk -f awkfile file 通過文件awkfile的內容依次進行控制。
cat awkfile /101/{print “\047 Hello! \047″} –遇到匹配行以後打印 ‘ Hello! ‘.\047代表單引號。
{print $1,$2} –因爲沒有模式控制,打印每一行的前兩個域。
6、
awk ‘$1 ~ /101/ {print $1}’ file 顯示文件中第一個域匹配101的行(記錄)。
7、
awk ‘BEGIN { OFS=”%”} {print $1,$2}’ file 通過設置輸出分隔符(OFS=”%”)修改輸出格式。
8、
awk ‘BEGIN { max=100 ;print “max=” max} BEGIN 表示在處理任意行之前進行的操作。{max=($1 >max ?$1:max); print $1,”Now max is “max}’ file 取得文件第一個域的最大值。
(表達式1?表達式2:表達式3 相當于:
if (表達式1)
表達式2
else
表達式3
awk ‘{print ($1>4 ? “high “$1: “low “$1)}’ file
9、
awk ‘$1 * $2 >100 {print $1}’ file 顯示文件中第一個域匹配101的行(記錄)。
10、
awk ‘{$1 == ‘Chi’ {$3 = ‘China’; print}’ file 找到匹配行後先將第3個域替換後再顯示該行(記錄)。
awk ‘{$7 %= 3; print $7}’ file 將第7域被3除,並將余數賦給第7域再打印。
11、
awk ‘/tom/ {wage=$2+$3; printf wage}’ file 找到匹配行後爲變量wage賦值並打印該變量。
12、
awk ‘/tom/ {count++;}
END {print “tom was found “count” times”}’ file END表示在所有輸入行處理完後進行處理。
13、
awk ‘gsub(/\$/,”");gsub(/,/,”"); cost+=$4; END {print “The total is $” cost>”filename”}’ file gsub函數用空串替換$和,再將結果輸出到filename中。
1 2 3 $1,200.00
1 2 3 $2,300.00
1 2 3 $4,000.00
awk ‘{gsub(/\$/,”");gsub(/,/,”");
if ($4>1000&&$4<2000) c1+=$4;
else if ($4>2000&&$4<3000) c2+=$4;
else if ($4>3000&&$4<4000) c3+=$4;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通過if和else if完成條件語句
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000&&$4<4000) exit;
else c4+=$4; }
END {printf "c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"' file
通過exit在某條件時退出,但是仍執行END操作。
awk '{gsub(/\$/,"");gsub(/,/,"");
if ($4>3000) next;
else c4+=$4; }
END {printf “c4=[%d]\n”,c4}”‘ file
通過next在某條件時跳過該行,對下一行執行操作。
14、
awk ‘{ print FILENAME,$0 }’ file1 file2 file3>fileall 把file1、file2、file3的文件內容全部寫到fileall中,格式爲
打印文件並前置文件名。
15、
awk ‘ $1!=previous { close(previous); previous=$1 }
{print substr($0,index($0,” “) +1)>$1}’ fileall 把合並後的文件重新分拆爲3個文件。並與原文件一致。
16、
awk ‘BEGIN {”date”|getline d; print d}’ 通過管道把date的執行結果送給getline,並賦給變量d,然後打印。
17、
awk ‘BEGIN {system(”echo \”Input your name:\\c\”"); getline d;print “\nYour name is”,d,”\b!\n”}’
通過getline命令交互輸入name,並顯示出來。
awk ‘BEGIN {FS=”:”; while(getline< "/etc/passwd" >0) { if($1~”050[0-9]_”) print $1}}’
打印/etc/passwd文件中用戶名包含050x_的用戶名。
18、
awk ‘{ i=1;while(i
19、
在awk中調用系統變量必須用單引號,如果是雙引號,則表示字符串
Flag=abcd
awk ‘{print ‘$Flag’}’ 結果爲abcd
awk ‘{print “$Flag”}’ 結果爲$Flag
4. strace
strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用。
strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。
下面记录几个常用 option .
1 -f -F选项告诉strace同时跟踪fork和vfork出来的进程
2 -o xxx.txt 输出到某个文件。
3 -e execve 只记录 execve 这类系统调用
—————————————————
进程无法启动,软件运行速度突然变慢,程序的"SegmentFault"等等都是让每个Unix系统用户头痛的问题,
本文通过三个实际案例演示如何使用truss、strace和ltrace这三个常用的调试工具来快速诊断软件的"疑难杂症"。
truss和strace用来跟踪一个进程的系统调用或信号产生的情况,而 ltrace用来跟踪进程调用库函数的情况。truss是早期为System V R4开发的调试程序,包括Aix、FreeBSD在内的大部分Unix系统都自带了这个工具;
而strace最初是为SunOS系统编写的,ltrace最早出现在GNU/DebianLinux中。
这两个工具现在也已被移植到了大部分Unix系统中,大多数Linux发行版都自带了strace和ltrace,而FreeBSD也可通过Ports安装它们。
你不仅可以从命令行调试一个新开始的程序,也可以把truss、strace或ltrace绑定到一个已有的PID上来调试一个正在运行的程序。三个调试工具的基本使用方法大体相同,下面仅介绍三者共有,而且是最常用的三个命令行参数:
-f :除了跟踪当前进程外,还跟踪其子进程。
-o file :将输出信息写到文件file中,而不是显示到标准错误输出(stderr)。
-p pid :绑定到一个由pid对应的正在运行的进程。此参数常用来调试后台进程。
使用上述三个参数基本上就可以完成大多数调试任务了,下面举几个命令行例子:
truss -o ls.truss ls -al: 跟踪ls -al的运行,将输出信息写到文件/tmp/ls.truss中。
strace -f -o vim.strace vim: 跟踪vim及其子进程的运行,将输出信息写到文件vim.strace。
ltrace -p 234: 跟踪一个pid为234的已经在运行的进程。
三个调试工具的输出结果格式也很相似,以strace为例:
brk(0) = 0×8062aa8
brk(0×8063000) = 0×8063000
mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0×92f) = 0×40016000
每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。 truss、strace和ltrace的工作原理大同小异,都是使用ptrace系统调用跟踪调试运行中的进程,详细原理不在本文讨论范围内,有兴趣可以参考它们的源代码。
举两个实例演示如何利用这三个调试工具诊断软件的"疑难杂症":
案例一:运行clint出现Segment Fault错误
操作系统:FreeBSD-5.2.1-release
clint是一个C++静态源代码分析工具,通过Ports安装好之后,运行:
# clint foo.cpp
Segmentation fault (core dumped)
在Unix系统中遇见"Segmentation Fault"就像在MS Windows中弹出"非法操作"对话框一样令人讨厌。OK,我们用truss给clint"把把脉":
# truss -f -o clint.truss clint
Segmentation fault (core dumped)
# tail clint.truss
739: read(0×6,0×806f000,0×1000) = 4096 (0×1000)
739: fstat(6,0xbfbfe4d0) = 0 (0×0)
739: fcntl(0×6,0×3,0×0) = 4 (0×4)
739: fcntl(0×6,0×4,0×0) = 0 (0×0)
739: close(6) = 0 (0×0)
739: stat("/root/.clint/plugins",0xbfbfe680) ERR#2 'No such file or directory'
SIGNAL 11
SIGNAL 11
Process stopped because of: 16
process exit, rval = 139
我们用truss跟踪clint的系统调用执行情况,并把结果输出到文件clint.truss,然后用tail查看最后几行。
注意看clint执行的最后一条系统调用(倒数第五行):stat("/root/.clint/plugins",0xbfbfe680) ERR#2 'No such file or directory',问题就出在这里:clint找不到目录"/root/.clint/plugins",从而引发了段错误。怎样解决?很简单: mkdir -p /root/.clint/plugins,不过这次运行clint还是会"Segmentation Fault"9。继续用truss跟踪,发现clint还需要这个目录"/root/.clint/plugins/python",建好这个目录后 clint终于能够正常运行了。
案例二:vim启动速度明显变慢
操作系统:FreeBSD-5.2.1-release
vim版本为6.2.154,从命令行运行vim后,要等待近半分钟才能进入编辑界面,而且没有任何错误输出。仔细检查了.vimrc和所有的vim脚 本都没有错误配置,在网上也找不到类似问题的解决办法,难不成要hacking source code?没有必要,用truss就能找到问题所在:
# truss -f -D -o vim.truss vim
这里-D参数的作用是:在每行输出前加上相对时间戳,即每执行一条系统调用所耗费的时间。我们只要关注哪些系统调用耗费的时间比较长就可以了,用less仔细查看输出文件vim.truss,很快就找到了疑点:
735: 0.000021511 socket(0×2,0×1,0×0) = 4 (0×4)
735: 0.000014248 setsockopt(0×4,0×6,0×1,0xbfbfe3c8,0×4) = 0 (0×0)
735: 0.000013688 setsockopt(0×4,0xffff,0×8,0xbfbfe2ec,0×4) = 0 (0×0)
735: 0.000203657 connect(0×4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000017042 close(4) = 0 (0×0)
735: 1.009366553 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0×0)
735: 0.000019556 socket(0×2,0×1,0×0) = 4 (0×4)
735: 0.000013409 setsockopt(0×4,0×6,0×1,0xbfbfe3c8,0×4) = 0 (0×0)
735: 0.000013130 setsockopt(0×4,0xffff,0×8,0xbfbfe2ec,0×4) = 0 (0×0)
735: 0.000272102 connect(0×4,{ AF_INET 10.57.18.27:6000 },16) ERR#61 'Connection refused'
735: 0.000015924 close(4) = 0 (0×0)
735: 1.009338338 nanosleep(0xbfbfe468,0xbfbfe460) = 0 (0×0)
vim试图连接10.57.18.27这台主机的6000端口(第四行的connect()),连接失败后,睡眠一秒钟继续重试(第6行的 nanosleep())。以上片断循环出现了十几次,每次都要耗费一秒多钟的时间,这就是vim明显变慢的原因。可是,你肯定会纳闷:"vim怎么会无 缘无故连接其它计算机的6000端口呢?"。问得好,那么请你回想一下6000是什么服务的端口?没错,就是X Server。看来vim是要把输出定向到一个远程X Server,那么Shell中肯定定义了DISPLAY变量,查看.cshrc,果然有这么一行:setenv DISPLAY ${REMOTEHOST}:0,把它注释掉,再重新登录,问题就解决了。
案例三:用调试工具掌握软件的工作原理
操作系统:Red Hat Linux 9.0
用调试工具实时跟踪软件的运行情况不仅是诊断软件"疑难杂症"的有效的手段,也可帮助我们理清软件的"脉络",即快速掌握软件的运行流程和工作原理,不 失为一种学习源代码的辅助方法。下面这个案例展现了如何使用strace通过跟踪别的软件来"触发灵感",从而解决软件开发中的难题的。
大家都知道,在进程内打开一个文件,都有唯一一个文件描述符(fd:file descriptor)与这个文件对应。而本人在开发一个软件过程中遇到这样一个问题:
已知一个fd,如何获取这个fd所对应文件的完整路径?不管是Linux、FreeBSD或是其它Unix系统都没有提供这样的API,怎么办呢?我们 换个角度思考:Unix下有没有什么软件可以获取进程打开了哪些文件?如果你经验足够丰富,很容易想到lsof,使用它既可以知道进程打开了哪些文件,也 可以了解一个文件被哪个进程打开。好,我们用一个小程序来试验一下lsof,看它是如何获取进程打开了哪些文件。lsof: 显示进程打开的文件。
/* testlsof.c */
#include #include #include #include #include
int main(void)
{
open("/tmp/foo", O_CREAT|O_RDONLY); /* 打开文件/tmp/foo */
sleep(1200); /* 睡眠1200秒,以便进行后续操作 */
return 0;
}
将testlsof放入后台运行,其pid为3125。命令lsof -p 3125查看进程3125打开了哪些文件,我们用strace跟踪lsof的运行,输出结果保存在lsof.strace中:
# gcc testlsof.c -o testlsof
# ./testlsof &
[1] 3125
# strace -o lsof.strace lsof -p 3125
我们以"/tmp/foo"为关键字搜索输出文件lsof.strace,结果只有一条:
# grep '/tmp/foo' lsof.strace
readlink("/proc/3125/fd/3", "/tmp/foo", 4096) = 8
原来lsof巧妙的利用了/proc/nnnn/fd/目录(nnnn为pid):Linux内核会为每一个进程在/proc/建立一个以其pid为名 的目录用来保存进程的相关信息,而其子目录fd保存的是该进程打开的所有文件的fd。目标离我们很近了。好,我们到/proc/3125/fd/看个究 竟:
# cd /proc/3125/fd/
# ls -l
total 0
lrwx—— 1 root root 64 Nov 5 09:50 0 -> /dev/pts/0
lrwx—— 1 root root 64 Nov 5 09:50 1 -> /dev/pts/0
lrwx—— 1 root root 64 Nov 5 09:50 2 -> /dev/pts/0
lr-x—— 1 root root 64 Nov 5 09:50 3 -> /tmp/foo
# readlink /proc/3125/fd/3
/tmp/foo
答案已经很明显了:/proc/nnnn/fd/目录下的每一个fd文件都是符号链接,而此链接就指向被该进程打开的一个文件。我们只要用readlink()系统调用就可以获取某个fd对应的文件了,代码如下:
#include #include #include #include #include #include
int get_pathname_from_fd(int fd, char pathname[], int n)
{
char buf[1024];
pid_t pid;
bzero(buf, 1024);
pid = getpid();
snprintf(buf, 1024, "/proc/%i/fd/%i", pid, fd);
return readlink(buf, pathname, n);
}
int main(void)
{
int fd;
char pathname[4096];
bzero(pathname, 4096);
fd = open("/tmp/foo", O_CREAT|O_RDONLY);
get_pathname_from_fd(fd, pathname, 4096);
printf("fd=%d; pathname=%sn", fd, pathname);
return 0;
}
出于安全方面的考虑,在FreeBSD 5 之后系统默认已经不再自动装载proc文件系统,因此,要想使用truss或strace跟踪程序,你必须手工装载proc文件系统:mount -t procfs proc /proc;或者在/etc/fstab中加上一行:
proc /proc procfs rw 0 0
5. objdump
6. tcpdump
第一种是关于类型的关键字,主要包括host,net,port, 例如 host 210.27.48.2,指明 210.27.48.2是一台主 机,net 202.0.0.0 指明 202.0.0.0是一个网络地址,port 23 指明端口号是23.如果没有指定类型,缺省的类型是 host.
第二种是确定传输方向的关键字,主要包括src , dst ,dst or src, dst and src ,这些 关键字指明了传输的方向。举例说明,src 210.27.48.2 ,指明ip包中源地址是 210.27.48.2 , dst net 202.0.0.0 指明目的网络地址是202.0.0.0 .如果没有指明方向关键字,则缺省是 src or dst关键字。
第三种是协议的关键字,主要包括fddi,ip,arp,rarp,tcp,udp等类型。Fddi指 明是在FDDI(分布式光纤数据接口网络)上的特定 的网络协议,实际上它是"ether"的别名,fddi和ether具有类似的源地址和目的地址,所 以可以将fddi协议包当作ether的包进行处理和 分析。其他的几个关键字就是指明了监听的包的协议内容。如果没有指定任何协议,则tcpdump将 会监听所有协议的信息包。
除了这三种类型的关键字之外,其他重要的关键字如 下:gateway, broadcast,less,greater,还有三种逻辑运算,取非运算是 'not ' '! ', 与运算是 'and','&&';或运算 是'or' ,'││';这些关键字可以组合起来构成强大的组合条件来满足人们的需要,下面举几个例子来 说明。
普通情况下,直接启动tcpdump将监视第一个网络界面上所有流过的数据包。
# tcpdump
tcpdump: listening on fxp0
11:58:47.873028 202.102.245.40.netbios-ns > 202.102.245.127.netbios-ns: udp 50
11:58:47.974331 0:10:7b:8:3a:56 > 1:80:c2:0:0:0 802.1d ui/C len=43
0000 0000 0080 0000 1007 cf08 0900 0000
0e80 0000 902b 4695 0980 8701 0014 0002
000f 0000 902b 4695 0008 00
11:58:48.373134 0:0:e8:5b:6d:85 > Broadcast sap e0 ui/C len=97
ffff 0060 0004 ffff ffff ffff ffff ffff
0452 ffff ffff 0000 e85b 6d85 4008 0002
0640 4d41 5354 4552 5f57 4542 0000 0000
0000 00
使用-i参数指定tcpdump监听的网络界面,这在计算机具有多个网络界面时非常有用,
使用-c参数指定要监听的数据包数量,
使用-w参数指定将监听到的数据包写入文件中保存
A想要截获所有210.27.48.1 的主机收到的和发出的所有的数据包:
#tcpdump host 210.27.48.1
B想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令:(在命令行中适用 括号时,一定要
#tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)
C如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
D如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令:
#tcpdump tcp port 23 host 210.27.48.1
E 对本机的udp 123 端口进行监视 123 为ntp的服务端口
# tcpdump udp port 123
F 系统将只对名为hostname的主机的通信数据包进行监视。主机名可以是本地主机,也可以是网络上的任何一台计算机。下面的命令可以读取主机hostname发送的所有数据:
#tcpdump -i eth0 src host hostname
G 下面的命令可以监视所有送到主机hostname的数据包:
#tcpdump -i eth0 dst host hostname
H 我们还可以监视通过指定网关的数据包:
#tcpdump -i eth0 gateway Gatewayname
I 如果你还想监视编址到指定端口的TCP或UDP数据包,那么执行以下命令:
#tcpdump -i eth0 host hostname and port 80
J 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包
,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
K 想要截获主机210.27.48.1 和主机210.27.48.2 或210.27.48.3的通信,使用命令
:(在命令行中适用 括号时,一定要
#tcpdump host 210.27.48.1 and \ (210.27.48.2 or 210.27.48.3 \)
L 如果想要获取主机210.27.48.1除了和主机210.27.48.2之外所有主机通信的ip包,使用命令:
#tcpdump ip host 210.27.48.1 and ! 210.27.48.2
M 如果想要获取主机210.27.48.1接收或发出的telnet包,使用如下命令:
#tcpdump tcp port 23 host 210.27.48.1
第三种是协议的关键字,主要包括fddi,ip ,arp,rarp,tcp,udp等类型
除了这三种类型的关键字之外,其他重要的关键字如下:gateway, broadcast,less,
greater,还有三种逻辑运算,取非运算是 'not ' '! ', 与运算是'and','&&';或运算 是'o
r' ,'||';
第二种是确定传输方向的关键字,主要包括src , dst ,dst or src, dst and src ,
如果我们只需要列出送到80端口的数据包,用dst port;如果我们只希望看到返回80端口的数据包,用src port.
#tcpdump –i eth0 host hostname and dst port 80 目的端口是80
或者
#tcpdump –i eth0 host hostname and src port 80 源端口是80 一般是提供http的服务的主机
如果条件很多的话 要在条件之前加and 或 or 或 not
#tcpdump -i eth0 host ! 211.161.223.70 and ! 211.161.223.71 and dst port 80
如果在ethernet 使用混杂模式 系统的日志将会记录
May 7 20:03:46 localhost kernel: eth0: Promiscuous mode enabled.
May 7 20:03:46 localhost kernel: device eth0 entered promiscuous mode
May 7 20:03:57 localhost kernel: device eth0 left promiscuous mode
tcpdump对截获的数据并没有进行彻底解码,数据包内的大部分内容是使用十六进制的形式直接打印输出的。显然这不利于分析网络故障,通常的解决办法 是先使用带-w参数的tcpdump 截获数据并保存到文件中,然后再使用其他程序进行解码分析。当然也应该定义过滤规则,以避免捕获的数据包填满整个硬 盘。
7. readelf
8. nm
9. unix2dos
· unix2dos -d filename //Convert DOS to Unix
· unix2dos -u filename //Convert Unix to DOS.
· unix2dos -b filename //Make backup of original file (.bak).
10. top 常用交互命令
- <空格>; 立即刷新显示。
- Ctrl+L 擦除并且重写屏幕。
- h或者? 显示帮助画面,给出一些简短的命令总结说明。
- k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什幺样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。
- i 忽略闲置和僵死进程。这是一个开关式命令。
- q 退出程序。
- r 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
- S 切换到累计模式。
- s 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间,单位为s。如果有小数,就换算成ms。输入0值则系统将不断刷新,默认值是5 s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
- f或者F 从当前显示中添加或者删除项目。
- o或者O 改变显示项目的顺序。
- l 切换显示平均负载和启动时间信息。
- m 切换显示内存信息。
- t 切换显示进程和CPU状态信息。
- c 切换显示命令名称和完整命令行。
- M 根据驻留内存大小进行排序。
- P 根据CPU使用百分比大小进行排序。
- T 根据时间/累计时间进行排序。
top -H -p 进程号 查看进程使用的所有线程状态
11. find
地址:http://blog.chinaunix.net/u/6889/showart.php?id=136817
12. lsof
13. nl
在 cat 指令有個 -n 選項,能為輸出加上行數。但 nl 指令則提供了更多這方面的彈性。
# cat -n fileA # nl fileA |
以上這兩種方式,都可以為檔案 fileA 的顯示,加上需要的行號。
但如果想要讓附加的行數,做左右對齊或者是補零的動作就得依賴 nl 指令來做了。
# nl -n rz fileA 000001 /home 000002 |-- SourceCode 000003 | |-- MySQL 000004 | | |-- filter-requires-mysql.sh 000005 | | |-- my.cnf .....略 |
變更行數的遞增值、顯示位元數
預設的行數遞增值是1,但這可以改變。選項 -i 可以讓我們做到這一點
# nl -i 2 fileA 1 /home 3 |-- SourceCode 5 | |-- MySQL 7 | | |-- filter-requires-mysql.sh 9 | | |-- my.cnf .....略 # |
除了遞增值以外,還有設定顯示行數的位元數。也就是 -w 選項,程式的預設值為6。如果有必要的話,我們可以自行更改
# nl -n rz -w 3 bb001 /home
002 |-- SourceCode
003 | |-- MySQL
004 | | |-- filter-requires-mysql.sh
005 | | |-- my.cnf
.....略
#
14. ar
ar cvs (lib)库文件名 文件1.o 文件2.o .... //生成静态库文件
at -t 库文件名 //显示库文件中包含那些文件
at x 库文件名 [模块名] //将库文件中的所有文件抽取出来
ar -d 库文件名 模块名 //将库文件中指定的模名删除掉
ar q 库文件名 模块名 //向库中追加模块
ar s 库文件名 //更新库文件中的符号表
ar r 库文件名 模块名 //替换库文件中相应的模块