1.变量
- 环境变量
不用事先定义就能狗使用的变量(系统预定义好了)
# 查询所有变量
env
# 常用环境变量
$USER # 当前用户
$HOME # 当前用户家目录
$PATH # 目前的执行路径(Linux会在这个变量里面搜索可执行命令)
$PWD # 当前工作目录
- 自定义变量
# 变量声名(不用写变量类型 所有变量都是字符串)
a=5
# 调用变量 没有歧义的时候 可以省略大括号
echo ${a}
echo $a
# 将变量提升为全局变量
export a
变量的定义是在bash进程的内存中 如果执行脚本 会启动一个子bash环境 此时父环境的变量子环境是无法读取的 除非将变量提升为全局变量
- 脚本里使用的特殊变量
参数(1-9,${10+})
#! /bin/bash
# 打印命令的前三个参数
echo $1 $2 $3
参数个数($#)
#! /bin./bash
# 打印参数个数
echo $#
所有参数(*,@)
#! /bin/bash
# 打印所有参数
echo $*
echo $@
上一条指令的返回码
mkdir abc
echo #?
2.运算
由于变量是字符串 shell不支持直接计算 需要用特殊语法 只支持整数运算
# 计算 a + b
a = 5 b = 5
echo $((a+b))
3.逻辑表达式(test 或者[])
# 用法
test expr 或 [ expr ]
# 返回值就是返回码
#与或非
test expr1 -a expr2 # 逻辑与
test expr1 -o expr2 # 逻辑或
test !expr1 # 逻辑非
# 例如 判断变量a、b是否相等 且a是非空串
test "$a" = "$b" -a "$a"
# 数值判断
test "$a" -gt "$b" #a>b 也可以写作[ "$a -gt $b" ]
test "$a" -ge "$b" #a>=b
test "$a" -eq "$b" #a==b
test "$a" -lt "$b" #a<b
test "$a" -le "$b" #a<=b
test "$a" -ne "$b" #a!=b
# 判断文件是否存在
test -e "/root/abc" # 判断/root/abc是否存在(文件或文件夹或软连接都可以)
test -f "/root/abc" # 判断/root/abc是否存在并且是一个文件
test -d "/root/abc" # 判断/root/abc是否存在并且是一个文件夹
test -L "/root/abc" # 判断/root/abc是否存在并且是一个软连接
# 判断当前用户是否对文件有权限
test -r "/root/abc" # 判断当前用户对/root/abc是否具有读权限
test -w "/root/abc" # 判断当前用户对/root/abc是否具有写权限
test -x "/root/abc" # 判断当前用户对/root/abc是否具有执行权限
# 字符串判断
test "${a}" # 判断a变量是否是非空串(空串返回false)
test -z “${a}” # 判断a变量是都是空串(非空串返回false)
test "${a}" = "${b}" # 判断a变量是否和b变量是相同的字符串
流程控制
1.if
#! /bin/bash
# 根据输入的第一个参数:
# 如果是1打印a
# 如果是2打印b
# 如果是其他打印 c
if test "$1" = "1"
then
echo a
elif test "$1" = "2"
then
echo b
else
echo c
fi
2.case
#! /bin/bash
# 根据输入的第一个参数:
# 如果是1打印a
# 如果是2打印b
# 如果是其他打印c
case “$1” in
"1")
echo a
;;
"2")
echo b
;;
*)
echo c
;;
esac
3.for
#! /bin/bash
# 从1 加到 100
s=0
for ((i=1;i<=100;i++))
do
s=$((s+i))
done
echo $s
#! /bin/bash
# 增强for
for i in abc def ghi
do
echo ${i}xxxxx
done
4.while
#! /bin/bash
# 从1加到100
s=0
i=1
while test $i -le 100
do
s=$((s+i))
i=$((i+1))
done
echo $s
5.读取控制台输入
# read
# -p 提示语
# -t 截止时间
# -r 自动转义(所输即所得)
read -r -t 5 -p "请在5s内输入一些东西:" abc
echo ${abc}
6.函数
# 函数的定义
function abc(){
echo abcdef
}
# 函数中引用参数
function abc(){
echo $1
echo $2
echo $3
}
# 定义又返回值的函数
function add() {
echo $(($q+$2))
}
result=$(add 1 6)
# 系统自带函数
basename # 获取文件名
diename # 获取文件父目录
# 注: 这两个函数都不会检查文件的存在性
# dirname的参数如果是相对路径 父目录也会返回相对路径 而不是绝对路径
# 想要dirname获取绝对路径 代码如下
cd -P $(dirname asdfads); pwd
7.流式数据处理指令
这些指令的特点就是 接受标准输入来的数据 处理完成后 输出到标准输出
- cut
# 从一行中剪切出我们想要的某一部分
# 按照分隔符分割 取其中某一段
ip addr show ens33 | grep global | grep 'inet' | cut -d " " -f 6 # 按空格切分行 取第六列
# 直接剪切特定位置的字符串
ip addr show ens33 | grep globa | grep ‘inet’ | cut -c 10-26 # 取第10到第26字节的内容
ip addr show ens33 | grep global | grep ‘inet’ | cut -c 10,26 # 取第10字节和第26字节
- grep
# 接受标准输入 过滤出我们想要的行 grep的参数是一个正则表达式
# 从一个文件中抓出想要的行
grep 'pattern' filename
# 从一个文件夹的所有文件中抓出特定的行
grep 'pattern' dir/*
# 带行号抓取
grep -n 'pattern' dir/*
# 递归抓取目录文件
grep -r -n 'pattern' dir/
# 反向抓取
grep -v 'abc' filename # 从filename文件中排除包含abc的行
# 结合管道符 抓取标准输入来的数据
ifconfig | grep 'broadcast'
- sed
# 对标准输入的数据做增删改 将修改后的数据输出到标准输出
# 在某一行后面增加:a,例如:在第三行后面增加一行xxxxx
ifconfig | grep -n '.*' | sed '3axxxxx'
# 删除某一行:d,例如:删除第三行
ifconfig | grep -n '.*' | sed '3d'
# 对某一行内容进行替换:s,例如将第三行中所有的数字替换成x 末尾的g表示全部替换 不加表示只替换第一个
ifconfig | grep -n '.*' | sed '3,5s/[0-9]/x/g'
# 行号可以写成范围 例如:将3-5行中的所有数字替换成x
ifconfig | grep -n '.*' | sed '3,5s/[0-9]/x/g'
# 行标记不一定非得是特定行号 可以用正则表达式匹配
ifconfig | grep | -n '.*' | sed '/^1/s/[0-9]/x/g'
# 正则表达式的行号 也可以写成范围
ifconfig | grep -n '.*' | sed '/^1:/,/^6:/s/[0-9]/x/g'
# 除了处理来自标准输入的数据 也可以将文件作为数据来源 例如: 将passwd文件中包含root的行剔除
sed '/root/d' passwd
# 如果想要直接修改文件 加-i参数 例如 删除passwd文件中包含root的行
sed -i '/root/d' passwd
- awk
# 对标准输入的数据做分列 然后进行数据处理
# 将passwd文件按照冒号分列 打印第一列
awk -F ":" '{print $1}' passwd
# 将passwd文件按照冒号分列 打印所有s开头的行的第一列
awk -F ":" '/^s/{print $1} ' passwd
# 将passwd文件按照冒号分列 s开头的行打印第一列 shutdown开头的行打印第三列
awk -F ":" '/^s/{print $1} /^shutdown/{print $3}' passwd
# 两个特殊的pattern: BEGIN和END
awk -F ":" 'BEGIN{print "数据处理之前先执行我"} END{print "所有数据处理完成再执行我"} /^s/{print $1} /^shutdown/{print $3}' passwd
# 累加第三列
awk -F ":" 'BEGIN{sum=0} {sum+=$3} END{print sum}' passwd
# 展示累加过程
awk -F ":" 'BEGIN{sum=0} {sum+=$3;print $3" "sum} END{print sum}' passwd
8.正则表达式
正则表达式是类似于通配符一样的匹配一系列具有通用特征字符串的pattern
1.无特殊符号的正则表达式 匹配其自身
# 从passwd文件中匹配包含halt的行
grep 'halt' passwd
2.^匹配一行开头的位置
# 从passwd文件中匹配以halt开头的行
grep '^halt' passwd
3.$匹配一行末尾的位置
# 从passwd文件中匹配以halt结尾的行
grep 'halt$' passwd
- .匹配一个任意字符(不包含换行符)
# 从passwd文件中匹配r??t的行
grep 'r..t' passwd
5.*不单用 与上一个子式连用 表示上一个子式匹配0-n次
# 从passwd文件中匹配rot,root,rooot......之类的字符串
grep 'ro*t' passwd
# 从passwd中匹配r开头t结尾的任意长度字符串(贪心匹配 会匹配尽量长的字符串)
grep 'r.*t' passwd
6.[]表示匹配某一范围内的任意一个字符串
[abc] # 匹配a或b或c任意一个字符
[a-c] # 匹配a或b或c任意一个字符
[a-cf-g] # 匹配a,b,c,f,g中任意一个字符
# 从source中匹配rat,rbt或rct
grep 'r[abc]t' source
7.\转义符号 不单用 消除其后面一个特殊符号的特殊含义
# 匹配^本身
grep '\^' source