首页
社区
课程
招聘
[原创]linux常用命令
发表于: 2022-7-7 10:02 6153

[原创]linux常用命令

2022-7-7 10:02
6153

1、cp命令

	cp dir1/a.doc dir2 表示将dir1下的a.doc文件复制到dir2目录下
	cp -r dir1 dir2 表示将dir1及其dir1下所包含的文件复制到dir2下
	cp -r dir1/. dir2 表示将dir1下的文件复制到dir2,不包括dir1目录

	说明:cp参数 -i:询问,如果目标文件已经存在,则会询问是否覆盖;


2、文件移动mv

	说明:目标目录与原目录一致,指定了新文件名,效果就是仅仅重命名。
	目标目录与原目录不一致,没有指定新文件名,效果就是仅仅移动。
	目标目录与原目录不一致,指定了新文件名,效果就是:移动 + 重命名。
	2.1 重命名(同一目录下,AAA重新命名为BBB)
		mv AAA BBB 
	2.2 移动当前目录的sal到mnt/sal
		mv sal /mnt/sal


3、rm命令

	强制递归删除目录 
		rm -rf TestPro
	强制删除文件夹内的log文件
		rm -f *.log


4、mkdir

新建sal目录: mkdir sal


5、查看文件ls或者ll命令

    5.1 按照时间排序
		ll -t	由新到旧
		ll -rt	有旧到新
	5.2 按照文件大小排序
		ll -Sh  由大到小排序(可读的方式)
		ll -Sr  由小到大排序(可读的方式)
	5.3 查看详细信息
		ls -l 除文件名称外,亦将文件型态、权限、拥有者、文件大小等资讯详细列出
		ll		同上:ls -l命令


6、查看工作目录

    pwd

7、改变权限chmod

	备注:a代表all所有用户,u代表文件拥有者,g代表和拥有同组的用户,o代表其他用户。
	r代表读,w代表写权限,x代表执行权限。+代表增加,-代表减少,=代表赋予
		chomod 777 file
		chmod a+r file	给file的所有用户增加读权限
		chmod a-x file	删除file的所有用户的执行权限
		chmod a+rw file	给file的所有用户增加读写权限
		chmod +rwx file	给file的所有用户增加读写执行权限
		chmod u=rw,go= file	对file的所有者设置读写权限,清空该用户组和其他用户对file的所有权限(空格代表无权限)
		chmod -R u+r,go-r docs	对目录docs和其子目录层次结构中的所有文件给用户增加读权限,而对用户组和其他用户删除读权限
		chmod 664 file	对file的所有者和用户组设置读写权限, 为其其他用户设置读权限
		chmod 0755 file	相当于u=rwx (4+2+1),go=rx (4+1 & 4+1)。0 没有特殊模式。
		chmod 4755 file	4设置了设置用户ID位,剩下的相当于 u=rwx (4+2+1),go=rx (4+1 & 4+1)。
		find path/ -type d -exec chmod a-x {} \;	删除可执行权限对path/以及其所有的目录(不包括文件)的所有用户,使用'-type f'匹配文件
		find path/ -type d -exec chmod a+x {} \;	允许所有用户浏览或通过目录path/


8、查看进程信息ps

	ps -ef |grep hello
	ps -aux |grep hello
	指令: ps
	作用: 主要是查看服务器的进程信息
	选项含义:
	-e:等价于 ‘-A’ ,表示列出全部的进程
	-f:显示全部的列(显示全字段


9、用ssh命令连接linux虚拟机

ssh sanganlei@192.168.116.158



10、su命令

	命令格式:su 用户名
	[sanganlei@localhost ~]$ su root
	Password: 
	[root@localhost sanganlei]#


11、vim使用

	a) 快捷键
		j 下一行, k 上一行,g第一行,G最后一行
		dd 删除光标所在行
		ndd :删除 n 行
		yy:复制当前行
		p:粘贴
		ggvG:全选
		gg:移动到文件头部位置
		G:移动到文件末尾
		nG:移动到 n 行,10G 即移动到文件第十行
		$:跳转到当前行末尾
		^:跳转到当前行开头
		a:进入编辑模式,插入内容位置在光标的后面
		复制此文件所有内容:
			ggvG 全选 + y 复制 + p 粘贴
		复制多行:
			1、v 进入可视模式(先按下Esc),通过移动光标选择目标,按 y 复制,p 粘贴
			2、输入: 进入命令行模式,输入 15 20 copy 21, 即将从第十五行到第二十行的内容从第二十一行开始复制

	b)vim显示行号
		:set nu 
	c)vim搜索字符串,按下小写的n下一个,大写的N上一个搜索结果
		:/ abcdef	
	d)替换字符串
		基本语法是 		
			:[range]s/目标字符串/替换字符串/[option]
		备注:其中range和option字段都可以缺省不填。
		参数说明:
			range:表示搜索范围,默认表示当前行;
				  range字段值1,10表示从第1到第10行;
				  %表示整个文件(相当于1,$);
				  而  .,$  代表从当前行到本文件的末尾
			s:substitute的简写,表示执行替换字符串操作
			option:表示操作类型,默认只对第一个匹配的字符进行替换
				option字段值g(global)表示全局替换;
				c(comfirm)表示操作时需要确认;
				i(ignorecase)表示不区分大小写;
		替换命令举例
			a)替换每一行中所有 vivian 为 sky
				:%s/vivian/sky/g
			b)将从2行到10行中出现的所有包含line的字符串中的line替换为lines
				:2,10s/line/lines/g表示将2~3行的line全局替换为lines
			c)全文的行首加入//字符,批量注释时非常有用
				:%s/^/\/\//表示在全文范围行首替换插入//,注意在Vim中需要将/进行转义后才可以替换
			d)替换当前行所有 vivian 为 sky
				:s/vivian/sky/g 
			e)替换第 n 行开始到最后一行中每一行的第一个 vivian 为 sky		
				:n,$s/vivian/sky/ 
			f)替换第 n 行开始到最后一行中每一行所有 vivian 为 sky
				:n,$s/vivian/sky/g 			
			g)替换每一行的第一个 vivian 为 sky		
				:%s/vivian/sky/
			h)将光标所在行出现的所有包含line的字符串中line替换为lines
				:s/line/lines/g表示将光标所在当前行的line全局替换为lines


