Shell
Shell概述起步
shell相关概念
shell基本概念:shell是shell程序和linux内核之间的解释器(常用的shell解释器:sh;bash)
shell编写机制:shell脚本中的命令按顺序依次执行(交互式命令的交互参数用EOF包裹并顶格书写)
shell脚本结构
#!/bin/bash #指定shell脚本运行环境(自由选择解释器)
#author :"author_name" #标明脚本作者
#create_time :"time" #标明脚本创建时间
#description :"description_content" #描述脚本功能
"script_content" #脚本具体内容
shell执行方式
(1)权限路径执行
chmod "right" "shell.sh" #赋予执行用户对shell脚本的执行权限
"file_path" "shell.sh" #直接访问shell脚本执行(绝对路径和相对路径均可)
(2)解释器执行法
"interpreter" "shell.sh" #调用解释器执行shell脚本(无需用户获得脚本的执行权限)
shell特殊符号
| ~ | - | ! | $ | & | `` | "" | '' | $? |
|---|---|---|---|---|---|---|---|---|
| 家目录 | 上一次路径 | 执行历史命令 | 取变量 | 后台执行 | 命令嵌套命令 | 字符串(能解释变量) | 字符串(不解释变量) | 上一条命令的执行状态码 |
$*:代表所有参数
$#:代表参数数量
$$:代表脚本运行的PID
$_:代表脚步最后一次执行的指令
$n:脚本的第n个参数
Shell数学运算
运算符号
| 加 | 减 | 乘 | 除 | 余 |
|---|---|---|---|---|
| + | - | *(默认通配符,需要转义字符转义才为乘) | \ | % |
运算方式
(1)expe:数学运算(只能整数运算)
(2)let :数学运算(只能整数运算)(必须把运算结果存放在变量中)
(3)(()):数学运算(只能整数运算)
(4)bc :数学运算(默认整数运算)(scale="num":切换为浮点运算并指定运算结果的小数位数)
(1)expe "a" + "b" #计算a+b的结果并输出
(2)let "c" = "a" + "b" #计算a+b的结果并存于变量c中
(3)(("a" + "b")) #计算a+b的结果并输出
(4)bc "a" + "b" #计算a+b的结果并输出(交互式,算式写在交互窗口,支持浮点计算)
Shell输入输出
格式化输入
read:输入(默认输入的数据在终端上可以看到)
-s:无输入回显
-t:设置输入限定时间,超过时间自动退出
-n:限定输入字符的最大个数
-p:添加打印功能
read -s "variable" #无回显输入并存于变量中
read -t6 "variable" #6秒内输入并存于变量中
read -n8 "variable" #输入字符长度最大为8位并存于变量中
read -p "input" "variable" #具有echo打印功能的输入并存于变量中
格式化输出
echo:输出(默认输出到标准输出设备;默认输出完成后换行)
-n:取消自动换行
-e:支持转义字符和颜色设置
echo -n "string" #输出string且无自动换行
echo -e "\033["background_color";"font_colorr"m "content" \033["function"m"
#设置输出效果
字体颜色:黑:30;红:31;绿:32;黄:33;蓝:34;紫:35;天蓝:33;白:37;范围:30-37
背景颜色:黑:40;红:41;绿:42;黄:43;蓝:44;紫:45;天蓝:43;白:47;范围:40-47
显示效果:无:0 ;设置高度:1;下划线:4;闪烁:5;反显:7;消隐:8
Shell变量详解
私有变量:(保存在~/.bash_profile或~/.bashrc文件中)(shell变量名推荐大写)
全局变量:(保存在/etc/profile或/etc/bashrc)(shell下变量名和等号紧跟)
私有变量定义规范:"variable"="content"
全局变量定义规范:export "variable"="content"
unset:取消变量的定义(私有变量和全局变量重新登录用户变量回归,临时变量则永久取消)
unset "variable" #取消变量的定义
Shell数组详解
基本数组
概念:下标是从零开始的自然数的数组(数组长度无预设,用多少是多少)
定义:"array_name"=("node1" "node2" "node3")
赋值:"array_name"[index]="content"
访问:
访问数组某个元素:${"array_name"["index"]}
访问数组所有元素:${"array_name"[@]}
访问数组所有索引:${"!array_name"[@]}
统计数字元素个数:${"#array_name[@]"}
从下标开始的访问:${"array_name[@]:"index""}
从下标开始的访问:${"array_name[@]:"index":"num""}
关联数组
概念:下标是自定义的任意值的数组(数组长度无预设,用多少是多少)
定义:
(1)declare -A "array_name"
(2)"array_name"=(["index1"]="node1" ["index2"]="node1")
赋值:"array_name"[index]="content"
访问:
访问数组某个元素:${"array_name"["index"]}
访问数组所有元素:${"array_name"[@]}
访问数组所有索引:${"!array_name"[@]}
统计数字元素个数:${"#array_name[@]"}
Shell流程控制
判断语句
if 语句
if判断格式:
(1)单判断格式
if [ condition ] #严格按照此空格格式
then
conmand1
fi
(2)双判断格式
if [ condition ]
then
command1
else
command2
fi
(3)多判断格式
if [ condition ]
then
command1
elif
then
command2
else
command3
fi
#if判断示例(单判断情况)
read -p "i=" i
if [ $i -eq 0 ]
then
echo "=0"
fi
#if判断示例(双判断情况)
read -p "i=" i
if [ $i -lt 0 ]
then
echo ">0"
else
echo "<0"
fi
#if判断示例(多判断情况)
read -p "i=" i
if [ $i -eq 0 ]
then
echo "=0"
elif [ $i -lt 0 ]
then #elif也必须有then
echo ">0"
else
echo "<0"
fi
test:判断结果(0为是,1为否)
-d:判断目录是否存在
-f:判断文件是否存储
-e:判断文件或目录是否存在
-r:判断文件或目录是否存在且是否操作用户由对其有读权限
-w:判断文件或目录是否存在且是否操作用户由对其有写权限
-x:判断文件是否存在且是否操作用户由对文件有执行权限
-z:判断字符串是否为空
-n:判断字符串长度是大于零
test -d yingxin;echo $? #判断yingxin目录是否存在
test -f yingxin;echo $? #判断yingxin文件是否存在
test -e yingxin;echo $? #判断yingxin文件或目录是否存在
test -r yingxin;echo $? #判断yingxin文件或目录是否存在且是否操作用户有对其读权限
test -w yingxin;echo $? #判断yingxin文件或目录是否存在且是否操作用户有对其写权限
test -x yingxin;echo $? #判断yingxin文件或目录是否存在且是否操作用户有对其执行权限
test -z "yingx";echo $? #判断"yingx"字符串是否为空
test -z "yingx";echo $? #判断"yingx"字符串长度是否大于零
| 运算类型 | 大于 | 小于 | 等于 | 大于等于 | 小于等于 |
|---|---|---|---|---|---|
| 数字运算 | -gt | -lt | -eq | -ge | -le |
| 字符运算 | > | < | == | >= | <= |
case 语句
case选择格式:
case $N in
"value1")
command1
;;
"value2")
command2
;;
*)
command3
;;
esac
#case示例
read -p "NUM:" N
case $N in
1)
echo haha
;;
2)
echo hehe
;;
*)
echo bye
;;
esac
循环语句
for 循环
for循环格式:(for循环适用于循环次数确定的情况)
(1)取值循环式
for "cycle_variable" in "range" #取值范围:罗列的取值、命令结果、字符串
do
command1
command2
done
(2)条件判断式
for(("cycle_variable";"condition";"change_way"))
do
command1
command2
done
#for循环示例(风格一)
for i in 1 2 3 4 5 6 7 8 9 #打印1 2 3 4 6 7 8 9
do
if [ $i -eq 5 ]
then
continue #跳过本轮循环
else
echo "i = $i"
fi
sleep 1 #延迟一秒
done
#for循环示例(风格二)
for((i = 1;i < 9;i++)) #打印i、j的和
do
for((j = 1;j < 9;j++))
do
`expr(($i + $j))`
if [ $i -ge 3 ]
then
break 2 #跳出从内到外两轮循环
fi
done
done
while 循环
while循环格式:(while循环适用于循环此时不定的情况)
while [ condition ] #严格按照此空格格式
do
command1
command2
done
#while循环示例
read -p "i=" i #打印i到6的值
while [ i -le 6 ]
do
echo $i
i=$((i+1))
done
until 循环
until循环格式:
until [ condition ] #严格按照此空格格式
do #格式和while一摸一样
command1 #while条件为真时执行循环
command2 #until条件为假时执行循环
done
#until循环示例
read -p "i=" i #打印i到6的值
intil [ !(i -le 6) ]
do
echo $i
i=$((i+1))
done
Shell函数封装
函数格式:
(1)小括号式
"function_name"(){
contain
}
(2)关键字式
function "function_name"{
contain
}
#函数示例(风格一)
yingxin(){
echo "Hello Yingxin"
}
yingxin()
#函数示例(风格二)
function yingxin{
echo "Hello Yingxin"
}
yingxin()
Shell文件操作
sed
sed:数据行处理(默认处理内存中的数据)
选项:
-e :一条命令多个操作
-f :从文件读取命令参数
-n :不输出内存数据
-i :数据处理结果写入原文件
-i.bak:数据处理结果写入原文件,并备份修改之前的文件
-r :使用正则表达式
命令:
a :在匹配后追加(另开一行)
i :在匹配前添加(另开一行)
p :打印匹配结果
d :删除匹配内容
s :替换匹配内容
c :更改匹配内容
y :转换匹配内容
标志:
"num" :操作第num个匹配项
g :替换全部匹配内容
p :打印原始内容
w :操作结果写入另一个文件
#sed命令参数示例
增加数据:
追加
sed 'a\yingxin' data.txt #data.txt文件中每一行后追加一行yingxin
sed '3a\yingxin' data.txt #data.txt文件中第三行后追加一行yingxin
sed '2,4a\yingxin' data.txt #data.txt文件中第二到四行后追加一行yingxin
sed '/3 the/a\yingxin' data.txt #data.txt中匹配3 the行后追加一行yingxin
插入
sed 'i\yingxin' data.txt #data.txt文件中每一行后插入一行yingxin
sed '3i\yingxin' data.txt #data.txt文件中第三行后插入一行yingxin
sed '2,4i\yingxin' data.txt #data.txt文件中第二到四行后插入一行yingxin
sed '/3 the/i\yingxin' data.txt #data.txt中匹配3 the行后插入一行yingxin
删除数据:
sed 'd' data.txt #删除data.txt文件中所有行
sed '3d' data.txt #删除data.txt文件中第三行
sed '2,4d' data.txt #删除data.txt文件中第二到四行
sed '/3 the/d' data.txt #删除data.txt文件中匹配3 the的行
修改数据
替换
sed 's\dog\cat\' data.txt #替换data.txt文件中所有行的dog为cat
sed '3s\dog\cat\' data.txt #替换data.txt文件中第三行的dog为cat
sed '2,4s\dog\cat\' data.txt #替换data.txt文件中第二到四行dog为cat
sed '/3 the/s\dog\cat\' data.txt#替换data.txt文件中匹配3 the行中dog为cat
修改
sed 'c\yingxin' data.txt #修改data.txt文件中所有行为yingxin
sed '3c\yingxin' data.txt #修改data.txt文件中第三行为yingxin
sed '2,4c\yingxin' data.txt #修改data.txt文件中第二到四行为yingxin
sed '/3 the/c\yingxin' data.txt #修改data.txt文件中匹配3 the行为yingxin
转换
sed 'y\ab\AB\' data.txt #转换data.txt文件中所有行的a、b为A、B
sed '3y\ab\AB\' data.txt #转换data.txt文件中第三行的a、b为A、B
sed '2,4y\ab\AB\' data.txt #转换data.txt文件中第二到四行a、b为A、B
sed '/3 the/y\ab\AB\' data.txt #转换data.txt文件中匹配3 the行a、b为A、B
查看
sed 'p' data.txt #打印data.txt文件中所有行
sed '3p' data.txt #打印data.txt文件中第三行
sed '2,4p' data.txt #打印data.txt文件中第二到四行
sed '/3 the/p' data.txt #打印data.txt文件中匹配3 the的行
#sed选项参数示例
sed -e 's\dog\cat\;s\brown\cat\' data.txt. #替换dog为cat和brown为green
sed -n 's\dog\cat\' data.txt. #替换dog为cat(不输出内存结果)
sed -f 'file.txt' data.txt #从文件file.txt读取操作命令
sed -i 's\dog\cat\' data.txt #替换dog为cat(结果覆盖原文件)
sed -i.bak 's\brown\green\' data.txt #替换并使用data.txt.bak备份原文件
sed -r '/^(3 the)/p' data.txt #打印data.txt文件中匹配3 the的行
#sed标志参数示例
sed 's\dog\cat\2' data.txt #替换data.txt文件中第二个dog为cat
sed 's\dog\cat\g' data.txt #替换data.txt文件中所有的dog为cat
sed 's\dog\cat\p' data.txt. #替换data.txt文件中dog为cat并打印
sed 's\dgo\cat\w file.txt' data.txt #替换并把结果写入file.txt文件中
awk
awk:文本格式化
选项:
-F:指定文件中列第分隔符
行处理变量:
NR==n:第n行
列处理变量:
$0 :全部列
$n :第n列
$NF:最后列
动作:
print:打印数据
awk -F: 'NR==1,NR==3{print "user:"$1,"right:"$2}' /etc/passwd
#输出/etc/passwd文件下的第一行和第三行的第一列和第二列
#在文件内部指定以:分隔列,结果按照"user"和"right"自定义格式展示
grep
grep:搜索匹配
-i:忽略字符的大小写
-o:仅显示匹配到的字符本身
-v:显示不能被匹配到的行
-E:支持扩展正则表达式
-q:静默模式(不输出任何信息)
grep -i dog data.txt. #在data.txt文件中查找dog(不区分大小写)
grep -o dog data.txt. #在data.txt文件中查找dog(只显示匹配项)
grep -v dog data.txt. #在data.txt文件中查找dog(显示未匹配项)
grep -E dog data.txt. #在data.txt文件中查找dog(支持扩展正则)
grep -q dog data.txt. #在data.txt文件中查找dog(不输出匹配结果)

浙公网安备 33010602011771号