一、语法相关
1. 进制数字表示
1 | 二进制转十进制输出,其他同理 |
2. 特殊符号和变量
2.1. 目录特殊符号
- 上一级
..
- 当前目录
.
- 当前用户目录
~
- 根目录
/
2.2. 内置变量
1 | 返回[0,32767]以内的随机整数,也就是0x7fff以内 |
3. 常用语法详解
3.1. <>
输入出重定向
1 | ls ./ >a.text # 正确输出到a.txt(覆盖) |
3.2. $ 意义
1 | $ # Shell本身的PID(ProcessID) |
3.3. cd 跳转目录命令
特殊跳转
- 跳转上一级
..
- 跳转当前目录
.
- 跳转当前用户目录
~
- 跳转根目录
/
- 跳转上一个目录
cd -
- 跳转前n目录
cd -n
- 跳转后n目录
cd +n
3.4. if 条件判断
文件表达式
1 | if [ -e file ] # 如果文件或者目录存在,不管有没有权限 |
整数变量表达式
1 | if [ int1 -eq int2 ] # 如果int1等于int2 |
字符串变量表达式
1 | if [ $a = $b ] # 如果string1等于string2 |
3.5. for 循环
(1) 文件遍历
1 | 此行代表以换行符为分割,默认为空格、\t和\n |
(2) index递增形式
1 | for ((i=0;i<2;i++)); do |
3.6. while 循环
1 | 按行读取文件内容 |
3.7. switch 语句
1 | case "$1" in |
4. 函数调用
1 | abc() { |
函数调用不加括号
5. 字符串操作
1 | string="12348213" |
5.1. 字符串替换
1 | echo ${string/23/bb} # 替换一次 |
5.2. 字符串截取
1 | 删除最后一个/及前面所有。作用是删除路径,只留文件名 |
- #:表示从左开始算起,并且截取第一个匹配的字符
- ##:表示从左开始算起,并且截取最后一个匹配的字符
- %:表示从右开始算起,并且截取第一个匹配的字符
- %%:表示从右开始算起,并且截取最后一个匹配的字符
1 | 截取给定一段,m开始截取n个 |
5.3. 字符串遍历
1 | string="abc |
6. 数组
1 | 数组声明 |
6.1. 数组遍历
数组遍历分为几种形式
1 | service_list=( |
- 低版本shell中,local不能修饰数组
6.2. 数组拷贝
1 | service_list=( |
7. eval
- eval是将字符串转成命令执行
- 可用于在脚本中将字符串转成变量名执行
1 | service_list=( |
8. bash和source、.
的区别
- source和
.
是一样的 - 三者都可以不需要文件有可执行权限
- bash类似于fork了一个子进程,内部变量和父进程没关系,但是父进程会等待子进程结果
- source和
.
更像直接把文件内容拷贝到位置上执行,主要用于导入变量和函数
9. 算术表达式
9.1. i++表示
(1) 使用let表示
1 | i=0 |
(2) 用(())
,这种用法常见于for循环中
1 | ((i++)) |
(3) 用expr
- 中间要有空格,否则就成字符串拼接了
1 | i=0 |
(4) 用如下模式
1 | i=$[$i+1]; # 分号不能少 |
10. shift 参数左移
- 一般用于shell脚本中,将传入的参数删除n个(不加就是1个),剩余的左移
1 | !/bin/bash |
1 | => bash test.sh a b c |
11. 循环错误处理
循环中使用exit是不会退出脚本的,会直接退出循环,类似break。想在循环中捕获错误并退出可以如下操作
1 | 错误处理函数 |
二、系统命令详解
1. find 文件查找
1.1. 选项
-type
: 类型,d为文件夹,f为文件-name
: 文件名称,支持*
-atime
: 访问时间,后跟参数,查看示例-mtime
: 修改时间,后跟参数,查看示例-ctime
: 元数据修改时间,后跟参数,查看示例
1.2. 实例
1 | 查找当前目录下文件类型的,修改时间在0.5天以内的文件 |
1.3. 统计代码行数
1 | 统计所有go文件,排除单测文件的代码行数,去除空行 |
2. file
2.1. 实例
1 | 查看文件类型,不显示文件名 |
3. tr
3.1. 实例
1 | 大小写转化 |
4. watch
watch命令以周期性的方式执行给定的指令,指令输出以全屏方式显示。watch是一个非常实用的命令,基本所有的Linux发行版都带有这个小工具,如同名字一样,watch可以帮你监测一个命令的运行结果,省得你一遍遍的手动运行。
4.1. 选项
- -n:指定指令执行的间隔时间(秒);
- -d:高亮显示指令输出信息不同之处;
- -t:不显示标题。
4.2. 实例
1 | watch uptime |
5. tail 实时查看文件内容(可用于查看log文件)
1 | tail -f (fileName) |
5.1. tail显示高亮
1 | tail -f sys.log | perl -pe 's/(关键词1)|(关键词2)|(关键词3)/\e[1;颜色1$1\e[0m\e[1;颜色2$2\e[0m\e[1;颜色3$3\e[0m/g' |
两个示例
- 黄字,高亮加粗显示
[1;33m
- 红底黄字,高亮加粗显示
[1;41;33m
效果配置列举
1 | 前景色 |
6. sort 排序
6.1. 选项解释
-u
: 排序后去重-V
: 版本号类型排序,如2.1.10
-n
: 数字排序而非字典序
6.2. 一些基本操作
1 | 将test.txt中排序并去重,但是只输出到控制台,可以用>写到文件 |
7. grep 查找内容
-r
: 遍历子目录-n
: 遍历行数-i
: 大小写无关-v
: 排除-E
: 衍生为正则表达式(用|代表或等)-o
: 正则只输出PATTERN部分-c
: 统计行数--include="*.c"
: 包含某个后缀的文件,可以多次设置--include
7.1. 内容匹配
- 查找字符串用
^
代表开头,用$
代表结束,可以使用^xxx$
进行全匹配
1 | 匹配ab开头的字符串 |
7.2. 查找进程排除grep
- 通常使用
ps + grep
查找进程,但是会多出一行当前查找的grep进程
1 | ps -aux | grep xxx | grep -v grep |
7.3. 查找包含内容的有几行
1 | 相当于 cat test.txt | grep "test" | wc -l |
7.4. 查找目录下所有文件匹配对应字符串
1 | grep -nr "test" ./ |
7.5. 正则查找,只显示匹配段
1 | 显示 APPVERSION=abc 到|停止,即所有非|都匹配,匹配多个 |
8. wc 查看文件或者内容行数
- 结合查找进程可以返回匹配的进程个数
wc -l
返回的是\n
的个数,如果最后一行没有换行,将不会统计最后一行
1 | ps -aux | grep xxx | grep -v grep | wc -l |
9. addr2line 根据地址定位代码位置
示例
1 | => addr2line 0x2026 -e run -f |
-e
: 指定可执行文件-f
: 显示函数名
9.1. 注意事项
- gcc编译需要添加
-g
参数 - 不加
-g
放到生产环境,加-g
的用于找代码位置
10. date 时间工具
10.1. 用法
1 | Usage: date [OPTION]... [+FORMAT] |
-d DATE_STRING
: 展示使用字符串描述的时间,不设置就是显示当前时间,DATE_STRING
使用@
加上时间戳也可以表示-s DATE_STRING
: 使用字符串描述的时间设置到系统时间上
10.2. 一些实例
1 | ######### 时间计算 ########## |
11. dd 批量拷贝命令
11.1. 实例
1. 生成大文件
1 | 生成指定大小文件,1M一个单位,120个单位,生成到/sftmpfs/test |
12. watch 监听命令
12.1. 实例
1 | 监听内存变化,每秒刷新一次 |
13. iptables 防火墙
13.1. 知识填充
13.2. 实例
1 | ######### 插入规则 ########## |
踩坑记
1) iptables报错iptables v1.8.4 (nf_tables): Could not fetch rule set generation id: Invalid argument
- 是iptables使用了nft模式,修改为legacy就好了,执行命令
1 | => update-alternatives --config iptables |
- 选择legacy即可
14. ls 列举目录
13.1. 选项
-l
: 列表显示详细信息-h
: 目录大小加上单位-t
: 按照时间排序-S
: 按照大小排序-r
: 反向排序
13.2. 时间显示格式修改
1 | => export TIME_STYLE='+%Y-%m-%d %H:%M:%S' |
15. netstat 网络状态查看
1 | usage: netstat [-vWeenNcCF] [<Af>] -r netstat {-V|--version|-h|--help} |
-a
: 显示所有连接,包括正在连接的-l
: 显示监听的连接,只显示被监听的端口和套接字文件-p
: 显示进程名-n
: 不把端口自动推测成服务,显示原始端口-t
: tcp-u
: udp
实例
1 | 显示所有tcp监听的端口,显示对应进程,按照数字显示端口 |
16. sed 文件查找替换打印
- sed命令有点复杂,一直不会用,但是很强大
16.1. 选项
-i[suffix]
: 替换文件内容,如果定义了suffix,会备份一份到xxxsuffix
16.2. 示例
1. 添加一行
1 | sed -i "/^start()/a\ |
2. 添加多行
1 | sed -i "/^start()/a\ |
3. 替换
1 | 将aaa替换成bbb |
3. 删除所有的html标签
1 | sed -i 's/<[^>]*>//g' "${file_name}" |
4. 截取文件中间部分
1 | sed -n '15,20p' test.txt |
16.3. 正则
*
: 匹配空格零次或多次\?
: 匹配空格零次或一次\+
: 匹配空格一次或多次
特殊用法
1. pattern带大括号,需要转义
- 将大括号单独用单引号包裹,两边闭合单引号
1 | sed -i 's/aaa''{''/bbb''{''/' aaa.txt |
17. echo 输出
-n
: 不换行-e
: 解析\n
等字符,默认不解析
18. diff & patch 差异输出和应用
diff
-r
: 递归对比文件夹改动-u
: 合并的方式输出,类似git diff,用于生成patch
git diff
-w
: 忽略空格改动--relative
: 相对目录,不使用git绝对目录
patch
-p<n>
: 裁剪前导/
和目录,p1忽略第一个/
,以此类推-l
: 忽略空格-i <patch_path>
: 输入patch文件--no-backup-if-mismatch
: 如果改动不完全,不要备份文件
18.1 git改动应用到某个目录上(非git标准目录)
1 | 和某个提交做diff,输出到patch文件 |
18.2 文件夹改动应用到另一个文件夹
1 | 两个同级目录对比(必须同级,不然应用差异时目录会有问题) |
19. fallocate 创建大文件
fallocate创建的文件仅仅是占用磁盘,没有内容,所以只有很少的I/O操作,比dd快很多
19.1. 几种基本用法
1 | 创建一个10G的文件 |
不知道为什么,fallocate不能重复对一个文件执行,想要重新分配需要手动删除前一个文件
20. lsof 查看系统文件占用(包括端口)
20.1. 几种基本用法
1 | 根据进程号查看端口占用 |
21. top 查看系统占用
21.1. 几个快捷键
Shift + E
: 调整内存单位1
: 切换cpu统计模式,所有/详细Shift + P
: cpu占用排序Shift + M
: 内存占用排序m
: 切换内存显示样式c
: 显示进程详细命令
21.2. 进程状态解析
- R——Runnable(运行): 正在运行或在运行队列中等待
- S——sleeping(中断): 休眠中,受阻,在等待某个条件的形成或接收到信号
- D——uninterruptible sleep(不可中断): 收到信号不唤醒和不可运行,进程必须等待直到有中断发生
- Z——zombie(僵死): 进程已终止,但进程描述还在,直到父进程调用wait4()系统调用后释放
- T——traced or stoppd(停止): 进程收到SIGSTOP,SIGSTP,SIGTOU信号后停止运行
后缀表示
- <: 优先级高的进程
- N: 优先级低的进程
- L: 有些页被锁进内存
- s: 进程的领导者(在它之下有子进程)
- l: ismulti-threaded (using CLONE_THREAD, like NPTL pthreads do)
- +: 位于后台的进程组
22. awk 逐行处理显示
22.1. 实例
1. git计算代码行数
1 | git diff xxxx --numstat | awk '{add+=$1;del+=$2} END {print "Add =",add,"Delete =",del}' |
计算diskstats每个分区写入大小
1 | => cat /proc/diskstats | awk '{printf"%s#%s:%s\t%.2fMB\n",$3,$1,$2,$10*512/1024/1024}' |
23. md5sum 计算MD5
23.1. 几种基本用法
1 | 计算字符串的md5 |
24. udevadm 系统usb管理
24.1 几种基本用法
1 | 监听usb事件,查看详细信息可以添加选项 |
25. lsblk 树型查看硬盘分区信息
-d
: 只显示硬盘,不显示分区-f
: 显示分区文件系统类型-o xxx,xxx
: 指定显示列name
: 名字rota
: 是否是转动磁盘,也就是机械硬盘。1为机械硬盘;0为固态硬盘
1 | => lsblk |
26. blkid 查看已挂载的硬盘的uuid信息
27. tune2fs 修改硬盘uuid
28. route 更新路由信息
28.1. 一些基本用法
1 | ######### 查看路由 ########## |
29. ps 查看系统进程
29.1. 选项含义
参数
a
: 列出所有用户的程序u
: 显示所属用户x
: 显示所有程序,不加只显示终端控制的程序c
: 只显示指令名称f
: 使用ascii字符展示关系e
: 显示环境变量ww
: 显示全,自动换行
30. ip 系统网络配置
- 默认配置ipv4,配置ipv6需要加上
-6
30.1. 路由相关
1 | ########## 查看路由 ########## |
1) 策略路由
- 一般的策略路由配置是设置mark到数据包,然后通过mark将数据包匹配对应的路由表
1 | ######### 查看所有的策略路由规则 ########## |
30.2. 查看网卡ip
1 | => ip addr |
30.3. 配置网卡
1 | 启用/禁用网卡 |
31. read 读取输入
31.1. 读取用户输入
1 | read -s 5 -p "do you wan't to continue [y/n]" input |
32. conntrack 连接跟踪
32.1. 选项解释
1 | 查看连接跟踪表 |
-p [protocol]
-s [src_ip]
-d [dst_ip]
--sport [src_port]
--dport [dst_port]
--state [NONE | SYN_SENT | SYN_RECV | ESTABLISHED | FIN_WAIT | CLOSE_WAIT | LAST_ACK | TIME_WAIT | CLOSE | LISTEN]
: 过滤状态
33. ss 查看socket占用情况
33.1. 选项解释
-t
: tcp-u
: udp-x
: unix-l
: listening-p
: 展示进程信息-m
: 展示socket内存占用情况-n
: 不把端口自动推测成服务,显示原始端口
v9k
33.2. 使用实例
1 | 查看22端口占用 |
34. pwd
34.1. 选项解释
-L
: 逻辑路径,软连接路径-P
: 物理路径,软连接映射的真实路径
35. mknod
- 用于挂载设备节点
35.1. 示例
1 | 挂载字符型设备,主设备号1,次设备号8 |
36. sudo
36.1. 选项
-E
: 继承当前环境变量
37. sysctl 修改内核参数
37.1. 选项
-a
: 列举所有内核参数-p
: 从/etc/sysctl.conf
加载配置-w
: 修改内核参数
示例
1 | 查找当前配置 |
38. pmap查看进程内存情况
选项
-x
: 显示扩展格式-d
: 显示设备格式-q
: 不显示头尾行-V
: 显示指定版本
示例
1 | => pmap -x 76381 |
39. setcap 提权命令
- 从2.1版开始,Linux内核有了能力(capability)的概念,即它打破了UNIX/LINUX操作系统中超级用户/普通用户的概念,由普通用户也可以做只有超级用户可以完成的工作
- 比如给kill命令杀死其他进程的能力,但是不能重启系统,也不能修改文件。仅拥有杀死其他进程的能力
39.1. 能力列举
CAP_CHOWN
: 修改文件属主的权限CAP_DAC_OVERRIDE
: 忽略文件的DAC访问限制CAP_DAC_READ_SEARCH
: 忽略文件读及目录搜索的DAC访问限制CAP_FOWNER
: 忽略文件属主ID必须和进程用户ID相匹配的限制CAP_FSETID
: 允许设置文件的setuid位CAP_KILL
: 允许对不属于自己的进程发送信号CAP_SETGID
: 允许改变进程的组IDCAP_SETUID
: 允许改变进程的用户IDCAP_SETPCAP
: 允许向其他进程转移能力以及删除其他进程的能力CAP_LINUX_IMMUTABLE
: 允许修改文件的IMMUTABLE和APPEND属性标志CAP_NET_BIND_SERVICE
: 允许绑定到小于1024的端口CAP_NET_BROADCAST
: 允许网络广播和多播访问CAP_NET_ADMIN
: 允许执行网络管理任务CAP_NET_RAW
: 允许使用原始套接字CAP_IPC_LOCK
: 允许锁定共享内存片段CAP_IPC_OWNER
: 忽略IPC所有权检查CAP_SYS_MODULE
: 允许插入和删除内核模块CAP_SYS_RAWIO
: 允许直接访问/devport,/dev/mem,/dev/kmem及原始块设备CAP_SYS_CHROOT
: 允许使用chroot()系统调用CAP_SYS_PTRACE
: 允许跟踪任何进程CAP_SYS_PACCT
: 允许执行进程的BSD式审计CAP_SYS_ADMIN
: 允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等CAP_SYS_BOOT
: 允许重新启动系统CAP_SYS_NICE
: 允许提升优先级及设置其他进程的优先级CAP_SYS_RESOURCE
: 忽略资源限制CAP_SYS_TIME
: 允许改变系统时钟CAP_SYS_TTY_CONFIG
: 允许配置TTY设备CAP_MKNOD
: 允许使用mknod()系统调用CAP_LEASE
: 允许修改文件锁的FL_LEASE标志
39.2. 示例
1 | 给tcpdump设置允许使用原始套接字,使得普通用户可以tcpdump |
40. xdg-open 按照系统默认打开方式打开文件
- 可以打开url、文件等
41. uniq 处理重复行
41.1. 选项解释
-c
: 在前面显示重复行数量-u
: 只打印不同的行-d
: 只打印出现过多次的行
41.2. 基本用法
1 | 统计重复行数量,uniq只能对相邻行处理,所以需要先排序 |
42. ipset 给iptables使用的ip列表
43. who
43.1. 基本使用
1 | 查看所有登陆到设备的信息,包括ssh的 |
44. df
-T
: 显示文件系统类型
1 | => df -h |
45. fdisk
45.1. 实例
查看磁盘扇区大小
1 | => fdisk -l /dev/vda |
三、工具命令
1. 文件夹目录大小 du
当前目录下所有子文件夹和文件的大小
1 | du ./ -h --max-depth=1 |
2. 抓包工具 tcpdump
2.1. 选项
-c [num]
: 抓取的包的数量-i
: 要监听的网口,不给默认为第一个网口-n
: 对地址以数字方式显式,否则显示为主机名,也就是说-n选项不做主机名解析-nn
: 除了-n的作用外,还把端口显示为数值,否则显示端口服务名-w xxx.pcap
: 保存到文件,pcap结尾,用于wirshark分析-v
: 显示更多信息,如ip包的存活时间、标识号、总长度和选项,并且检查ip包或icmp包的头部checksum-vv
: 除-v
作用外,NFS回包和SMB包会被解码-X
: 打印每一个包,以hex和ascii的形式打印
2.2. 过滤器
host [ip_addr]
: 源ip和目的ip为ip_addr
[src|dst] [ip_addr]
: 源ip/目的ip为ip_addr
[protocol]
: 协议tcp
udp
icmp
icmp6
: ping ipv6
port [port_num]
: 端口[src|dst] port [port_num]
: 源/目的端口[tcp|udp] port [port_num]
: tcp/udp端口[tcp|udp] [src|dst] port [port_num]
: tcp/udp的源/目的端口ip6
: ipv6
2.3. 示例
1 | 抓5个192.168.100.62到本机eth0的icmp(ping)包 |
3. 网络嗅探 nmap
4. 远程连接 ssh
4.1. ssh生成公钥和私钥
1 | ssh-keygen -t rsa -C "xxx@xxx.com" |
4.2. ssh通过代理访问
1 | socks5代理 |
4.3. 端口转发
- 手册解释如下
1 | -L [bind_address:]port:host:hostport |
- 用法
1 | 监听本地端口9229,转发给远程的9229端口 |
4.4. ssh登陆信息
1 | => echo $SSH_CONNECTION |
1) 添加ssh登陆后执行命令
- 修改
.bashrc
添加
1 | ssh远程登陆执行命令 |
4.5. 忽略known_hosts
错误
- 配置到
~/.ssh/config
中
1 | # 对单个服务器 |
踩坑记
(1) 低版本ssh连接失败
- 修改
/etc/ssh/ssh_config
或~/.ssh/config
,添加下面字段即可
1 | # 对单个服务器 |
(2) ssh首次登录总要等一会才提示密码框
- 原因是ssh去找主机名的DNS
- 快速解决是修改服务端的
/etc/ssh/sshd_config
,然后重启服务
1 | UseDNS no |
(3) scp报错 path canonicalization failed
可能是服务端ssh版本太老导致,添加-O
使用旧版本协议
5. 压缩和解压缩命令
5.1. tar命令
5.1.1. 参数解析
-c
: 建立压缩档案-x
: 解压-t
: 查看内容-r
: 向压缩归档文件末尾追加文件-u
: 更新原压缩包中的文件
这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。
-z
: 有gzip属性的 tar.gz-j
: 有bz2属性的 tar.bz2-J
: tar.xz-Z
: 有compress属性的 tar.Z-v
: 显示所有过程-O
: 将文件解开到标准输出
这几个根据需要在压缩或解压档案时可选的。
-f [tar_file_name]
: 必须,使用档案名字,多选项时,此参数为最后一个。-C [dir_name]
: 解压到什么目录,压缩时的父目录
5.1.2. 示例
1 | tar -xzf xxx.tar.gz # 解压tar.gz文件 |
5.1.3. 加密压缩
1 | 使用openssl命令进行加密压缩 |
- openssl在1.1.0版本有修改导致不兼容,可以用下面的方法
1
在OpenSSL 1.1.0中,我们从MD5更改为SHA-256。我们这样做是作为整体改变的一部分,以摆脱现在不安全和破碎的MD5算法。如果您有旧文件,请使用“-md md5”标志对其进行解密
5.2. zip命令
5.2.1. 压缩
压缩只会追加不会删除已经存在于zip文件中的文件
-j
: 去除路径-r
: 递归压缩所有文件-m
: 打包后删除压缩的源文件-x <pattern>
: 忽略某些文件,可以连续写多个
1 | zip -r (filename.zip) (path) |
5.2.2. 解压
1 | unzip xxx.zip -d xxx |
- 不加
-d
就解压到当前目录
6. e2label 修改卷标名称
分区为ext2/ext3
类型使用
1 | e2label /dev/(partition) "(name)" |
7. readelf 查看二进制符号表
7.1. 查看符号表
- 查看有哪些二进制符号和对应的函数地址
1 | -s 符号表 |
7.2. 查看二进制依赖
- 会显示依赖的动态库路径
1 | readelf -d xxx |
8. objdump 导出汇编指令表
导出二进制的汇编指令表,如果没有strip掉符号,还能看到每个函数的汇编指令和对应地址
-D
: 展示所有段的汇编-S
: 将代码内嵌到汇编中(前提是有符号,也就是gcc需要加-g)
1 | objdump -DS xxxx > xxx.dump |
9. strace 查看系统调用
-t
: 打印时间-tt
: 打印时间,精确到微秒-T
: 打印系统调用占用时间-f
: 打印进程号,可针对多进程程序-v
: 参数打全,不省略-o file
: 结果输出到文件-p [PID]
: 挂载到一个进程
9.1. 查看单进程的系统调用,不重启进程
1 | strace -p xxx |
10. tree 查看文件树
-L n
: 目录深度
11. sshfs 挂载远程目录
1 | 和mount一样,将远程的/aaa挂载到本地~/xxx |
12. cmake 跨平台编译命令
CMakeLists.txt编写参见CMakeLists.txt
12.1 基本使用命令
-DCMAKE_BUILD_TYPE
STRING=Debug
: 在linux上会编译出libxxxd.so
STRING=Release
STRING=MinSizeRel
STRING=RelWithDebInfo
: 在linux上会编译出libxxxrd.so
1 | 指定build目录生成工程 |
13. gdb c/c++单步调试工具
13.1 gdb内部基本使用命令
1 | start # 开始调试,停在第一行代码处,(gdb)start |
13.2. 可以看代码版本 cgdb
1) 快捷键
gdb窗口
Esc
: 转到代码窗口
代码窗口
i
: 转到gdb窗口o
: 打开源码文件列表,/
搜索j
: 光标下移k
: 光标上移Space
: 当前行打断点=
: 放大代码窗口一行-
: 减小代码窗口一行Shift + +
: 放大窗口一大段Shift + _
: 缩小窗口一大段
13.3. 函数堆栈
bt
: 查看当前堆栈frame <n>
: 跳转到当前哪一层堆栈up <n>
: 向上跳几层down <n>
: 向下跳几层
13.4. 带参数的执行
1 | gdb --args /path/to/run a b |
13.5. gdbserver远程调试
- 在远程服务器执行
1 | gdbserver 0.0.0.0:6666 --attach 14614 |
- vscode配置文件
1 | { |
13.6. gdb忽略某个信号不打断
- 经常遇到gdb调试进去后,因为某些信号打断,又可以继续,使用下面命令跳过
1 | handle SIGINT nostop |
13.7. gdb挂载进程调试
1 | gdb /path/to/exec pid |
14. tmux
快捷键
- 工具特定命令前缀为
Ctrl + b
session操作
tmux ls
: 查看session列表prefix, d
: 离开当前session,但是session继续跑tmux a -t <session-name>
: 重新回到一个sessiontmux kill-session -t <session-name>
: 杀死一个session
窗口操作
prefix, c
: 创建新窗口prefix, n
: 下一个窗口prefix, p
: 上一个窗口prefix, l
: 进入前一个操作的窗口prefix, w
: 列出窗口进行选择prefix, ,
: 重命名当前窗口prefix, Shift + &
: 删除当前窗口
窗格操作
prefix, <方向键>
: 切换到相应窗格prefix, Shift + "
: 纵向分屏prefix, Shift + %
: 横向分屏prefix, Shift + !
: 将当前窗格新起一个窗口存放prefix, Ctrl + <方向键>
: 朝相应方向移动边界prefix, :resize-pane -D|U|L|R <num>
: 向对应方向移动多少行,也就是快捷键不顶用用这个prefix, x
: 关闭当前窗格prefix, z
: 当前窗格放大(专注,切换窗格就恢复了)prefix, ;
: 切换到上一个窗格prefix, o
: 切换到下一个窗格prefix, [
: 进入copy modeprefix, Ctrl + o
: 顺时针切换各个窗格prefix, m
: 标记窗格,配合下面命令交换窗格prefix, :swapp
: 切换窗格
copy mode
Ctrl + s
: 向下查找,输入字符串回车后,使用n和N选择下一个或者上一个Ctrl + r
: 向上查找
15. fzf
配置
- 安装完成后,将下面配置加到
.zshrc
或者.bashrc
中
1 | 40%屏显示非全屏,展示反向(输入框在上面,文件在下面正序),文件在右侧展示前50行 |
16.
16.1. C/C++
基本选项
-I xxx
: 许多函数定义最后有一个__THROW
类似的,ctags将解析出错,加上此选项会忽略xxx--fields=+iaS
:--extra=+q
--c-kinds=+p
添加系统头文件支持
- 执行以下命令生成系统头文件的tags
- 添加
set tags+=~/.vim/systags
包含系统头文件tags
系统头文件检索列表,里面尖括号字段根据系统适配
1 | /usr/include |
1 | 把上面列表文件都扫出来,加到files.list里面 |
16.2. php支持
转载自 https://www.cnblogs.com/longdouhzt/archive/2013/04/15/3022908.html
- 添加以下命令到
~/.bashrc
或者~/.zshrc
等当前使用的bash的起始配置文件中,可以使用phptags来生成php的tags文件
1 | alias phptags='ctags --langmap=php:.engine.inc.module.theme.php --php-kinds=cdf --languages=php' |
- 添加以下配置到
~/.ctags
中,添加一些匹配规则
1 | --regex-php=/^[ \t]*[(private|public|static)( \t)]*function[ \t]+([A-Za-z0-9_]+)[ \t]*\(/\1/f, function, functions/ |
- 到工程目录下
phptags -R
即可生成相应tags
17. gcc
17.1. 选项解释
编译选项
-Os
: 类似于-O2.5
但是不缩减代码尺寸-fpie
: pie功能看后面解释,给可执行文件使用,e代表executable
-fno-pie
: 关闭pie功能-fpic
: 和pie类似,给链接库使用,c代表code-s
: strip掉所有符号-fsanitize=address
: 监听内存泄漏,需要同时加上-lasan
并且保证已经安装libasan-fno-stack-protector
: gcc默认会添加栈安全检查,但是这个会依赖glibc的库,导致undefined reference to `__stack_chk_fail’的问题-MD
: 编译时输出依赖关系到x.d
,一般是头文件包含关系-Werror
: 所有warning当作error处理-nostdinc
: 不搜索默认路径头文件,一般是嵌入式或内核开发使用-m32
: 32位编译
链接选项
-pie
: 链接选项,需要和-fpie
一起使用,不过不加好像是默认看编译选项-no-pie
: 链接选项,关闭pie,同样需要和-fno-pie
一起使用,不过不加好像是默认看编译选项-m elf_i386
: 生成32位的可执行文件
1) PIE技术
PIE(position-independent executable)是一种生成地址无关可执行程序的技术。编译器在生成代码时,会添加特殊指令,让内部跳转时不关心内存在哪里加载,也就可以将二进制在内存中随即地址加载
一般技术为添加__x86.get_pc_thunk.ax
函数,使用当前的地址加上偏移计算出对应调用地址
1 | 00280000 <start_kernel>: |
__x86.get_pc_thunk.bx
实现是将esp内存的地址赋值给ebx,esp存的地址是下一条指令所在的地址,也就是上面的280009: 81 c3 7b 06 00 00 add $0x67b,%ebx
的地址0x280009
。对这个地址添加0x67b
得到0x280684
也就是_GLOBAL_OFFSET_TABLE_
的地址。这段汇编就是将全局偏移表的地址存到ebx中,后面进行使用。
使用当前地址加偏移的方式就可以让二进制在加载内存时不用在特定地址加载。
此方式只需要给全局变量和静态变量使用,因为函数地址本身就是偏移得来的,
17.2. 查看预定义宏
1 | => gcc -dM -E - < /dev/null |
17.3. 单函数优化级别设定
- 全局优化级别设定后,可以在编译时指定单个函数的优化级别
1 | static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) __attribute__((optimize("O0"))); |
- 或者指定一批,
pragma
后面的函数都会应用此优化
1 |
|
17.4. 编译过程的报错解释
unused-result
: 返回值未使用pointer-sign
: 指针符号错误int-conversion
: 整形类型转换unused
: 变量未使用declaration-after-statement
: 语句在定义前面,这个一般在C90标准中有问题
17.5. 实例
1) 编译动态库
1 | gcc -shared -fPIC main.cpp -o main.so |
18. firewalld 防火墙
18.1. 选项解释
--permanent
: 永久生效,加了这个选项,需要执行reload才能生效;不加,会立即生效,但是reload后会消失
18.2. 基本操作
1 | 重载防火墙规则 |
18.3. 区域操作
1 | ######### 查看区域 ########## |
18.4. 服务操作
1 | ######### 查看服务 ########## |
18.5. 端口操作
1 | ######### 查看服务 ########## |
18.6. 直接操作
- 这个操作和firewalld原生的不在一起,如果firewalld放开了,这里禁止了,无法访问
- 如果firewalld禁止了,这里放开了,同样无法访问
1 | firewall-cmd --direct -add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j accept |
19. jq linux的json解析工具
1. 几种基本用法
1 | 检查key是否存在 |
20. iotop 磁盘占用统计工具
1. 几种基本用法
- 需要使用root权限
- 类似与top,不需要跟参数
统计中快捷键
o
: 仅显示占用io的进程a
: 显示累计数据shift + P
: 只显示进程,不显示线程,默认显示所有线程- 使用左右方向键来选择排序的列
21. 图片操作工具 imagemagick
21.1. 图片转pdf
- 按照图片名字顺序生成pdf
1 | convert *.jpg +compress foo.pdf |
21.2. pdf转图片
- 执行了下面命令后,就会生成 image_name-0.jpg,image_name-1.jpg等等图片,数目由PDF页数决定。
1 | convert pdf_name.pdf image_name.jpg |
额外的参数
-resize 1800x
: 指定生成的像素大小,越大生成的图片越大,转化的时间越久-density 150
: 参数指定密度,具体含义再查-quality 100
: 指定生成图片的质量
1 | convert -resize 1800x -density 150 -quality 100 pdf_name.pdf image_name.jpg |
21.3. gif和图片转换
1 | gif转jpg |
21.4. 图片信息查看
1 | => identify -verbose misc2.jpg |
22. 模拟网络延迟 tc
- 局限就是只能对某一个网卡设置,不能设定规则来指针对ip和端口
22.1. 基本操作
1 | ######### 增加延迟 ########## |
23. ltrace 跟踪库函数调用
23.1 选项
-r
: 显示运行时间,0.000123
-t
: 和-r
不能同时用,显示当前时间,23:12:11
-tt
: 和-r
不能同时用,显示当前时间,23:12:11.345678
-ttt
: 和-r
不能同时用,显示当前时间戳,1645024757.123456
-T
: 显示调用花费的时间,在函数调用返回值后面用<>
包裹-i
: 显示函数的地址-c
: 显示统计数据,表格形式-S
: 将系统调用显示出来,使用SYS_
作为前缀-p [PID]
: 挂载到一个进程
23.2 实例
1 | 监听一段时间的5623的函数调用次数,需要ctrl c停止监听后才显示结果 |
24. dmidecode 获取硬件信息
24.1. 获取内存信息
- 可以获取到有几个插槽,每个插槽内存信息(包括频率、大小、电压、类型等)
1 | => sudo dmidecode -t memory |
25. nc 网络链接工具
25.1. 选项详解
-l
: 监听-p [port]
: 本地端口,监听状态就绑定这个端口,非监听状态就是使用此端口发送-v
: 显示输出,会打印一些连接过程和错误信息-u
: udp模式,默认是tcp-n
: 不翻译ip到hostname-s
: 监听地址,默认监听所有地址-w [second]
: 连接超时时间,单位秒-z
: 测试模式,用于扫描,连接成功就断开,加上-v
会显示结果
25.2. 基本用法
1 | ######### tcp ########## |
26. curl 网络请求工具
参考: https://blog.csdn.net/angle_chen123/article/details/120675472
26.1. 选项解释
-X [proto]
: 指定协议,可选POST/GET/HEAD/DELETE/PUT/PATCH
,默认是GET-H "[name]: [value]"
: 添加一个header头,示例-H "Content-Type: application/json"
-d @file
: 文件内容为post内容-d "string"
: 内容为post的body内容,指定了-d
会默认使用POST-F "name=@file"
: 表单形式提交文件,会自动设置Content-Type: multipart/form-data
,示例-F "page=@/tmp/a;filename=a.txt"
--insecure
: 允许不授信的证书-o [filename]
: 输出储存到文件-c [filename]
: 将返回的cookie保存到文件-b [filename]
: 将文件内容作为cookie发送-b 'name=value; name=value'
: 设置cookie-x "127.0.0.1:1080"
: 使用代理访问
POST默认的头部数据
1 | POST /api HTTP/1.1 |
GET默认头部数据
1 | GET /api HTTP/1.1 |
26.1. 几种常用的示例
1 | get请求下载文件 |
27. clang
27.1. 查看预定义宏
1 | => clang -dM -E -x c /dev/null |
28. brctl 网桥管理命令
- 命令创建的都只是临时生效,重启后就不生效了。想要持续生效需要参考对应的网络管理器的配置。
- 网桥绑定网卡后,就会接管此网卡,此网卡配置都可以清除,反正不生效。配置网桥即可
28.1. 基本用法
1 | 创建网桥 |
29. sox 音频转换命令
29.1. 常用用法
1 | sox rec.au rec.wav |
30. nslookup 解析域名
30.1. 选项
-q=A
: 查询A记录-vc
: 使用tcp查询
31. wget
31.1. 选项
-r
: 表示递归下载。-np
: 表示不要进入父级目录。-nH
: 表示不要在本地创建主机名目录。--cut-dirs=2
: 表示从第二级目录开始下载。-R index.html
: 表示不下载 index.html 文件。
31.2. 示例
1 | 递归下载此链接下所有文件,不进入父级目录,下载完看到es5目录(前两级裁剪掉了) |
32. hexdump
32.1. 选项
-C
: 显示ascii和hex对应的格式-n <length>
: 指定显示几个字节
32.2. 示例
1 | => hexdump 隐藏的钥匙.jpg | head -n 3 |
33. base64
33.1. 选项
-d
: 解密
33.2. 示例
- base64一般是对文件,如果需要字符串则要使用管道
1 | 解密 |
34. nmcli
networkmanager的命令行工具
34.1. 基本使用
1 | ######### connection 连接相关 ########## |
踩坑记
1) 某个网卡显示没管理
1 | => nmcli device |
- 需要修改
/usr/lib/NetworkManager/conf.d/10-globally-managed-devices.conf
,把ethernet
加进去
1 | [keyfile] |
- 然后重新
systemctl reload NetworkManager.service
就可以了
35. split 大文件分割
35.1. 选项
-l 100
: 指定行数分割-b 500m
: 指定大小分割文件
36.2. 使用示例
1) 按大小分割文件
1 | => ls -lh blackbox.tar.gz |
36. blktrace 磁盘跟踪命令
36.1. blktrace命令
-d <dev>
: 指定设备-a <event>
: 指定采集事件,可以多次使用此选项代表指定多个- barrier: barrier attribute
- complete: completed by driver
- discard: discard / trim traces
- fs: requests
- issue: issued to driver
- pc: packet command events
- queue: queue operations
- read: read traces
- requeue: requeue operations
- sync: synchronous attribute
- write: write traces
- notify: trace messages
- drv_data: additional driver specific trace
-w <seconds>
: 采集时间,默认一直采集直到Ctrl+c
1) 实例
- 采集
/dev/vda
的issue和compelte事件,采集10s,输出默认是vda.blktrace.n
,几个cpu几个文件
1 | => blktrace -d /dev/vda -a issue -a complete -w 10 |
36.2. blkiomon
-h <file>
: 输出可读文件,-
代表输出到stdout-I <interval>
: 输出间隔,配合blktrace就是多少秒输出一次统计
1) 实例
- 统计一段时间内的写入大小,一般用于磁盘写入模型分析
1 | => blktrace -d /dev/vda -a write -w 10 -o - | blkiomon -I 5 -h - |
36.3. blkparse
-i <dev>
: 分析blktrace输出的dev.blktrace.cpu
文件,指定dev会自动找当前目录的文件-o <file>
: 输出text到文件,默认到stdout
1) 实例
1 | => blkparse -i vda -o vda.txt |
四、小技巧
1. swap临时空间(可用于编译时内存不足问题)
1 | 查看内存文件 |
2. 自颁发证书(不受信)
在开发过程中,https请求需要配置ssl证书,这个证书需要到部分供应商申请(阿里云、腾讯云等),自然不是免费的。开发过程中并不想这么麻烦,可以使用shell中的openssl进行自颁发证书。
- 颁发证书需要先生成一个颁发机构,也就是CA
1 | 新建目录防止混乱 |
- 生成证书
1 | 同样生成私钥key |
- 使用ca给证书签名
1 | 签名前需要有几个准备文件 |
- 将生成的domain.crt和domain.key配置到服务器即可
3. 快捷键
Ctrl + a
/home
: 移到行首Ctrl + e
/end
: 移到行首Ctrl + r
: 历史命令搜索,不支持模糊搜索,只支持连续字符Ctrl + k
: 清空光标后面的字符Ctrl + u
: 清空光标前面的字符
4. 安装软件
4.1. 二进制安装
- 一般二进制都会自带依赖,可以直接使用
- linux根目录有一个opt目录,大致是让用户自定义软件放在这里
- /usr/local/bin目录下放的是用户自定义应用,所以移过去后可以软链过去
1 | sudo mv xxx /opt/xxx |
5. 代码扫描
- github搜索shellcheck软件,根据系统安装
- vscode搜索shellcheck插件,安装
- 不在PATH中则手动配置路径即可完成扫描
6. 软件运行
6.1. 临时加载库so
- 只想要当前运行加载so,可以执行下面命令
1 | export LD_LIBRARY_PATH="xxx" |
7. 脚本技巧
7.1. 获取脚本所在目录
1 | !/bin/bash |
8. 有用的软件
8.1. 登陆显示系统信息
安装landscape-common
,可以在登陆时显示下面的信息
1 | Welcome to Ubuntu 20.04.1 LTS (GNU/Linux 5.6.0-25-generic x86_64) |
8.2. x11vnc linux远程桌面
设置密码
- 默认储存到
/home/<username>/.vnc/passwd
1 | x11vnc -storepasswd |
设置开机启动
- 写一个service文件到
/usr/lib/systemd/system/x11vnc.service
- 要修改passwd的路径
1 | [Unit] |
systemctl enable x11vnc
,加到开机启动项中service x11vnc start
,当前开启服务
无显示器模拟显示器
- 在没有显示器的情况下x11vnc特别慢,插上显示器就快了,因为没有显示器显卡不工作
- 安装
xserver-xorg-video-dummy
模拟显示器 - 新增配置文件
/usr/share/X11/xorg.conf.d/xorg.conf
1 | Section "Device" |
- 重启设备就好了
sddm管理桌面x11vnc起不来
- 可能需要单独写一个脚本处理,上面service的exec就指定这个脚本的目录即可
- sddm使用单独的auth模式
1 | !/bin/bash |
gdm3管理桌面x11vnc起不来
- 同上,不过脚本变成下面这样
- 尝试的出现一个问题,当使用gdm3启动kde时,在桌面登陆前,没有
/run/user/1000/gdm/Xauthority
,需要先登录再启动 - 但是存在一个
/run/user/129/gdm/Xauthority
,这个可以打开登陆界面,登陆完这个就只有黑屏,需要使用上面的配置,并且-dislay
需要设置成:1
1 | !/bin/bash |
9. 查看电量
1 | cat /sys/class/power_supply/battery/capacity |
10. 命令后台执行
10.1. 已启动进程
1 | => test.sh |
10.2. 直接后台启动进程
1 | &将进程转后台执行,此时bash不能退出,因为进程是bash的子进程 |
12. shell脚本单例
1 | # 进程单例判断 |
13. 挂载windows共享文件夹
uid
和gid
需要根据需要设置成对应的id,为挂在过来的所属用户和用户组
1 | 查看windows共享文件夹 |
踩坑记
1. ssh用rsakey无法免密登陆
- sshd要求使用rsakey需要有以下权限限制
/home/xxx
需要700权限,不允许用户组编辑/home/xxx/.ssh
需要700权限/home/xxx/authorized_keys
需要600权限