12、查看网络配置

        ifconfig

13、linux查找命令

	a)查找/data目录下的txt文件
		find /data -name "*.txt"
	b)在根目录下查找a.txt
		find / -name a.txt
	c)在当前目录下查找a.txt
		find . -name file.txt
	d)-group:按照文件所属的组来查找文件。在home目录下查询所属组为 root 的文件
		find /home -group root
	e)-user:按照文件的属主来查找文件。在home目录下查询所有者为 root 的文件
		find /home -user root
	f)-type 根据文件类型查找,f表示文件,d表示目录,l表示软链接。如查找 /home 目录下文件类型是目录
		find /home -type d
	g)用find命令查找到了文件,输出的方式有以下两种
		find / -name '*.txt'  >a.txt
		find / -name '*.txt'  -print >a.txt,
        h)根据文件名查找
                find /usr -name "*osg*"


14、查看centos内核

        uname -r

15、查看centos版本

        cat /etc/centos-release

16、linux更新内核版本

	以CentOS6.9内核2.6.32-696.el6.x86_64更换内核2.6.32-696.6.3.el6.x86_64为例

	(1)下载kernel-2.6.32-696.6.3.el6.x86_64.rpm,在https://vault.centos.org/网站下载对应的内核版本
	(2). 查看内核版本
	uname -r
	(3). 查看rpm包
	rpm -qa | grep kernel 
	(4). 删除旧内核
	yum remove kernel-2.6.32-696.el6.x86_64  
	(5). 安装新内核
	rpm -ivh kernel-2.6.32-696.6.3.el6.x86_64.rpm --force --nodeps
	(6). reboot 重启
	(7). uname -r


17、动态查看日志文件

        tail -f filename.log

18、linux多个内核,更改内核启动顺序

	1、查看默认启动顺序
		awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg
	2、查看当前默认内核启动项grub2-editenv list
	3、更改默认启动内核项
		grub2-set-default 1(这个根据第2点查看的结果选你要进入的内核)


19、查看linux内核驱动模块

 	19.1、查看内核模块
		lsmod |grep fc
	19.2、卸载驱动模块
		rmmod fccore_a
		rmmod fccore_a fccore_s fccore_r fccore fchook
	19.3、加载驱动模块
		insmod fccore_a


20、scp远程拷贝命令

(拷贝本机器的b.txt文件到远程机器192.168.116.184的/root目录)

        scp b.txt root@192.168.116.184:/root

21、ssh连接

        一定不要忘了最后的22是远程机器的端口号。

        ssh root@192.168.116.184 22

22、 crontab 定期执行程序

    语法:crontab [ -u user ] file
    或者crontab [ -u user ] { -l | -r | -e }
    说明:
            -e : 执行文字编辑器来设定时程表
            -r : 删除目前的时程表
            -l : 列出目前的时程表

            *    *    *    *    *
            -    -    -    -    -
            |    |    |    |    |
            |    |    |    |    +----- 星期中星期几 (0 - 6) (星期天 为0)
            |    |    |    +---------- 月份 (1 - 12) 
            |    |    +--------------- 一个月中的第几天 (1 - 31)
            |    +-------------------- 小时 (0 - 23)
            +------------------------- 分钟 (0 - 59)
    例子:
        每一分钟执行一次 /bin/ls:
            * * * * * /bin/ls
        在 12 月内, 每天的早上 6 点到 12 点,每隔 3 个小时 0 分钟执行一次 /usr/bin/backup:
            0 6-12/3 * 12 * /usr/bin/backup
        周一到周五每天下午 5:00 寄一封信给 alex@domain.name:
            0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata
        每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha":
            20 0-23/2 * * * echo "haha"

23、查看程序依赖的库

	ldd DemoWork1
	ldd -r DemoWork1


24、查看是否成功加载某个so

     如何查看已经运行起来的程序,是否成功加载某个so文件

	a)ps -ef |grep demo.out查看进程id
	b)cd /proc/进程id
	c)cat maps

25、gdb设置源代码路径

	1、显示gdb搜索的源代码路径
		show dir
	2、设置源代码路径
	   a)调试时递归设置源代码路径(用这种最好,省事,非递归的麻烦)
			gdb `find /root/projects -type d -printf '-d %p '` DemoWork1
			gdb -q DemoWork1 `find /root/projects/ -type d -printf '-d %p '`
			有的版本的 find不支持  -printf选项,此时,可以用下面的方法:
				gdb `find . -type d | xargs printf " -d %s"`  DemoWork1
		b)非递归设置源代码路径
			dir srcpath
	3、清除源代码路径
		dir


