Bash
shell是Linux内核与用户之间的解释器程序
变量
- 自定义变量,名称可以用数字、字母、下划线、不能以数字开头,不能使用特殊符号,等号两边不能有空格 
- 格式:
变量名称=值 
 - 格式:
 - 环境变量,由系统提前定义好,使用时直接调用 
- 当前用户名:
USER - 当前用户ID:
UID - 当前家目录:
HOME - 主机名:
HOSTNAME - 当前用户的解释器:
SHELL - 当前位置:
PWD - 存储命令的路径:
PATH - 一级提示符:
PS1 - 二级提示符:
PS2 
 - 当前用户名:
 - 位置变量与预定义变量 
$1:执行脚本时后面第1个位置参数$2:执行脚本时后面第2个位置参数$3:执行脚本时后面第3个位置参数$*:执行脚本时后面所有位置参数$#:执行脚本时后面位置参数的个数$$:当前程序的进程号$?:判断上一条指令是否执行成功
 
env查看所有环境变量
set查看所有变量
""双引号,界定范围
''单引号,界定范围,屏蔽特殊符号``或者$()获取命令的执行结果
指令
read
-p可以定义提示信息,u相当于自定义名称
#!/bin/bash
read -p "请输入用户名" u
useradd $u
 
stty
stty -echo:屏蔽回显stty echo:恢复回显
expr
- 加、减、乘、除、取余,直接输出
 
a=10
b=20
expr $a + $b  # 30
 
[ ] 或 []或 []或(())
- 加、减、乘、除、取余,不输出
 
a=10
b=20
echo $[a+b]  # 30
 
let
- 加、减、乘、除、取余,不输出,专门用于变量的创建,或者变量的自增
 
let a++
let a+=10
 
bc
- 加、减、乘、除、取余,可以进行小数计算
 
echo "1.1+1" | bc
echo "scale=3;10/3" | bc  # 指定小数点后保留3位
 
条件测试
字符串测试
==:判断等号两边的字符串是否相等!=:判断等号两边的字符串是否不等
[ a == b]
[ a != b]
-z:判断变量是否为空! -z:判断变量是否非空
[ -z $a ]
[ ! -z $a ]
 
逻辑组合
&&:条件成功执行||:条件失败执行
[ root == $USER ] && exit  # &&左边成功,才会执行exit
[ root == $USER ] || exit  # ||左边失败,才会执行exit
 
