Shell Cheatsheet
shell是提供与内核沟通接口的命令解释器程序,但实际上shell是这种解释器的统称,Linux系统的shell种类很多,包括Bourne shell(简称sh)、Bourne Again shell(简称bash)、C shell(简称csh)、K shell(简称ksh)、Shell for Root等等。
sh和bash都是Linux系统shell的一种,其中bash命令是sh命令的超集,大多数sh脚本都可以在bash下运行。Linux系统中预设默认使用的就是bash。
基础
Linux提供的Shell解析器有:
1 | [atguigu@hadoop101 ~]$ cat /etc/shells |
执行方式
shell脚本以#!/bin/bash
开头(指定解析器)
1 | 创建脚本 |
python脚本以
#!/usr/bin/python
开头(指定python解析器)
执行python脚本只能显式调用python解释器:[linux@localhost datas]$ python helloworld.py
screen后台管理
开启一个由screen管理的终端,此时出现一个新终端
1 | screen -S first |
如果这个终端不小心关闭,这可以重新登录screen找到这个终端
1 | screen -list |
若想退出screen管理的这个这个终端,在该终端下键入ctrl+d
即可
screen -S xxx -> 新建一个叫xxx的session
screen -ls -> 列出当前所有的session
screen -r xxx -> 回到xxx这个session
screen -d xxx -> 远程detach某个session
screen -R 先试图恢复离线的作业。若找不到离线的作业,即建立新的screen作业。
screen -d -r xxx -> 结束当前session并回到xxx这个session
在每个screen session 下,所有命令都以 ctrl+a(C-a) 开始:
[
-> 进入 copy mode,在 copy mode 下可以回滚、搜索、复制就像用使用 vi 一样,ctrl+c退出该模式n
-> Next,切换到下一个 windowp
-> Previous,切换到前一个 window
tmux
摘自:https://pragmaticpineapple.com/gentle-guide-to-get-started-with-tmux/
ctrl+b:进入tmux命令模式,tmux的命令都要先加上ctrl+b
ctrl+b + ?:如果忘记了tmux命令,可以用该命令
pane management
ctrl+b + “:水平创建一个pane
ctrl+b + %:垂直创建一个pane
ctrl+b + LeftArrow/Right/Up/Down:在pane之间移动光标
ctrl+d:关闭pane
window management
ctrl+b + c:创建window
底部有各window的名称(默认是序号,从0开始)与该window正在运行的任务,带星号*的window是当前焦点所在window,带折号-的window是最后一个window
ctrl+b + 0/1/2:前往第0/1/2号window
ctrl+b + p/n:前往previous window/前往next window
sessions
tmux ls:列出所有session
ctrl+b + d:退出tmux当前session
tmux new -s heythere:创建名为heythere的session
tmux attach -t heythere:连接名为heythere的session
1 | tmux ls |
wc
命令格式:
wc [选项]文件…命令功能:
统计指定文件中的字节数、字数、行数,并将统计结果显示输出。该命令统计指定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。wc同时也给出所指定文件的总统计数。命令参数:
-c 统计字节数。
-l 统计行数。
-m 统计字符数。这个标志不能与 -c 标志一起使用。
-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。
-L 打印最长行的长度。
–help 显示帮助信息
–version 显示版本信息
例子: 在文件a中统计 hello 出现的行数:
grep hello a | wc -l
在文件a中统计hello出现的次数:
grep -o hello a | wc -l
grep
1 | grep xxx xxx.log #文件查找 |
日志文件很大,想从中grep某个字段耗时很久,这时可以用tac命令从后往前查:tac xxx.log | grep xxx
cp
复制时自动创建不存在的子目录:http://www.dreamwu.com/post-1346.html
cp: with –parents, the destination must be a directory
du
du -h -d 1 展示当前目录所有文件及文件夹的大小,深度为1就是指当前目录
tail
最常用的tail -f
1 | tail -300f shopbase.log #倒数300行并进入实时监听文件写入模式 |
find
1 | find /home/admin -size +2500k # 搜索目录下超过2500k的文件,+号改-号就变成搜索小于2500k的文件 |
linux下文件的创建时间、访问时间、修改时间和改变时间:https://blog.csdn.net/zyz511919766/article/details/14452027
分析
uptime
- 最后三个数字是1、5、15分钟内的平均负载,可以通过这个变化趋势判断负载的变化
- 平均负载是指数衰减移动平均数
- 平均负载大于CPU数量,表示CPU不足以服务线程,有些线程在等待,一个有64颗CPU的系统的平均负载为128,这意味着平均每个CPU上有一个线程在运行,还有一个线程在等待
1 | uptime |
vmstat
虚拟内存统计信息,第一行是系统启动启动以来的总结信息
- swpd:交换出的内存量,单位KB,下同
- free:空闲的可用内存
- buff:用于缓冲缓存的内存
- cache:用于页缓存的内存
- si:换入的内存(换页)
- so:换出的内存(换页)
- r:运行队列长度——可运行线程总数
- us:用户态时间
- sy:系统态时间
- id:空闲
- wa:等待I/O,即线程被阻塞等待磁盘I/O的CPU空闲时间
如果si和so列一直非0,那么系统正存在内存压力,可以用其他工具研究什么在消耗内存
vmstat参数-S可将输出设置为MB,这样会对齐方便阅读
1 | vmstat 1 |
mpstat
多处理器统计信息,报告每个CPU的统计信息
- CPU:逻辑CPU ID,或者ALL表示总结信息
- %usr:用户态时间
- %nice:以nice优先级运行的进程用户态时间
- %sys:系统态时间(内核)
- %iowait:I/O等待
- %irq:硬件中断CPU用量
- %soft:软件中断CPU用量
- %quest:花在访客虚拟机的时间
- %idle:空闲
%usr+%sys达到100%,则说明跑满!
1 | mpstat -P ALL |
sar
- 系统活动报告,system activity information
ps
进程状态
源于BSD的风格
- a:所有用户
- u:扩展信息
- x:没有终端的进程
源于SVR4
- -e:所有进程
- -f:完整信息
TIME:进程自创建开始消耗的CPU总时间(用户态+系统态),小时:分钟:秒
%MEM:主存使用(物理内存、RSS)占总内存的百分比
RSS:常驻集合大小(KB)
包括系统库在内的映射共享段,如果把所有RSS列求和,可能会超过系统的内存总和,这是因为重复计算了这部分共享内存
VSZ:虚拟内存大小(KB)
1 | ps aux |
top
最消耗CPU的任务,默认按照CPU用量排序
TIME+:1:36.53代表在CPU上的时间总计为1分36.53秒
1
2
3
4
5
6
7
8top
top - 17:58:46 up 304 days, 20:31, 1 user, load average: 7.45, 7.46, 7.53
Tasks: 518 total, 8 running, 494 sleeping, 0 stopped, 16 zombie
Cpu(s): 22.3 us, 0.3 sy, 0.0 ni, 77.4 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 13146870+total, 46123176 free, 25231976 used, 60113548 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 10480180+avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND注意top命令本身也是非常消耗CPU的!
time
用来运行命令并报告CPU用量
1
2
3
4
5
6time echo "hello"
hello
real 0m0.000s
user 0m0.000s
sys 0m0.000s
perf
- 原名为Linux性能计数器,现在是Linux性能事件
iostat
汇总单个磁盘的统计信息,通常是调查磁盘IO问题使用的第一个命令
-c:显示CPU报告
-d:显示磁盘报告
-k/-m:以KB/MB显示
-x:输出扩展信息
1
2
3
4
5
6
7
8
9iostat
[内核版本 主机名 日期 架构 CPU数量]
avg-cpu: %user %nice %system %iowait %steal %idle
6.49 0.00 0.39 0.07 0.00 93.04
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
vda 18.83 7.56 258.81 199523373 6833818632
vdb 15.41 159.75 1708.72 4218061185 45118703004
netstat
- 网络统计书许
- 默认:列出连接socket的信息
- -a:列出所有socket的信息
- -s:网络栈统计信息
- -i:网络接口信息
- -r:列出路由表
- -n:不解析IP地址为主机名
- -c:连续模式,每秒输出最新的统计信息到终端
1 | 网络接口、MTU、接收(RX-)、传输(TX-)指标 |
ifconfig
- 即能手动设置网络接口,也可以列出所有网络接口的当前配置,数据与netstat -i一致
- ifconfig已经被ip命令淘汰
ip
- 配置网络接口和路由,并且观测它们的状态和统计信息,数据与netstat -i一致
lsof
- 按进程ID列出包括socket细节在内的打开文件
ss
- socket统计信息
ddddddddd
dd
d
d
d
d
d
dd
d
d
d
d
d
d
shell编程
shell变量
- 定义变量时,变量名不加美元符号$
- 定义变量时,变量名和等号之间不能有空格
- 使用一个定义过的变量只要在变量名加上美元符号$即可
- shell变量分为局部变量(变量前面加local)和全局变量(变量前面不添加),局部变量的可见范围是代码块或函数内,全局变量则全局可见,和别的语言类似。
1 | name=chenying |
shell字符串
- 字符串可以用单引号,也可以用双引号。
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的,也不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
- 双引号里可以有变量,双引号里可以出现转义字符。
1 | name='Isabella' |
拼接字符串
1 | name='Isabella' |
获取字符串长度
1 | string="Isabella" |
截取字符串
此栗子从字符串第 3 个字符开始截取 6 个字符:
1 | string="abcdefghijklmn" |
数组
用括号来表示数组,数组元素用”空格”符号分割开,既可以一次性定义,也可以一个个定义,可以使用不连续的下标,下标范围也没有限制
1 | 定义数组name |
获取数组长度
1 | 取得数组元素的个数 |
传递参数
脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推。
1 | !/bin/bash |
执行./test.sh a b c,输出结果为:
1 | 第一个参数为:a |
使用expr表达式计算
- 加+ 减- 乘* 除/ 取余% 赋值= 相等== 不相等!=
- 表达式和运算符之间要有空格,例如 1+1 是不对的,必须写成1 + 1;
- 整个表达式要被 `` 包含;
1 | !/bin/bash |
输出结果:
1 | a + b : 30 |
流程控制
if-else条件分支
1 | 判断两个变量是否相等 |
for循环
1 | 1 |
1 | 遍历当前文件目录中的所有文件 |
while循环
1 | while condition |
until循环
until 循环执行一系列命令直至条件为 true 时停止,与 while 循环在处理方式上刚好相反。
1 | until condition |
case
shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令,语法格式:
1 | case 值 in |
跳出循环
在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:break和continue。
shell函数
简化写法中function可以不写,语法格式
1 | function name() { |
grep——擅长查找
这里的模式,要么是字符(串),要么是正则表达式。
1 | grep [OPTIONS] PATTERN [FILE...] |
grep常用选项如下:
- -c:仅列出文件中包含模式的行数。
- -i:忽略模式中的字母大小写。
- -l:列出带有匹配行的文件名。
- -n:在每一行的最前面列出行号。
- -v:列出没有匹配模式的行。
- -w:把表达式当做一个完整的单字符来搜寻,忽略那些部分匹配的行。
sed——擅长取行和替换
1 | sed [option]... 'script' inputfile |
sed常用选项如下:
- -e:可以在同一行里执行多条命令
- -f:后跟保存了sed指令的文件
- -i:直接对内容进行修改,不加-i时默认只是预览,不会对文件做实际修改
- -n:sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
sed常用操作:
- a:向匹配行后面插入内容
- i:向匹配行前插入内容
- c:更改匹配行的内容
- d:删除匹配的内容
- s:替换掉匹配的内容
- p:打印出匹配的内容,通常与-n选项一起使用
- w:将匹配内容写入到其他地方。
1 | 输出长度不小于50个字符的行 |
替换模式(操作为s):
- g 默认只匹配行中第一次出现的内容,加上g,就可以全文替换了。常用。
- p 当使用了-n参数,p将仅输出匹配行内容。
- w 和上面的w模式类似,但是它仅仅输出有变换的行。
- i 这个参数比较重要,表示忽略大小写。
- e 表示将输出的每一行,执行一个命令。不建议使用,可以使用xargs配合完成这种功能。
1 | 一行命令替换多处内容,不加-e只能替换第一处的内容 |
awk——擅长取列
awk支持用户自定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具
1 | awk [options] 'script' var=value file(s) |
- -F fs:fs 指定输入分隔符,fs可以时字符串或正则表达式
- -v var=value:赋值一个用户定义变量,将外部变量传递给awk
- -f scriptfile:从脚本文件中读取awk命令
一般的开发语言,数组下标是以0开始的,但awk的列$是以1开始的,而0指的是原始字符串。
1 | 对于csv这种文件来说,分隔的字符是,。AWK使用-F参数去指定。以下代码打印csv文件中的第1和第2列。 |
使用sh -x调试shell脚本
sh -x的作用:
- “-x”选项可用来跟踪脚本的执行,是调试shell脚本的强有力工具。
- “-x”选项使shell在执行脚本的过程中把它实际执行的每一个命令行显示出来,并且在行首显示一个”+”号。
- “+”号后面显示的是经过了变量替换之后的命令行的内容,有助于分析实际执行的是什么命令。
利用shell内置的环境变量调试:
- $LINENO:代表shell脚本的当前行号,类似于C语言中的内置宏__LINE__
- $FUNCNAME:函数的名字,类似于C语言中的内置宏__func__,但宏__func__ 只能代表当前所在的函数名,而$FUNCNAME的功能更强大,它是一个数组变量,其中包含了整个调用链上所有的函数的名字,故变量${FUNCNAME [0]}代表shell脚本当前正在执行的函数的名字,而变量${FUNCNAME[1]}则代表调用函数${FUNCNAME[0]}的函数的名字,余者可以依此类推。
- $PS4:主提示符变量$PS1和第二级提示符变量$PS2比较常见,而$PS4的值将被显示在“-x”选项输出的每一条命令的前面。在Bash Shell中,缺省的$PS4的值是”+”号。
- 利用$PS4这一特性,通过使用一些内置变量来重定义$PS4的值,我们就可以增强”-x”选项的输出信 息。例如先执行export PS4=’+{$LINENO:${FUNCNAME[0]}} ‘, 然后再使用“-x”选项来执行脚本,就能在每一条实际执行的命令前面显示其行号以及所属的函数名。
本文落笔与 2021-07-25