26、gdb调试(A机编译,B机调试)

     (动态库文件libadd.so在B机器上编译的。要在A机器上源码调试libadd.so)

		备注:要想源代码调试某个动态库,在生成动态库时,必须加上 -g选项,否则无法源码调试。
		a)调试testSO.out指定源代码路径
			gdb `find /root/projects/sosrc -type d -printf '-d %p '` testSO.out
		b)显示源代码路径
			show dir

27、查看端口是否占用

            netstat -ano|grpe 8080

28、查看符号二进制文件的符号

            nm exeOrSo |grep funName

            readelf -s libNetCommunicate.so

29、gdb查看加载的动态库的信息

	a)显示所有已经加载的动态库信息
		info shared
	b)显示某个已经加载的动态库信息
		info shared libtgcDefender.so

30、gdb调试给动态库加载符号

            sharedlibrary myso

31、gdb调试(A机编译,B机调试)

                 (A电脑上编译的。B机器上调试)

		备注:要想源代码调试某个动态库,在生成动态库时,必须加上 -g选项,否则无法源码调试。
		a)调试DemoWork时指定源代码路径
			gdb `find /root/projects -type d -printf '-d %p '` DemoWork
		b)显示源代码路径
			show dir

32、Linux链接概念

	Linux链接分两种,
		一种被称为硬链接(Hard Link),另一种被称为符号链接(Symbolic Link)。默认情况下,使用 ln 命令不加参数创建硬链接,
			加 -s 参数则创建软链接。
        硬链接:
			相当于创建了源文件的副本,不会随着源文件的删除而消失,会随着源文件内容的更改而更改;
			即让多个不在或者同在一个目录下的文件名,同时能够修改同一个文件,其中一个修改后,所有与其有硬链接的文件都一起修改了。
        软链接:
			软链接也称之为符号链接(Symbolic Link)。这个文件包含了另一个文件的路径名。
			可以是任意文件或目录,可以链接不同文件系统的文件。软链接类似于 Windows的快捷方式。 
 

		[root@user ~]# touch f1             # 创建文件 f1 
		[root@user ~]# ln f1 f2               # 创建 f1 的一个硬链接文件f2
		[root@user ~]# ln -s f1 f3           # 创建 f1 的一个软链接文件f3
		[root@user ~]# ls -li                    # -i参数显示文件的inode节点信息
			total 24
		17567 -rw-------. 1 root root 1115 Jan  9  2014 anaconda-ks.cfg
	  175 -rw-r--r--. 1 root root 3486 Aug 18  2014 cloud-set-guest-password
	  235 -rw-r--r--. 2 root root    0 Mar 14 12:18 f1
	  235 -rw-r--r--. 2 root root    0 Mar 14 12:18 f2
	  237 lrwxrwxrwx. 1 root root    2 Mar 14 12:14 f3 -> f1
	   49 -rw-r--r--. 1 root root 8526 Jan  9  2014 install.log
	   67 -rw-r--r--. 1 root root 3314 Jan  9  2014 install.log.syslog
		通过上面的测试可以看出:硬链接文件 f2 与源文件f1的 inode 节点均为 235,软链接 f3 则与两者的 inode 不同。
		[root@user ~]# echo "I am f1" >> f1
		[root@user ~]# cat f1
		I am f1 
		[root@user ~]# cat f2
		I am f1
		[root@user ~]# cat f3
		I am f1
		[root@user ~]# rm -f f1
		[root@user ~]# cat f2
		I am f1
		[root@user ~]# cat f3
		cat: f3: No such file or directory
		通过上面的测试可以看出:当删除原始文件 f1 后,硬链接 f2 不受影响,但是软链接 f1 文件失效


33、lsof命令

	a)列出所有打开的文件:
		lsof
		备注: 如果不加任何参数,就会打开所有被打开的文件,建议加上一下参数来具体定位

	b)查看谁正在使用某个文件
		lsof   /filepath/file

	c)递归查看某个目录的文件信息
		lsof +D /filepath/filepath2/
		备注: 使用了+D,对应目录下的所有子目录和文件都会被列出

	d)比使用+D选项,遍历查看某个目录的所有文件信息 的方法
		lsof | grep ‘/filepath/filepath2/’

	e)列出某个用户打开的文件信息
		lsof  -u username
		备注: -u 选项,u其实是user的缩写

	f)列出某个程序所打开的文件信息
		lsof -c mysql
		备注: -c 选项将会列出所有以mysql开头的程序的文件,其实你也可以写成lsof | grep mysql,但是第一种方法明显比第二种方法要少打几个字符了

	g)列出多个程序多打开的文件信息
		lsof -c mysql -c apache

	h)列出某个用户以及某个程序所打开的文件信息
		lsof -u test -c mysql

	i)列出除了某个用户外的被打开的文件信息
		lsof   -u ^root
		备注:^这个符号在用户名之前,将会把是root用户打开的进程不让显示

	j)通过某个进程号显示该进行打开的文件
		lsof -p 1

	k)列出多个进程号对应的文件信息
		lsof -p 123,456,789

	l)列出除了某个进程号,其他进程号所打开的文件信息
		lsof -p ^1

	m)列出所有的网络连接
		lsof -i

	n)列出所有tcp 网络连接信息
		lsof  -i tcp

	o)列出所有udp网络连接信息
		lsof  -i udp

	p)列出谁在使用某个端口
		lsof -i :3306

	q)列出谁在使用某个特定的udp端口
		lsof -i udp:55

	r)特定的tcp端口
		lsof -i tcp:80

	s)列出某个用户的所有活跃的网络端口
		lsof  -a -u test -i

	t)列出所有网络文件系统
		lsof -N

	u)域名socket文件
		lsof -u

	v)某个用户组所打开的文件信息
		lsof -g 5555

	w)根据文件描述列出对应的文件信息
		lsof -d description(like 2)

	x)根据文件描述范围列出文件信息
		lsof -d 2-3