数字判断
-eq:等于-ne:不等于-gt:大于-ge:大于等于-lt:小于-le:小于等于
文件判断
-e:判断文件是否存在-f:判断文件是否存在,并且是普通文件-d:判断文件是否存在,并且是目录-r:判断当前用户对文件是否有读权限-w:判断当前用户对文件是否有写权限-x:判断当前用户对文件是否有执行权限
字符串处理
- 字符串截取:
${变量:index:step} - 字符串拼接:
c=aaa$c - 字符串替换:
${变量/旧/新}(替换一个),${变量//旧/新}(替换全部) - 字符串删除:
${变量#要删除的内容}(从头部开始,匹配最短,##就是匹配最长),${变量%要删除的内容,}(从尾部开始,匹配最短,%%就是匹配最长) - 定义变量初值:
${变量:-初值} 
# 随机6位数密码
x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789
for i in {1..6}
don={RANDOM&62}a=${x:n:1}c=a$c
done
echo $c# 字符串替换 aaabbbccc -> aasbbbccc
a=aaabbbccc
a=${a/aaa/aas}# 字符串删除,将abcdefg中的abcd删除
a=abcdefg
echo ${a#*d}  # efg# 字符串删除,将abcdefg中的efg删除
echo ${a%e*}  # abcd# 定义变量初值
echo ${n:-123456}  # 123456
 
三剑客
grep
基本正则列表
| 正则符号 | 描述 | 
|---|---|
| ^ | 匹配行首 | 
| $ | 匹配行尾 | 
| [] | 集合,匹配集合中的任意单个字符 | 
| [^] | 对集合取反 | 
| . | 匹配任意单个字符 | 
| * | 匹配前一个字符任意次数(*不允许单独使用) | 
| \{n,m\} | 匹配一个字符n到m次 | 
| \{n\} | 匹配一个字符n次 | 
| \{n,\} | 匹配一个字符n次及以上 | 
| \(\) | 保留,有个分组的意思 | 
grep '^root' /etc/passwd  # 找以root开头的行
grep 'bash$' /etc/passwd  # 找以bash结尾的行
grep '^$' /etc/passwd  # 找到空行
grep -v '^$' /etc/passwd  # 找到非空行grep '[abcd]' /etc/passwd # 显示a、b、c、d任意一个字母
grep '[^abcd]' /etc/passwd  # 找不是a、b、c、d的其他内容
grep '[0-9]' /etc/passwd  # 显示所有数字
grep '[^0-9]' /etc/passwd  # 显示非数字
grep '[a-z]' /etc/passwd  # 显示所有小写字母
grep '[A-Z]' /etc/passwd  # 显示所有大写字母
grep '[0-9a-Z]' /etc/passwd  # 显示所有数字和字母
grep '[^0-9a-Z]' /etc/passwd  # 显示所有字符grep '.' /etc/passwd  # 显示单个字符
grep 'r..t' /etc/passwd  # 找到rt之间有两个任意字符的行
grep 'ro*t' /etc/passwd  # 找到rt,中间有0个或者多个o的的行 rt rot root这样都行
grep '.*' /etc/passwd  # 找任意,包含空行grep 'ro\{1,2\}t' /etc/passwd  # 找到rt,中间的o可以有1~2个
grep 'ro\{2\}t' /etc/passwd  # 找到rt,中间的o必须是2个
grep 'ro\{2,\}' /etc/passwd  # 找到rt,中间的o有2个或者超过两个的
 
扩展正则列表
| 正则符号 | 描述 | 
|---|---|
| + | 最少匹配一次,1次到多次 | 
| ? | 最多匹配一次,0次到1次 | 
| {n,m} | 匹配n到m次 | 
| () | 组合成整体 | 
| | | 或者 | 
| \b | 单词边界 | 
| \w | 匹配数字、字母、下划线 | 
| \s | 匹配空格 | 
| \d | 匹配数字,grep -P支持 | 
以上命令均可以加-E选项,并且去掉所有的\
grep 'ro\{1,\}t' /etc/passwd
grep -E 'ro+t' /etc/passwd
egrep 'ro+t' /etc/passwdegrep 's?bin' /etc/passwd  # 匹配sbin或者binegrep 'ro{1,5}t' /etc/passwd # 配置rt,中间的o出现1次到5次egrep '(:0)+' /etc/passwd  # 将:0看做一个整体,匹配1次或多次egrep '^bin|^root' /etc/passwd  # 找到以bin或者root开头的行egrep '\bthe\b' test.txt  # test.txt中的the,两边不允许出现数字,字母,下划线
 
sed
格式:sed 选项 条件 指令 文件
- 选项 
-n:屏蔽默认输出-r:支持扩展正则-i:修改源文件
 - 指令 
p:输出d:删除s:替换a:行下添加i:行下添加c:替换整行
 
# 输出
sed -n 'p' /etc/passwd  # 输出第一行
sed -n '2p' /etc/passwd  # 输出第二行
sed -n '2,4p' /etc/passwd  # 输出第二行到第四行
sed -n '2p,4p' /etc/passwd  # 输出第二行和第四行
sed -n '3,+1p' /etc/passwd  # 输出第三行和后面一行
sed -n '/^root/p' /etc/passwd  # 输出以root开头的行
sed -nr '/^root|^bin/p' /etc/passwd  # 输出以root或者bin开头的行
sed -n '1!p' /etc/passwd  # 输出除第一行外的其他行
sed -n '$p' /etc/passwd  # 输出最后一行
sed -n '=' /etc/passwd  # 输出行号
sed -n '$=' test.txt  # 输出文件的总行数# 删除
sed 'd' test.txt  # 删除第一行
sed '4d' test.txt  # 删除第四行
sed '4,7d' test.txt  # 删除4~7行
sed '/^bin/d' test.txt  # 删除以bin开头的行
sed '/xml/d' test.txt  # 删除所有包含xml的行
sed '/!xml/d' test.txt  # 删除不包含xml的行
sed '$d' test.txt  # 删除最后一行
sed '/^$/d'test.txt  # 删除所有空行# 替换
sed 's/2222/3333/' test.txt  # 将所有行的第一个2222替换成3333
sed 's/2222/3333/2' test.txt  # 将所有行的第二个2222替换成3333
sed '1s/2222/3333/1' test.txt  # 将第一行的第一个2222替换成3333
sed 's/2222/3333/g' test.txt  # 将所有的2222替换成3333
sed '/^root/s/2222/3333/g' test.txt  # 将以root开头的行里面的所有的2222替换成3333
sed 's@/bin/bash@/sbin/nologin@g' test.txt  # 将所有的/bin/bash改成/sbin/nologin,这里的@理论上可以用所有数字键上的符号# a、i、c
sed 'a haha' test.txt  # 在每行下面添加一行,内容为haha
sed '1a haha' test.txt  # 在第一行下面添加一行,内容为haha
sed '/^root/a haha' test.txt  # 在开头为root的那一行下面添加一行,内容为haha
sed '$a haha' test.txt  # 在最后一行下面添加一行,内容为hahased '/bin/i heihei' test.txt  # 在有bin的行上面添加一行,内容为heiheised '/aaa$/c hoho' test.txt  # 将以aaa结尾的那一行替换成hoho
 
awk
格式:awk 选项 条件 指令 文件
- 选项 
-F:定义分隔符
 - 指令 
print:输出
 - 条件 
/字符串/
 - 内置变量 
$0所有列、$1第一列、$2第二列、$3第三列…NR:行号NF:列号
 - 处理时机 
BEGIN:执行一次,读取文档之前执行- 逐行任务
 END:执行一次,读取文档之后执行
 
awk '/to/{print}' test.txt  # 输出带有to的行
awk '/to/{print $2}' test.txt  # 输出带有to的行的第二列
awk '{print $0,$1}' test.txt  # 输出所有列 第一列
awk '/^deb-src/{print NR": "$0}' test.txt  # 输出以deb-src开头的行号: 内容
awk '{print NR,NF}' test.txt  # 输出所有行的行号,列数
awk -F: '{print $1"的home目录"$6}' /etc/passwd  # 以:为分隔符,输出  用户名的home目录/xxx/xxx
df -h | awk '/\/$/{print $4}'  # 输出/根目录还剩多少空间awk -F: '$6~/root/{print}' /etc/passwd  # 输出第6列包含root的行
awk -F: '$6!~/root/{print}' /etc/passwd  # 输出第6列不包含root的行awk -F: '$3<3{print}' /etc/passwd  # 输出第3列小于3的行
awk -F: 'NR==2{print}' /etc/passwd  # 输出第二行
awk -F: 'NR>2{print}' /etc/passwd  # 输出行号大于2的行awk -F: 'NR==2||NR==4{print}' /etc/passwd  # 输出行号等于2或者等于4的行
awk -F: '$7~/bash/&&$3<=500{print}' /etc/passwd  # 第7列包含bash并且第三列小于等于500的行awk -F: 'BEGIN{print "User\tUid\tHome"}{print $1"\t"$3"\t"$6}END{print "Total: "NR}' user
User	Uid	Home
root	0	/root
bin	1	/bin
daemon	2	/sbin
adm	3	/var/adm
lp	4	/var/spool/lpd
Total: 5# 统计ip访问次数
awk '{a[$1]++}END{for(i in a){print i"\t"a[i]}}' /var/log/nginx/access.log