1、重定向>、 >>、 1>、 2>、 1>>、 2>>
(1)>是重定向到一个文件,>>是追加内容到一个文件。如果文件不存在,那么这两个命令都会首先创建这个文件。
(2)1> 将正确的输出重定向到某个文件,2> 将错误的输出重定向到某个文件(这里0、1、2分别代表标准输入、标准输出、错误输出)。将错误输出和正确输出保存到同一个文件:
command 1> a.txt 2>&1 # 可以简化为:command > a.txt 2>&1
(3) 1>> 、2>>其实也就是追加数据到文件中,和前面介绍的>>没有什么不同,需要提到的一点是,如果我们想将错误的和正确的信息重定向追加到同一个文件应该怎么做呢?你可能会想到2>>&1,然而现实是,并没有这个语法。然而我们却可以使用1 >> a.txt 2>&1的语法实现这个功能,比如:
command 1>> a.txt 2>&1
(4)如果我们想保存正确的结果,错误的结果直接丢向垃圾站,既不保存为文件,也不在标准输出打印又该怎么做呢?
command 1>> right.txt 2> /dev/null
2、后台运行程序(nohup):
在linux中执行python程序时,我们通常会用 python xx.py命令来执行,但这样执行的程序在关闭linux的控制台后,执行的程序就退出了,要让程序关闭后继续执行该怎么办?要让python程序在关闭控制台后继续执行,我们需要使用到nohub命令。nohup是linux下的一个命令,其用途为不挂断地运行命令。执行python时,命令格式如下:
$ nohup python -u xx.py > log.out 2>&1 &
使用&命令后,作业被提交到后台运行,当前控制台没有被占用,但是一但把当前控制台关掉(退出帐户时),作业就会停止运行。因此这里使用nohup和&号两个命令。
3、压缩和解压:
(1)压缩 :
tar -cvf jpg.tar *.jpg # 将目录里所有jpg文件打包成jpg.tar;
tar -czf jpg.tar.gz *.jpg # 将目录里所有jpg文件打包成jpg.tar后,用gzip压缩,生成jpg.tar.gz;
tar -cjf jpg.tar.bz2 *.jpg # 将目录里所有jpg文件打包成jpg.tar后,用bzip2压缩,生成一个jpg.tar.bz2;
tar -cZf jpg.tar.Z *.jpg # 将目录里所有jpg文件打包成jpg.tar后,用compress压缩,生成一个jpg.tar.Z;
rar a jpg.rar *.jpg # rar格式的压缩,需要先下载rar for linux;
zip jpg.zip *.jpg # zip格式的压缩,需要先下载zip for linux;
(2)解压:
tar -xvf file.tar # 解压 tar包
tar -xzvf file.tar.gz # 解压tar.gz
tar -xjvf file.tar.bz2 # 解压 tar.bz2
tar -xZvf file.tar.Z # 解压tar.Z
unrar e file.rar # 解压rar
unzip file.zip # 解压zip
(3)参数介绍:
-c: 建立压缩档案
-x:解压
-t:查看内容
-r:向压缩归档文件末尾追加文件
-u:更新原压缩包中的文件
这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。
-z:有gzip属性的
-j:有bz2属性的
-Z:有compress属性的
-v:显示所有过程
-O:将文件解开到标准输出
下面的参数-f是必须的
-f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。
4、网络相关(netstat):
该命令用于显示各种网络相关信息,如网络连接,路由表,接口状态 (Interface Statistics),masquerade 连接,多播成员 (Multicast Memberships) 等等。
语法为:
netstat [-acCeFghilMnNoprstuvVwx] [-A<网络类型>] [--ip]
参数说明:
-a:显示所有连线中的Socket。
-A<网络类型>:列出该网络类型连线中的相关地址。
-c:持续列出网络状态。
-C:显示路由器配置的快取信息。
-e:显示网络其他相关信息。
-F:显示FIB。
-g:显示多重广播功能群组组员名单。
-h:在线帮助。
-i:显示网络界面信息表单。
-l:显示监控中的服务器的Socket。
-M:显示伪装的网络连线。
-n:直接使用IP地址,而不通过域名服务器。
-N:显示网络硬件外围设备的符号连接名称。
-o:显示计时器。
-p:显示正在使用Socket的程序识别码和程序名称。
-r:显示Routing Table。
-s:显示网络工作信息统计表。
-t:显示TCP传输协议的连线状况。
-u:显示UDP传输协议的连线状况。
-v:显示指令执行过程。
-V:显示版本信息。
-w:显示RAW传输协议的连线状况。
-x:此参数的效果和指定"-A unix"参数相同。
--ip:此参数的效果和指定"-A inet"参数相同。
5、进程查看器(ps):
Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信息,就可以使用top命令。要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而 ps 命令就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行和运行的状态、进程是否结束、进程有没有僵死、哪些进程占用了过多的资源等等。总之大部分信息都是可以通过执行该命令得到的。ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;如果想对进程时间监控,应该用 top工具。
(1)linux上进程有5种状态:
1)运行(正在运行或在运行队列中等待);
2)中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号);
3)不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生);
4)僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放);
5)停止(进程收到SIGSTOP, SIGTSTP, SIGTTIN, SIGTTOU信号后停止运行运行);
(2)ps工具标识进程的5种状态码:
1)D 不可中断 uninterruptible sleep (usually IO)
2)R 运行 runnable (on run queue)
3)S 中断 sleeping
4)T 停止 traced or stopped
5)Z 僵死 a defunct (”zombie”) process
(3)命令参数:
a 显示所有进程
-a 显示同一终端下的所有程序
-A 显示所有进程
c 显示进程的真实名称
-N 反向选择
-e 等于“-A”
e 显示环境变量
f 显示程序间的关系
-H 显示树状结构
-j 显示与作业相关的信息:会话ID、进程组ID、控制终端计终端进程组ID
r 显示当前终端的进程
T 显示当前终端的所有程序
u 指定用户的所有进程
-au 显示较详细的资讯
-aux 显示所有包含其他使用者的行程
-C<命令> 列出指定命令的状况
–lines<行数> 每页显示的行数
–width<字符数> 每页显示的字符数
–help 显示帮助信息
–version 显示版本显示
(4) 输出列的含义:
F 代表这个程序的旗标 (flag), 4 代表使用者为 super user
S 代表这个程序的状态 (STAT),关于各 STAT 的意义将在内文介绍
UID 程序被该 UID 所拥有
PID 进程的ID
PPID 则是其上级父程序的ID
C CPU 使用的资源百分比
PRI 这个是 Priority (优先执行序) 的缩写,详细后面介绍
NI 这个是 Nice 值,在下一小节我们会持续介绍
ADDR 这个是 kernel function,指出该程序在内存的那个部分。如果是个 running的程序,一般就是 “-“
SZ 使用掉的内存大小
WCHAN 目前这个程序是否正在运作当中,若为 - 表示正在运作
TTY 登入者的终端机位置
TIME 使用掉的 CPU 时间。
CMD 所下达的指令为何
(4)经常使用
ps -u username : 显示指定用户信息;
ps -ef :显示所有进程信息,连同命令行;
ps -ef | grep username : ps 与grep 组合使用,查找特定进程;
ps -aux : 列出目前所有的正在内存中的程序;
ps -l : 将与这次登入的 PID 与相关信息列示出来;
6、任务管理器(top)
top命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器。top是一个动态显示过程,即可以通过用户按键来不断刷新当前状态.如果在前台执行该命令,它将独占前台,直到用户终止该程序为止.比较准确的说,top命令提供了实时的对系统处理器的状态监视.它将显示系统中CPU最“敏感”的任务列表.该命令可以按CPU使用.内存使用和执行时间对任务进行排序;而且该命令的很多特性都可以通过交互式命令或者在个人定制文件中进行设定。
(1)top的返回信息
$top
top - 09:14:56 up 264 days, 20:56, 1 user, load average: 0.02, 0.04, 0.00
Tasks: 87 total, 1 running, 86 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.0%us, 0.2%sy, 0.0%ni, 99.7%id, 0.0%wa, 0.0%hi, 0.0%si, 0.2%st
Mem: 377672k total, 322332k used, 55340k free, 32592k buffers
Swap: 397308k total, 67192k used, 330116k free, 71900k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 2856 656 388 S 0.0 0.2 0:49.40 init
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 7:15.20 ksoftirqd/0
4 root RT 0 0 0 0 S 0.0 0.0 0:00.00 migration/0
1)第一行
09:14:56 : 系统当前时间
264 days, 20:56 : 系统开机到现在经过了多少时间
1 users : 当前2用户在线
load average: 0.02, 0.04, 0.00: 系统1分钟、5分钟、15分钟的CPU负载信息
2)第二行:
Tasks:任务;
87 total:很好理解,就是当前有87个任务,也就是87个进程。
1 running:1个进程正在运行
86 sleeping:86个进程睡眠
0 stopped:停止的进程数
0 zombie:僵死的进程数
3)第三行:
Cpu(s):表示这一行显示CPU总体信息
0.0%us:用户态进程占用CPU时间百分比,不包含renice值为负的任务占用的CPU的时间。
0.7%sy:内核占用CPU时间百分比
0.0%ni:改变过优先级的进程占用CPU的百分比
99.3%id:空闲CPU时间百分比
0.0%wa:等待I/O的CPU时间百分比
0.0%hi:CPU硬中断时间百分比
0.0%si:CPU软中断时间百分比
注:这里显示数据是所有cpu的平均值,如果想看每一个cpu的处理情况,按1即可;折叠,再次按1;
4)第四行
Men:内存的意思
8175320kk total:物理内存总量
8058868k used:使用的物理内存量
116452k free:空闲的物理内存量
283084k buffers:用作内核缓存的物理内存量
5)第五行
Swap:交换空间
6881272k total:交换区总量
4010444k used:使用的交换区量
2870828k free:空闲的交换区量
4336992k cached:缓冲交换区总量
6)进程信息
PID:进程的ID
USER:进程所有者
PR:进程的优先级别,越小越优先被执行
NInice:值
VIRT:进程占用的虚拟内存
RES:进程占用的物理内存
SHR:进程使用的共享内存
S:进程的状态。S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数
%CPU:进程占用CPU的使用率
%MEM:进程使用的物理内存和总内存的百分比
TIME+:该进程启动后占用的总的CPU时间,即占用CPU使用时间的累加值。
COMMAND:进程启动命令名称
(2)top命令交互操作指令
q:退出top命令
<Space>:立即刷新
s:设置刷新时间间隔
c:显示命令完全模式
t::显示或隐藏进程和CPU状态信息
m:显示或隐藏内存状态信息
l:显示或隐藏uptime信息
f:增加或减少进程显示标志
S:累计模式,会把已完成或退出的子进程占用的CPU时间累计到父进程的MITE+
P:按%CPU使用率排行
T:按MITE+排行
M:按%MEM排行
u:指定显示用户进程
r:修改进程renice值
kkill:进程
i:只显示正在运行的进程
W:保存对top的设置到文件^/.toprc,下次启动将自动调用toprc文件的设置。
h:帮助命令。
q:退出
注:强调一下,使用频率最高的是P、T、M,因为通常使用top,我们就想看看是哪些进程最耗cpu资源、占用的内存最多; 注:通过”shift + >”或”shift + <”可以向右或左改变排序列 如果只需要查看内存:可用free命令。只查看uptime信息(第一行),可用uptime命令;
(3)常用命令
top -p pidid :显示指定的进程信息
top -c : 显示完整的程序命令
top基本视图中,按键盘数字“1”,可监控每个逻辑CPU的状况
7、跨机远程拷贝(scp)
scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的。当你服务器硬盘变为只读 read only system时,用scp可以帮你把文件移出来。
(1)命令格式:
scp [参数] [原路径] [目标路径]
(2)命令参数:
-1 强制scp命令使用协议ssh1
-2 强制scp命令使用协议ssh2
-4 强制scp命令只使用IPv4寻址
-6 强制scp命令只使用IPv6寻址
-B 使用批处理模式(传输过程中不询问传输口令或短语)
-C 允许压缩。(将-C标志传递给ssh,从而打开压缩功能)
-p 留原文件的修改时间,访问时间和访问权限。
-q 不显示传输进度条。
-r 递归复制整个目录。
-v 详细方式显示输出。scp和ssh(1)会显示出整个过程的调试信息。这些信息用于调试连接,验证和配置问题。
-c cipher 以cipher将数据传输进行加密,这个选项将直接传递给ssh。
-F ssh_config 指定一个替代的ssh配置文件,此参数直接传递给ssh。
-i identity_file 从指定文件中读取传输时使用的密钥文件,此参数直接传递给ssh。
-l limit 限定用户所能使用的带宽,以Kbit/s为单位。
-o ssh_option 如果习惯于使用ssh_config(5)中的参数传递方式,
-P port 注意是大写的P, port是指定数据传输用到的端口号
-S program 指定加密传输时所使用的程序。此程序必须能够理解ssh(1)的选项。
(3)使用示例 :
1)实例1:从远处复制文件到本地目录
$scp root@10.6.159.147:/opt/soft/demo.tar /opt/soft/
# 说明: 从10.6.159.147机器上的/opt/soft/的目录中下载demo.tar 文件到本地/opt/soft/目录中
2)实例2:从远处复制到本地
$scp -r root@10.6.159.147:/opt/soft/test /opt/soft/
# 说明: 从10.6.159.147机器上的/opt/soft/中下载test目录到本地的/opt/soft/目录来。
3)实例3:上传本地文件到远程机器指定目录
$scp /opt/soft/demo.tar root@10.6.159.147:/opt/soft/scptest
# 说明: 复制本地opt/soft/目录下的文件demo.tar 到远程机器10.6.159.147的opt/soft/scptest目录
4)实例4:上传本地目录到远程机器指定目录
$scp -r /opt/soft/test root@10.6.159.147:/opt/soft/scptest
# 说明: 上传本地目录 /opt/soft/test到远程机器10.6.159.147上/opt/soft/scptest的目录中
8、定时任务(crontab)
(1)命令格式
crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]
(2)命令参数
-u user:用来设定某个用户的crontab服务;
file:file是命令文件的名字,表示将file做为crontab的任务列表文件并载入crontab。如果在命令行中没有指定这个文件,
crontab命令将接受标准输入(键盘)上键入的命令,并将它们载入crontab。
-e:编辑某个用户的crontab文件内容。如果不指定用户,则表示编辑当前用户的crontab文件。
-l:显示某个用户的crontab文件内容,如果不指定用户,则表示显示当前用户的crontab文件内容。
-r:从/var/spool/cron目录中删除某个用户的crontab文件,如果不指定用户,则默认删除当前用户的crontab文件。
-i:在删除用户的crontab文件时给确认提示。
(3)crontab的文件格式:分 时 日 月 星期 要运行的命令
第1列分钟0~59
第2列小时0~23(0表示子夜)
第3列日1~31
第4列月1~12
第5列星期0~7(0和7表示星期天)
第6列要运行的命令
(4)常用方法:
创建一个新的crontab文件,向cron进程提交一个crontab文件之前,首先要设置环境变量EDITOR。cron进程根据它来确定使用哪个编辑器编辑crontab文件。99 %的UNIX和LINUX用户都使用vi,如果你也是这样,那么你就编辑$HOME目录下的. profile文件,在其中加入这样一行:
EDITOR=vi; export EDITOR
然后保存并退出。不妨创建一个名为<user> cron的文件,其中<user>是用户名,例如, davecron。在该文件中加入如下的内容。
# (put your own initials here)echo the date to the console every
# 15minutes between 6pm and 6am
* * * * date >> /home/$HOME/log.txt # 以追加的方式重定向
保存并退出。注意前面5个域用空格分隔。在上面的例子中,系统将每分钟向日志文件输出一次当前时间。如果系统崩溃或挂起,从最后所显示的时间就可以一眼看出系统是什么时间停止工作的。为了提交你刚刚创建的crontab文件,可以把这个新创建的文件作为cron命令的参数:
$ crontab davecron
现在该文件已经提交给cron进程,它将每分钟运行一次。同时,新创建文件的一个副本已经被放在/var/spool/cron目录中,文件名就是用户名(即dave)。
使用-l参数列出crontab文件:
$ crontab -l
* * * * date >> /home/$HOME/log.txt # 以追加的方式重定向
可以使用这种方法在$HOME目录中对crontab文件做一备份:
$ crontab -l > $HOME/mycron
这样,一旦不小心误删了crontab文件,可以用上一节所讲述的方法迅速恢复。
如果希望添加、删除或编辑crontab文件中的条目,而EDITOR环境变量又设置为vi,那么就可以用vi来编辑crontab文件:
$ crontab -e
可以像使用vi编辑其他任何文件那样修改crontab文件并退出。如果修改了某些条目或添加了新的条目,那么在保存该文件时, cron会对其进行必要的完整性检查。如果其中的某个域出现了超出允许范围的值,它会提示你。 我们在编辑crontab文件时,没准会加入新的条目。例如,加入下面的一条:
# DT:delete core files,at 3.30am on 1,7,14,21,26,26 days of each month
30 3 1,7,14,21,26 * * /bin/find -name 'core' -exec rm {} \;
保存并退出。最好在crontab文件的每一个条目之上加入一条注释,这样就可以知道它的功能、运行时间,更为重要的是,知道这是哪位用户的定时作业。
删除crontab文件
$crontab -r
(5)使用实例:
1)实例1:每1分钟执行一次myCommand
* * * * * myCommand
2)实例2:每小时的第3和第15分钟执行
3,15 * * * * myCommand
3)实例3:在上午8点到11点的第3和第15分钟执行
3,15 8-11 * * * myCommand
4)实例4:每隔两天的上午8点到11点的第3和第15分钟执行
3,15 8-11 */2 * * myCommand
5)实例5:每周一上午8点到11点的第3和第15分钟执行
3,15 8-11 * * 1 myCommand
6)实例6:每晚的21:30重启smb
30 21 * * * /etc/init.d/smb restart
7)实例7:每月1、10、22日的4 : 45重启smb
45 4 1,10,22 * * /etc/init.d/smb restart
8)实例8:每周六、周日的1 : 10重启smb
10 1 * * 6,0 /etc/init.d/smb restart
9)实例9:每天18 : 00至23 : 00之间每隔30分钟重启smb
0,30 18-23 * * * /etc/init.d/smb restart
10)实例10:每星期六的晚上11 : 00 pm重启smb
0 23 * * 6 /etc/init.d/smb restart
11)实例11:每一小时重启smb
* */1 * * * /etc/init.d/smb restart
12)实例12:晚上11点到早上7点之间,每隔一小时重启smb
0 23-7 * * * /etc/init.d/smb restart
9、查看系统进程通信(ipcs、ipcrm)
ipcs是Linux下显示进程间通信设施状态的工具。可以显示消息队列、共享内存和信号量的信息。对于程序员非常有用,普通的系统管理员一般用不到此指令。
(1)查看系统使用的IPC资源:
ipcs
(2)分别查询IPC资源:
$ipcs -m # 查看系统使用的IPC共享内存资源
$ipcs -q # 查看系统使用的IPC队列资源
$ipcs -s # 查看系统使用的IPC信号量资源
(3)系统IPC参数查询(查询消息队列、共享内存和信号量的最大容量):
$ipcs -l
(4)ipcrm:移除一个消息对象、或者共享内存段、或者一个信号集,同时会将与ipc对象相关链的数据也一起移除。当然,只有超级管理员,或者ipc对象的创建者才有这项权利:
ipcrm用法 :
ipcrm -M shmkey # 移除用shmkey创建的共享内存段
ipcrm -m shmid # 移除用shmid标识的共享内存段
ipcrm -Q msgkey # 移除用msqkey创建的消息队列
ipcrm -q msqid # 移除用msqid标识的消息队列
ipcrm -S semkey # 移除用semkey创建的信号
ipcrm -s semid # 移除用semid标识的信号
10、抓包工具(tcpdump)(参考)
(1)针对特定网口抓包(-i选项)
当我们不加任何选项执行tcpdump时,tcpdump将抓取通过所有网口的包;使用-i选项,我们可以在某个指定的网口抓包(其中网口的名字可以用ifconfig命令查看):
tcpdump -i eth0
(2)抓取指定数目的包(-c选项)
默认情况下tcpdump将一直抓包,直到按下”ctrl+c”中止,使用-c选项我们可以指定抓包的数量:
tcpdump -c 2 -i eth0
(3)将抓到包写入文件中(-w选项)
使用-w选项,我们可将抓包记录到一个指定文件中,以供后续分析
tcpdump -w 20120606.pcap -i eth0
(4)读取tcpdump保存文件(-r选项)
对于保存的抓包文件,我们可以使用-r选项进行读取:
tcpdump -r 20120606.pcap
(5)抓包时不进行域名解析(-n选项)
默认情况下,tcpdump抓包结果中将进行域名解析,显示的是域名地址而非ip地址,使用-n选项,可指定显示ip地址。
(6)增加抓包时间戳(-tttt选项)
使用-tttt选项,抓包结果中将包含抓包日期:
tcpdump -n -tttt -i eth0
(7)指定抓包的协议类型
我们可以只抓某种协议的包,tcpdump支持指定以下协议:ip,ip6,arp,tcp,udp,wlan等。以下例子只抓取arp协议的包
tcpdump -i eth0 arp
(8)指定抓包端口
如果想要对某个特定的端口抓包,可以通过以下命令:
tcpdump -i eth0 port 22
(9)抓取特定目标ip和端口的包
网络包的内容中,包含了源ip地址、端口和目标ip、端口,我们可以根据目标ip和端口过滤tcpdump抓包结果,以下命令说明了此用法:
tcpdump -i eth0 dst 10.70.121.92 and port 22
(10)tcpdump 与wireshark
Wireshark是Windows下非常简单易用的抓包工具。但在Linux下很难找到一个好用的图形化抓包工具。还好有Tcpdump。我们可以用Tcpdump + Wireshark 的完美组合实现:在 Linux 里抓包,然后在Windows 里分析包。
tcpdump tcp -i eth1 -t -s 0 -c 100 and dst port ! 22 and src net 192.168.1.0/24 -w ./target.cap
1)tcp: ip icmp arp rarp 和 tcp、udp、icmp这些选项等都要放到第一个参数的位置,用来过滤数据报的类型;
2)-i eth1 : 只抓经过接口eth1的包;
3)-t : 不显示时间戳;
4)-s 0 : 抓取数据包时默认抓取长度为68字节。加上-S 0 后可以抓到完整的数据包;
5)-c 100 : 只抓取100个数据包;
6)dst port ! 22 : 不抓取目标端口是22的数据包;
7)src net 192.168.1.0/24 : 数据包的源网络地址为192.168.1.0/24;
8)-w ./target.cap : 保存成cap文件,方便用ethereal(即wireshark)分析;
11、程序调试工具(strace、pstack)
(1)跟踪进程中的系统调用(strace)
strace常用来跟踪进程执行时的系统调用和所接收的信号。 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核态模式,通过系统调用访问硬件设备。strace可以跟踪到一个进程产生的系统调用,包括参数,返回值,执行消耗的时间。
1)输出参数含义:
每一行都是一条系统调用,等号左边是系统调用的函数名及其参数,右边是该调用的返回值。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建内核。
$strace cat /dev/null
execve("/bin/cat", ["cat", "/dev/null"], [/* 22 vars */]) = 0
brk(0) = 0xab1000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29379a7000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
...
2)参数介绍
-c 统计每一系统调用的所执行的时间,次数和出错的次数等.
-d 输出strace关于标准错误的调试信息.
-f 跟踪由fork调用所产生的子进程.
-ff 如果提供-o filename,则所有进程的跟踪结果输出到相应的filename.pid中,pid是各进程的进程号.
-F 尝试跟踪vfork调用.在-f时,vfork不被跟踪.
-h 输出简要的帮助信息.
-i 输出系统调用的入口指针.
-q 禁止输出关于脱离的消息.
-r 打印出相对时间关于,,每一个系统调用.
-t 在输出中的每一行前加上时间信息.
-tt 在输出中的每一行前加上时间信息,微秒级.
-ttt 微秒级输出,以秒了表示时间.
-T 显示每一调用所耗的时间.
-v 输出所有的系统调用.一些调用关于环境变量,状态,输入输出等调用由于使用频繁,默认不输出.
-V 输出strace的版本信息.
-x 以十六进制形式输出非标准字符串
-xx 所有字符串以十六进制形式输出.
-a column 设置返回值的输出位置.默认 为40.
-e expr 指定一个表达式,用来控制如何跟踪.格式如下:[qualifier=][!]value1[,value2]...
qualifier只能是 trace,abbrev,verbose,raw,signal,read,write其中之一.value是用来限定的符号或数字.默认的 qualifier是 trace.
感叹号是否定符号.例如:-e open等价于 -e trace=open,表示只跟踪open调用.而-etrace!=open表示跟踪除了open以外的其他调用.有两个特殊的符号 all 和 none.
注意有些shell使用!来执行历史记录里的命令,所以要使用\\.
-e trace=set 只跟踪指定的系统 调用.例如:-e trace=open,close,rean,write表示只跟踪这四个系统调用.默认的为set=all.
-e trace=file 只跟踪有关文件操作的系统调用.
-e trace=process 只跟踪有关进程控制的系统调用.
-e trace=network 跟踪与网络有关的所有系统调用.
-e strace=signal 跟踪所有与系统信号有关的 系统调用
-e trace=ipc 跟踪所有与进程通讯有关的系统调用
-e abbrev=set 设定 strace输出的系统调用的结果集.-v 等与 abbrev=none.默认为abbrev=all.
-e raw=set 将指 定的系统调用的参数以十六进制显示.
-e signal=set 指定跟踪的系统信号.默认为all.如 signal=!SIGIO(或者signal=!io),表示不跟踪SIGIO信号.
-e read=set 输出从指定文件中读出 的数据.例如:-e read=3,5
-e write=set 输出写入到指定文件中的数据.
-o filename 将strace的输出写入文件filename
-p pid 跟踪指定的进程pid.
-s strsize 指定输出的字符串的最大长度.默认为32.文件名一直全部输出.
-u username 以username 的UID和GID执行被跟踪的命令
3)使用实例:
1)跟踪可执行程序
strace -f -F -o ~/straceout.txt myserver
-f -F选项告诉strace同时跟踪fork和vfork出来的进程,-o选项把所有strace输出写到~/straceout.txt里 面,myserver是要启动和调试的程序。
2)跟踪服务程序
strace -o output.txt -T -tt -e trace=all -p 28979
跟踪28979进程的所有系统调用(-e trace=all),并统计系统调用的花费时间,以及开始时间(并以可视化的时分秒格式显示),最后将记录结果存在output.txt文件里面。
(2)跟踪进程栈(pstack)
此命令可显示每个进程的栈跟踪。pstack 命令必须由相应进程的属主或 root 运行。可以使用 pstack 来确定进程挂起的位置。此命令允许使用的唯一选项是要检查的进程的 PID。这个命令在排查进程问题时非常有用,比如我们发现一个服务一直处于work状态(如假死状态,好似死循环),使用这个命令就能轻松定位问题所在;可以在一段时间内,多执行几次pstack,若发现代码栈总是停在同一个位置,那个位置就需要重点关注,很可能就是出问题的地方;
1)用法:
# pstack PID
2)实例
$ps -ef | grep bash
tdev1 7013 7012 0 19:42 pts/1 00:00:00 -bash
tdev1 11402 11401 0 20:31 pts/2 00:00:00 -bash
tdev1 11474 11402 0 20:32 pts/2 00:00:00 grep bash
$pstack 7013
#0 0x00000039958c5620 in __read_nocancel () from /lib64/libc.so.6
#1 0x000000000047dafe in rl_getc ()
#2 0x000000000047def6 in rl_read_key ()
#3 0x000000000046d0f5 in readline_internal_char ()
#4 0x000000000046d4e5 in readline ()
#5 0x00000000004213cf in ?? ()
#6 0x000000000041d685 in ?? ()
#7 0x000000000041e89e in ?? ()
#8 0x00000000004218dc in yyparse ()
#9 0x000000000041b507 in parse_command ()
#10 0x000000000041b5c6 in read_command ()
#11 0x000000000041b74e in reader_loop ()
#12 0x000000000041b2aa in main ()
(3)strace和pstack配合使用
在分析程序运行时出现的问题时,可以先使用strace跟踪出具体耗时的系统调用,再到使用pstack查到程序中具体的耗时函数,一步步找到了影响程序运行时间的程序代码。
12、列出系统打开的文件(lsof)
lsof 是 linux 下的一个非常实用的系统级的监控、诊断工具。它的意思是 List Open Files,很容易你就记住了它是 “ls + of”的组合~它可以用来列出被各种进程打开的文件信息,记住:linux 下 “一切皆文件”,lsof打开的文件可以是:普通文件、目录、网络文件系统的文件、字符或设备文件、(函数)共享库、管道,命名管道、符号链接、网络文件(例如:NFS file、网络socket,unix域名socket)、还有其它类型的文件等等。因此,使用 lsof,你可以获取任何被打开文件的各种信息。只需输入 lsof 就可以生成大量的信息,因为 lsof 需要访问核心内存和各种文件,所以必须以 root 用户的身份运行它才能够充分地发挥其功能。
(1)命令格式:
命令格式:lsof [参数] [文件]
命令参数:
- -a 列出打开文件存在的进程
- -c<进程名> 列出指定进程所打开的文件
- -g 列出GID号进程详情
- -d<文件号> 列出占用该文件号的进程
- +d<目录> 列出目录下被打开的文件
- +D<目录> 递归列出目录下被打开的文件
- -n<目录> 列出使用NFS的文件
- -i<条件> 列出符合条件的进程。(4、6、协议、:端口、 @ip )
- -p<进程号> 列出指定进程号所打开的文件
- -u 列出UID号进程详情
- -h 显示帮助信息
- -v 显示版本信息
(2)使用示例(参考)
1)实例1:无任何参数:lsof
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,2 4096 2 /
init 1 root rtd DIR 8,2 4096 2 /
init 1 root txt REG 8,2 43496 6121706 /sbin/init
init 1 root mem REG 8,2 143600 7823908 /lib64/ld-2.5.so
init 1 root mem REG 8,2 1722304 7823915 /lib64/libc-2.5.so
init 1 root mem REG 8,2 23360 7823919 /lib64/libdl-2.5.so
init 1 root mem REG 8,2 95464 7824116 /lib64/libselinux.so.1
init 1 root mem REG 8,2 247496 7823947 /lib64/libsepol.so.1
。。。。
lsof输出各列信息的意义如下:
COMMAND:进程的名称
PID:进程标识符
PPID:父进程标识符(需要指定-R参数)
USER:进程所有者
PGID:进程所属组
FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等
(1)cwd:表示current work dirctory,即:应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改
(2)txt :该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的 /sbin/init 程序
(3)lnn:library references (AIX);
(4)er:FD information error (see NAME column);
(5)jld:jail directory (FreeBSD);
(6)ltx:shared library text (code and data);
(7)mxx :hex memory-mapped type number xx.
(8)m86:DOS Merge mapped file;
(9)mem:memory-mapped file;
(10)mmap:memory-mapped device;
(11)pd:parent directory;
(12)rtd:root directory;
(13)tr:kernel trace file (OpenBSD);
(14)v86 VP/ix mapped file;
(15)0:表示标准输出
(16)1:表示标准输入
(17)2:表示标准错误
一般在标准输出、标准错误、标准输入后还跟着文件状态模式:r、w、u等
(1)u:表示该文件被打开并处于读取/写入模式
(2)r:表示该文件被打开并处于只读模式
(3)w:表示该文件被打开并处于
(4)空格:表示该文件的状态模式为unknow,且没有锁定
(5)-:表示该文件的状态模式为unknow,且被锁定
同时在文件状态模式后面,还跟着相关的锁
(1)N:for a Solaris NFS lock of unknown type;
(2)r:for read lock on part of the file;
(3)R:for a read lock on the entire file;
(4)w:for a write lock on part of the file;(文件的部分写锁)
(5)W:for a write lock on the entire file;(整个文件的写锁)
(6)u:for a read and write lock of any length;
(7)U:for a lock of unknown type;
(8)x:for an SCO OpenServer Xenix lock on part of the file;
(9)X:for an SCO OpenServer Xenix lock on the entire file;
(10)space:if there is no lock.
TYPE:文件类型,如DIR、REG等,常见的文件类型
(1)DIR:表示目录
(2)CHR:表示字符类型
(3)BLK:块设备类型
(4)UNIX: UNIX 域套接字
(5)FIFO:先进先出 (FIFO) 队列
(6)IPv4:网际协议 (IP) 套接字
DEVICE:指定磁盘的名称
SIZE:文件的大小
NODE:索引节点(文件在磁盘上的标识)
NAME:打开文件的确切名称
2)实例2:查看谁正在使用某个文件,也就是说查找某个文件相关的进程:lsof /bin/bash
3)实例3:递归查看某个目录的文件信息:lsof test/test3
4)实例4:不使用+D选项,遍历查看某个目录的所有文件信息的方法:lsof | grep 'test/test3'
5)实例5:列出某个用户打开的文件信息:lsof -u username # -u 选项,u其实是user的缩写
6)实例6:列出某个程序进程所打开的文件信息:lsof -c mysql # 说明: -c 选项将会列出所有以mysql这个进程开头的程序的文件,其实你也可以写成 lsof | grep mysql, 但是第一种方法明显比第二种方法要少打几个字符了
7)实例7:列出多个进程多个打开的文件信息:lsof -c mysql -c apache
8)实例8:列出某个用户以及某个进程所打开的文件信息:lsof -u test -c mysql # 用户与进程可相关,也可以不相关
9)实例9:列出除了某个用户外的被打开的文件信息:lsof -u ^root # 说明:^这个符号在用户名之前,将会把是root用户打开的进程不让显示
10)实例10:通过某个进程号显示该进行打开的文件:lsof -p 1
11)实例11:列出多个进程号对应的文件信息:lsof -p 1,2,3
12)实例12:列出除了某个进程号,其他进程号所打开的文件信息:lsof -p ^1
13)实例13:列出所有的网络连接:lsof -i
14)实例14:列出所有tcp 网络连接信息:lsof -i tcp
15)实例15:列出所有udp网络连接信息:lsof -i udp
16)实例16:列出谁在使用某个端口:lsof -i :3306
17)实例17:列出谁在使用某个特定的udp端口:lsof -i udp:55 或者:特定的tcp端口:lsof -i tcp:80
18)实例18:列出某个用户的所有活跃的网络端口:lsof -a -u test -i
19)实例19:列出所有网络文件系统:lsof -N
20)实例20:域名socket文件:lsof -u
21)实例21:某个用户组所打开的文件信息:lsof -g 5555
22)实例22:根据文件描述列出对应的文件信息:lsof -d description(like 2),例如:lsof -d txt、lsof -d 1、lsof -d 2 #说明:0表示标准输入,1表示标准输出,2表示标准错误,从而可知:所以大多数应用程序所打开的文件的 FD 都是从 3 开始
23)实例23:根据文件描述范围列出文件信息:lsof -d 2-3
24)实例24:列出COMMAND列中包含字符串" sshd",且文件描符的类型为txt的文件信息:lsof -c sshd -a -d txt
25)实例25:列出被进程号为1234的进程所打开的所有IPV4 network files :lsof -i 4 -a -p 1234
26)实例26:列出目前连接主机peida.linux上端口为:20,21,22,25,53,80相关的所有文件信息,且每隔3秒不断的执行lsof指令:lsof -i @peida.linux:20,21,22,25,53,80 -r 3
参考:https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html