34、centos安装gtest

	sudo yum install epel-release
	sudo yum install dnf
	sudo dnf install dnf-plugins-core
	sudo dnf install gtest gtest-devel
	sudo find /usr -name gtest.h
		/usr/include/gtest/gtest.h


35、查看可执行程序的系统调用

strace 可执行程序名字


36、查看程序进程栈

	命令:		pstack 进程id
	使用例子:
	/opt/app/tdev1$ps -fe| 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
	/opt/app/tdev1$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 ()

37、解压和压缩命令

	以下是压缩命令:
		a)把/home目录下面的data目录压缩为data.zip
			zip -r data.zip data #压缩data目录

		b)把/home目录下面的a文件夹和3.txt压缩成为a123.zip
			zip -r a123.zip a 3.txt

	以下是解压命令:
		a)把文件解压到当前目录下
			unzip test.zip
		b)如果要把文件解压到指定的目录下,需要用到-d参数。
			unzip -d /temp test.zip
		c)解压的时候,有时候不想覆盖已经存在的文件,那么可以加上-n参数
			unzip -n test.zip
			unzip -n -d /temp test.zip
		d)解压的时候,想覆盖已经存在的文件,那么可以加上-o参数	
			unzip -o -d /home/test_monitor_dir/  /home/test_monitor_dir/laosang.zip
		e)只看一下zip压缩包中包含哪些文件,不进行解压缩
			unzip -l test.zip

38、抓包命令

   a)抓取源地址为192.168.29.162的报文
		tcpdump -i eth1 src host 192.168.29.162

   b)抓取目的地址为192.168.29.162报文
		tcpdump -i eth1 dst host 192.168.29.162
	
   c)抓取当前服务器eth0网卡端口8080的网络数据
		tcpdump -n -i eth0 port 8080
		
   d)抓取当前服务器eth0网卡端口8080的网络数
		tcpdump -i any udp port 5236 and dst host 172.16.24.13 -w dm.cap
		备注	-i指定网卡(用ifconfig命令)
				-w抓的包写入到文件
				src hsot 源地址
				dst host 目的地址
				src port 源端口
				dst port 目的端口
				and      逻辑与
				or       逻辑或

39、linux服务命令

	1、查看命令帮助
		systemctl --help
	2、启动服务
		systemctl start 服务名
	3、查看服务状态
		systemctl status 服务名
	4、停止服务
		systemctl stop 服务名
	5、查看服务是否活跃
		systemctl is-active 服务名
	6、重新加载服务配置
		reload是在不重启服务的情况下重新加载配置文件
		systemctl reload 服务名
	7、重启服务
		restart命令实际上是先stop,然后start。
		systemctl restart 服务名
	8、查看可用systemctl管理的所有服务
		systemctl list-units --type=service
	9、注销服务
		服务被注销后该服务就无法通过systemctl进行启停管理。
			注销服务:
				systemctl mask 服务名
			再次启动试试(无法启动)
				systemctl start 服务名
	10、取消注销服务
			取消注销服务:
				systemctl unmask 服务名
			再次启动试试(可以启动)
				systemctl start 服务名
	11、设置服务开机自启动
		systemctl enable 服务名
	12、取消服务开机自启动
		systemctl disable 服务名
	13、查看服务是否开机自启动
		systemctl is-enabled 服务名
	14、杀死服务
		systemctl kill 服务名
		systemctl is-failed 服务名

40、查看麒麟版本

lsb_release -a

41、银河麒麟之命令行下配置网卡及DNS

	https://zhuanlan.zhihu.com/p/531250079
		ubuntu/debian 系统安装方法:

42、安装curl

	ubuntu/debian 系统安装方法:
		apt-get update -y && apt-get install curl -y

	centos 系统安装方法:
		yum update -y && yum install curl -y

43、du 命令:

  查看当前目录和子目录文件夹/文件大小情况

	du = disk usage 磁盘使用率,输出每个文件或者目录总大小
	# 查看当前目录的总大小
	$ du -sh  
	# 查看当前目录所有子目录的大小
	$ du -sh * 
	# 查看当前目录和所有子目录大小,最后一行会显示当前目录的总大小,不包括隐藏文件
	$ du -ach *
	# du -sh 目录路径
	$ du -sh /usr

44、df 命令

    用于显示磁盘分区上的可使用的磁盘空间

	df = disk free 命令用于显示磁盘分区上的可使用的磁盘空间
	
	# 以可读性高的结果展示磁盘分区上的可使用的磁盘空间
	$ df -h

45、Linux下如何查看高CPU占用率线程

	可以用下面的命令将 cpu 占用率高的线程找出来:
	 ps H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu

	这个命令首先指定参数'H',显示线程相关的信息,格式输出中包含:user,pid,ppid,tid,time,%cpu,cmd,
	然后再用%cpu字段进行排序。这样就可以找到占用处理器的线程了。

	直接使用 ps Hh -eo pid,tid,pcpu | sort -nk3 |tail 获取对于的进程号和线程号,然后跳转到3.
	查看哪个进程线程占用cpu过高; top / ps -aux, 获得进程号
	确定哪个线程占用cpu过高,进入进程号的目录:/proc/pid/task, 
	执行:grep SleepAVG  **/status  | sort -k2,2 | head,  确定cpu占用较高的线程号。
	使用kill -3 pid 会打印线程堆栈的情况
	在 Linux 下 top 工具可以显示 cpu 的平均利用率(user,nice,system,idle,iowait,irq,softirq,etc.),
	可以显示每个 cpu 的利用率。但是无法显示每个线程的 cpu 利用率情况,这时就可能出现这种情况,
	总的 cpu 利用率中 user 或 system 很高,但是用进程的 cpu 占用率进行排序时,没有进程的 user 或 system 与之对应。
	把以下文件保存到cpu.sh可实时显示每个线程的cpu占用率:
		#!/bin/sh

		while true
		do
				ps -H -eo user,pid,ppid,tid,time,%cpu,cmd --sort=%cpu
				sleep 1
		done

46、定位cpu占用率方法

	1、拷贝以下代码,创建gstack文件(没有扩展名),使用dos2unix命令,转换为linux格式
		执行命令chmod 777 gstack, 
		执行命令:cp gstack  /usr/bin/
			#!/bin/sh
			if test $# -ne 1; then
				echo "Usage: `basename $0 .sh` <process-id>" 1>&2
				exit 1
			fi
			 
			if test ! -r /proc/$1; then
				echo "Process $1 not found." 1>&2
				exit 1
			fi
			 
			# GDB doesn't allow "thread apply all bt" when the process isn't
			# threaded; need to peek at the process to determine if that or the
			# simpler "bt" should be used.
			 
			backtrace="bt"
			if test -d /proc/$1/task ; then
				# Newer kernel; has a task/ directory.
				if test `/bin/ls /proc/$1/task | /usr/bin/wc -l` -gt 1 2>/dev/null ; then
				backtrace="thread apply all bt"
				fi
			elif test -f /proc/$1/maps ; then
				# Older kernel; go by it loading libpthread.
				if /bin/grep -e libpthread /proc/$1/maps > /dev/null 2>&1 ; then
				backtrace="thread apply all bt"
				fi
			fi
			 
			GDB=${GDB:-/usr/bin/gdb}
			 
			if $GDB -nx --quiet --batch --readnever > /dev/null 2>&1; then
				readnever=--readnever
			else
				readnever=
			fi
			 
			# Run GDB, strip out unwanted noise.
			$GDB --quiet $readnever -nx /proc/$1/exe $1 <<EOF 2>&1 | 
			set width 0
			set height 0
			set pagination no
			$backtrace
			EOF
			/bin/sed -n \
				-e 's/^\((gdb) \)*//' \
				-e '/^#/p' \
				-e '/^Thread/p'
			#end
	2、top命令查出cpu占有率高的进程id,这里调查的70957进程
		执行命令:top
			 PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
			70894 root      20   0  156880   5568   4228 S  16.6  0.1   1:09.35 sshd                                                                        
			 70957 root      20   0   25172   1136    948 S   3.7  0.0   0:14.75 cleanupDB.out                                                               
			 56208 root      20   0       0      0      0 S   0.7  0.0   0:06.96 kworker/2:0                                                                 
			 69769 root      20   0       0      0      0 S   0.7  0.0   0:02.92 kworker/3:2                                                                 
				18 root      20   0       0      0      0 S   0.3  0.0   0:13.50 ksoftirqd/2                                                                 
	
	3、用top -H -p pid命令查看进程内各个线程占用的CPU百分比
	   假如cpu占用率高的进程id为14094
		执行命令:top -H -p 70957
		第一列是两个线程id,70958这个线程占用的cpu比较高。
		控制台输出:
			PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND  
			70958 root      20   0   25172   1136    948 S  3.7  0.0   0:18.52 cleanupDB.out                                                                
			70957 root      20   0   25172   1136    948 S  0.0  0.0   0:00.00 cleanupDB.out 
			
		
	4.使用gstack命令查看进程中各线程的函数调用栈
		执行命令:gstack 70957 > gstack.log
		在gstack.log中查找线程ID为70958,由于函数栈会暴露函数细节,因此只显示了两个函数桢,线程ID 70958对应线程号是2
			Thread 2 (Thread 0x7fde4a882700 (LWP 70958)):
			#0  0x00007fde4a972bbd in write () from /lib64/libc.so.6
			#1  0x00007fde4a8fd2f3 in _IO_new_file_write () from /lib64/libc.so.6
			#2  0x00007fde4a8feb0e in __GI__IO_do_write () from /lib64/libc.so.6
			#3  0x00007fde4a8fda50 in __GI__IO_file_xsputn () from /lib64/libc.so.6
			#4  0x00007fde4a8f27e2 in fwrite () from /lib64/libc.so.6
			#5  0x00007fde4b1ffbb5 in std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) () from /lib64/libstdc++.so.6
			#6  0x00007fde4b1ffeb7 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /lib64/libstdc++.so.6
			#7  0x000000000040242c in funA() ()
			#8  0x000000000040243c in test() ()
			#9  0x0000000000403a0b in void std::_Bind_simple<void (*())()>::_M_invoke<>(std::_Index_tuple<>) ()
			#10 0x0000000000403965 in std::_Bind_simple<void (*())()>::operator()() ()
			#11 0x00000000004038fe in std::thread::_Impl<std::_Bind_simple<void (*())()> >::_M_run() ()
			#12 0x00007fde4b21e330 in execute_native_thread_routine () from /lib64/libstdc++.so.6
			#13 0x00007fde4b478ea5 in start_thread () from /lib64/libpthread.so.0
			#14 0x00007fde4a981b0d in clone () from /lib64/libc.so.6
			Thread 1 (Thread 0x7fde4ba96740 (LWP 70957)):
			#0  0x00007fde4a972b5d in read () from /lib64/libc.so.6
			#1  0x00007fde4a8fed54 in __GI__IO_file_underflow () from /lib64/libc.so.6
			#2  0x00007fde4a8fff22 in __GI__IO_default_uflow () from /lib64/libc.so.6
			#3  0x00007fde4a8fa8fa in getchar () from /lib64/libc.so.6
			#4  0x0000000000402464 in main ()
		
	5.使用gcore命令转存进程映像及内存上下文
		执行命令:gcore 70957
		该命令生成core文件core.70957
		
	6、用strace命令查看系统调用和花费的时间
		执行命令:strace -T -r -c -p 70957
		-c参数显示统计信息,去掉此参数可以查看每个系统调用话费的时间及返回值。
	7.用gdb调试core文件,并线程切换到37号线程
		gcore和实际的core dump时产生的core文件几乎一样,只是不能用gdb进行某些动态调试
		切换到2号线程,并查看其调用堆栈
		(gdb) gdb yourAppName core.70957
		(gdb) thread 2
		[Switching to thread 2 (Thread 0x7fde4a882700 (LWP 70958))]
		(gdb) bt

47、火焰图调查性能瓶颈位置

	1、安装perf和可视化生成器
		1.1 yum方式安装perf
			yum install perf -y           
		1.2 下载生成火焰图工具
			git clone https://github.com/brendangregg/FlameGraph.git  
			选择好火焰图文件存放路径后执行该条命令,从github上获取火焰图的相关文件,
			获取完成后会有一个FlameGraph的文件夹,如下图
	2、生成监视记录文件
		1.3 生成监视记录文件perf.data
			perf record -F 99 -p 7778 -g -- sleep 60
			备注:
				上述代码中perf record表示记录,-F 99表示每秒99次,-p 7778是进程号,即对哪个进程进行分析,
				-g表示记录调用栈,sleep 30则是持续30秒,-a 表示记录所有cpu调用。更多参数可以执行perf --help查看。
				perf.data文件生成后,表示采集完成。最好是在火焰图的目录下进行采集,方便转换成SVG图形。
	3、生成火焰图
			perf script -i perf.data &> perf.unfold                        //生成脚本文件
			./FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded              
			./FlameGraph/flamegraph.pl perf.folded > perf.svg 
		备注:	
			y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,
			顶部就是正在执行的函数,下方都是它的父函数。
			x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。
			注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
			火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题。

48、查看内核日志

dmesg -w

49、perf分析高CPU进程

	1.perf top
	类似于 top,它能够实时显示占用 CPU 时钟最多的函数或者指令,因此可以用来查找热点函数
	第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。
	第二列 Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),
	如内核、进程名、动态链接库名、内核模块名等。
	第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动
	态链接库,而 [k] 则表示内核空间。
	最后一列 Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表

	示。
	分析命令 :perf top -g -p XXX
	-g 开启调用关系分析,-p 指定 进程号 XXX

50、strace跟踪系统调用

	50.1 获取命令帮助
		strace -h

	50.2 直接在命令前面加上strace命令就可以跟踪命令的执行过程了
		例如strace跟踪ls -h命令
		直接在命令前面加上strace命令就可以跟踪命令的执行过程了,会详细的显示命令过程中执行的命令、
		系统调用、进程接收的信号等。
		命令: strace ls -h
		以下为strace跟踪ls -h命令的输出结果:
			user01@user01-VMware-Virtual-Platform:~/桌面$ strace ls -h
			execve("/usr/bin/ls", ["ls", "-h"], 0x7ffcfd9e9198 /* 54 vars */) = 0
			brk(NULL)                               = 0x55df001ad000
			arch_prctl(0x3001 /* ARCH_??? */, 0x7ffcaa5e71d0) = -1 EINVAL (无效的参数)
			access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (没有那个文件或目录)

	50.3 strace命令跟踪统计结果简洁显示
		使用-c参数可以显示strace命令的统计结果,显示命令执行了哪些系统调用信号、耗时、各系统调用次数等。
		命令:strace  -c ls -h
		以下为使用上述命令的输出结果:
			user01@user01-VMware-Virtual-Platform:~/桌面$ strace  -c ls -h
			1  2  cn.lanxin.desktop  fc-linux-install-x86_64  install_conf.toml
			% time     seconds  usecs/call     calls    errors syscall
			------ ----------- ----------- --------- --------- ----------------
			 21.48    0.001213         121        10         1 openat
			 20.75    0.001172          43        27           mmap
			  9.45    0.000534          59         9           mprotect
			  8.87    0.000501          62         8           pread64
			  7.49    0.000423          38        11           close
			  7.47    0.000422          42        10           fstat
	50.4 查看openat等系统调用类型(筛选查看指定的系统调用)
		strace默认查看所有调用信号,使用-e参数可以查看指定类型的调用,减少输出信息。
		支持的信号包括:trace, abbrev, verbose, raw, signal, read, write, fault, inject, kvm等
		命令:strace -e openat ls -h
		以下为使用上述命令的输出结果:
			openat(AT_FDCWD, "/dev/cur_gl", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
			openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
			openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
			1  1.txt  2  cn.lanxin.desktop	fc-linux-install-x86_64  install_conf.toml
			+++ exited with 0 +++
			
	50.5、显示时间戳
		strace输出默认是没有时间信息的,使用-t或者-tt参数我们可以打印命令执行的时间,精确到毫秒。
		命令:strace -t -e openat ls -h
		以下为使用上述命令的输出结果:
			root@user01-VMware-Virtual-Platform:/home/user01/桌面# strace -t -e openat ls -h
			11:41:45 openat(AT_FDCWD, "/dev/cur_gl", O_RDONLY|O_CLOEXEC) = -1 ENOENT (没有那个文件或目录)
			11:41:45 openat(AT_FDCWD, "/proc/filesystems", O_RDONLY|O_CLOEXEC) = 3
			11:41:45 openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
			11:41:45 openat(AT_FDCWD, ".", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
			1  1.txt  2  cn.lanxin.desktop	fc-linux-install-x86_64  install_conf.toml
			11:41:45 +++ exited with 0 +++

	50.6、将strace结果输出到指定文件
		 如果希望保存strace命令执行的结果,我们可以使用-o参数将内容输出到指定文件。
		 命令:strace -t -o ./strace.log ls -h
		 
		 
	50.7、跟踪正在运行的进程
		 如果是排查已经正在运行的进程的问题,我们可以使用-p参数跟踪指定进程的系统信号调用。
		a)查询要跟踪的进程pid命令:ps -ef|grep 进程名
		b)跟踪正在运行的进程
			1、显示时间戳
				strace -t -p 进程pid
			2、或者命令(显示时间戳、跟踪fork):					
				strace -t  -f -p 进程pid
			3、获取命令(显示时间戳、系统调用栈回溯、保存到文件)
				strace -t -o ./strace_tgclient.log -k -p 进程pid
			4、统计进程的系统调用统计信息							
				strace  -c -p 进程pid


51、perf工具使用

		1、
			perf是linux性能分析工具

		2、 perf命令介绍
			perf有很多子命令,以为为常用的命令:
				perf list:      查看当前软硬件环境支持的性能事件
				perf stat:     分析指定程序的性能概况
				perf top:     实时显示系统/进程的性能统计信息
				perf record:记录一段时间内系统/进程的性能事件
				perf report:读取perf record生成的perf.data文件,并显示分析数据
			2.1 perf list命令
				命令功能:查看当前软硬件环境支持的性能事件
				一般执行命令:perf list
			
			2.2 perf stat命令
				命令功能:		分析指定程序的性能概况
				一般执行命令:	perf stat -a -p 进程pid
				默认事件简介:
						Task-clock(msec):CPU利用率,该值高,说明程序的多数时间花费在 CPU 计算上而非 IO
						Context-switches:进程切换次数,记录了程序运行过程中发生了多少次进程切换,频繁的进程切换是应该避免的
						Cache-misses:程序运行过程中总体的 cache 利用情况,如果该值过高,说明程序的 cache 利用不好
						CPU-migrations:表示进程31404运行过程中发生了多少次 CPU 迁移,即被调度器从一个 CPU 转移到另外一个 CPU 上运行
						Cycles:处理器时钟,一条机器指令可能需要多个 cycles
						Instructions: 机器指令数目
						IPC:是 Instructions/Cycles 的比值,该值越大越好,说明程序充分利用了处理器的特性
						Cache-references: cache命中的次数
						Cache-misses: cache失效的次数
						Page-faults:缺页异常的次数。当应用程序请求的页面尚未建立、请求的页面不在内存中,或者请求的页面虽然在内存中,但物理地址和虚拟地址的映射关系尚未建立时,都会触发一次缺页异常。另外TLB不命中,页面访问权限不匹配等情况也会触发缺页异常。
						Branches:遇到的分支指令数
						Branch-misses:预测错误的分支指令数
				命令参数
						-e <event>:指定性能事件(可以是多个,用,分隔列表)
						-p <pid>:   指定待分析进程的 pid(可以是多个,用,分隔列表)
						-t <tid>;:    指定待分析线程的 tid(可以是多个,用,分隔列表)
						-a:从所有 CPU 收集系统数据
						-d:打印更详细的信息,可重复 3 次
							-d:L1 和 LLC data cache
							-d -d:dTLB 和 iTLB events
							-d -d -d:增加 prefetch events
						-r <n>;:  重复运行命令 n 次,打印平均值。n 设为 0 时无限循环打印
						-c <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
						-A:与-a选项联用,不要将 CPU 计数聚合
						-I <N msecs>:每隔 N 毫秒打印一次计数器的变化,N 最小值为 100 毫秒

			2.3 perf top命令
				命令功能:实时显示系统/进程的性能统计信息
				一般执行命令:perf  top  -a  -g  -p 进程pid,动态监视指定进程
				常用命令参数:
						-e <event>:指明要分析的性能事件。
						-p <pid>:仅分析目标进程及其创建的线程。
						-k <path>:带符号表的内核映像所在的路径。
						-K:不显示属于内核或模块的符号。
						-U:不显示属于用户态程序的符号。
						-d <n>:界面的刷新周期,默认为2s。
						-g:得到函数的调用关系图。
			2.4 perf record命令
				命令功能:收集一段时间内的性能事件到文件 perf.data,随后需要用perf report命令分析
				一般执行命令:
						perf record -F 999 -a -p xxxx -g -- sleep 30
						备注:
							# record 表示记录cpu的执行数据
							# -F:采样频率(次/秒)
							# -p:进程号
							# -g:输出调用栈数据
							# -a:所有cpu
							# -- sleep:本次采样总时长(秒)
				常用命令行参数:
					-e <event>:指定性能事件(可以是多个,用,分隔列表)
					-p <pid>:指定待分析进程的 pid(可以是多个,用,分隔列表)
					-t <tid>:指定待分析线程的 tid(可以是多个,用,分隔列表)
					-u <uid>:指定收集的用户数据,uid为名称或数字
					-a:从所有 CPU 收集系统数据
					-g:开启 call-graph (stack chain/backtrace) 记录
					-C <cpu-list>:只统计指定 CPU 列表的数据,如:0,1,3或1-2
					-r <RT priority>:perf 程序以SCHED_FIFO实时优先级RT priority运行这里填入的数值越大,进程优先级越高(即 nice 值越小)
					-c <count>: 事件每发生 count 次采一次样
					-F <n>:每秒采样 n 次
					-o <output.data>:指定输出文件output.data,默认输出到perf.data
		2.5、perf report命令
			命令功能:读取perf record生成的perf.data文件,并显示分析数据
				perf report 有许多控制命令,使用perf report -h查看
				不带任何参数运行时,默认在当前目录查找perf.data文件并统计输出
				perf report -i perf.data > perf.txt把结果写入文本文件


52、linux下时间戳和标准时间转换

	1.字符串转化成时间戳
	date -d "2012-02-02 00:00:00" +%s
	输出:1328112000

	2.时间戳转化为字符串
	date -d "1970-01-01 UTC 1328247282 seconds" "+%F %T"
	输出:2012-02-03 13:34:42		


53、麒麟系统,解析域名暂时失败解决办法

	首先使用cd命令进入etc;
	然后使用vi编辑器编辑resolv.conf
	接着在nameserver后面添加域名。
	例如:
	nameserver 8.8.8.8
	nameserver 114.114.114.114
	然后:    wq保存;
	然后重启网路服务,执行以下命令
	$ /etc/init.d/networking force-reload
	$ /etc/init.d/networking restart


54、cat命令清空文件

cat /dev/null > /www/aaa.txt;


55、valgrind定位内存泄漏

    1、安装valgrind
		sudo yum install valgrind #centos
		sudo apt-get install valgrind #ubuntu
	2、检测内存泄漏
		valgrind --tool=memcheck --leak-check=full ./test.out
		
		编译源程序加上-g参数
		如果你的程序是会正常退出的程序,
		那么当程序退出的时候valgrind自然会输出内存泄漏的信息。
		如果程序是个守护进程,我们 只要在别的终端下杀死valgrind进程
		kill -TERM valgrind进程的PID
		这样我们的程序(./a.out)就被kill了



56、valgrind定位守护进程内存泄漏

	1、安装valgrind对client检测
		安装完valgrind和linux fc后
		cd /opt/fc  #首先要cd到fc安装目录
		kill client_pid  #杀掉client进程
		valgrind --tool=memcheck --leak-check=full --log-file=valgrind_report.txt /opt/client -l trace  | tee client_out.txt       
		备注:把tgclient挂到valgrind上执行,valgrind输出会保存到valgrind_report.txt文件中,
		tgclient输出会保存到tgclient_out.txt文件中(每次执行,输出都会覆盖之前的文件)
	2、退出tgclient并产生内存泄漏分析报告
		kill -TERM valgrind进程的PID
		这样我们的程序tgclient就被kill了

57、gcore抓取进程core文件并分析所有调用堆栈

	1、抓取进程的core文件
		gcore 进程pid
	2、把进程的所有线程调用堆栈保存到文件中
		a)gdb 程序名  coredump文件名
		b)set logging file 日志文件名字.log
		c)set logging on
		d)thread apply all bt
		e)set logging off


58、查看进程信息

	1、动态查看一个进程加载的动态库(三个命令任何一个都可以)
		cat /proc/<PID>/maps|awk '{print $6}'|grep '\.so'|sort|uniq
		lsof -p <PID>|awk '{print $NF}'|grep '\.so'|sort|uniq
		pmap -p <PID>|awk '{print $4}'|grep '\.so'|sort|uniq

	2、查看进程加载了哪些so
		cat /proc/你的程序pid/maps
		cat /proc/你的程序pid/maps |grep test
	3、查看进程的环境变量
		cat  /proc/你的程序pid/environ
		cat  /proc/你的程序pid/environ |grep LD_
	4、pmap可以看到进程实际使用的内存
		pmap -d pid






[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-10-13 14:16 被sanganlei编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 4583
活跃值: (6836)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
great written,but some more
2022-7-8 00:51
0
游客
登录 | 注册 方可回帖
返回
//