提示:本人才疏学浅,此例子仅供参考,如有不对还请告知
目录
前言
现阶阶段所学,如有错误还请指正
Shell概述
shell是什么?
在Linux内核与用户之间的解释器程序
通常指 /bin/bash
负责向内核翻译及传达用户/程序指令
相当于操作系统的“外壳”
bash优点:tab键、历史命令、快捷键、别名、重定向、管道
使用步骤
1.交互式 —— 命令行
人工干预、智能化程度高
逐条解释执行、效率低
2.非交互式 —— 脚本
需要提前设计、智能化难度大
批量执行、效率高
方便在后台静悄悄地运行
什么是shell脚本
提前写好可执行的语句,能够完成特定任务的文件 按顺序、批量化处理
shell脚本的编写规范
1.声明解释器 #!/bin/bash
2.编写注释 #编写脚本功能、作者信息、变量作用等内容
3.执行指令 ls cd pwd .....
所有需要脚本执行的任务都可以逐行写在这里
脚本的执行方式:
1.添加x权限,使用绝对或者相对路径执行
chmod u+x test01.sh
/opt/test01.sh
用户(root)---bash---bash--- echo abc
2.使用解释器执行脚本,无需x权限,会开启新bash进程(子进程)
bash test01.sh
用户(root)---bash---bash--- echo abc
3.使用source命令执行脚本,无需x权限,不会开启新bash进程
source test01.sh
用户(root)---bash--- echo abc
变量
常量 固定不变(内容)
变量 使用固定的名称存放,可能会发生变化的内容(值),可以提高脚本 的灵活度、提高适应力
变量的种类
自定义变量,名称可以用数字、字母、下划线,不能以数字开头,不能使用特殊符号。
变量名称=变量的值
a=10 //创建变量(赋值)
echo $a //调用变量
unset a //取消变量或者
a= echo ${a}RMB //使用大括号可以避免混淆
a=10 然后 a=20 多次赋值之后,仅最后一次生效
env //可以显示所有环境变量
env | grep HOSTNAME //可以配合grep搜索
set //显示所有变量
abcd=8888
set | grep abcd //可以配合grep搜索
引号与反撇号
" " 双引号 界定范围
' ' 单引号 界定范围 屏蔽特殊符号功能 ,即便 $ 也视为普通字符
`` 反撇号 可以获取命令的执行结果,或者使用$( )可以实现相同效果
环境变量,由系统提前定义好,使用时直接调用
USER 当前用户名 HOME 当前用户的家目录 UID 当前用户的id号
SHELL 当前用户的解释器 HOSTNAME 主机名 PWD 当前位置
PATH 存储命令路径 PS1 一级提示符 PS2 二级提示符
比如:你输入cp filename1 \,回车,此时就出现第二级提示符。\是续行的意思。 默认的第二级提示符是“>;”
位置变量与预定义变量
$1 执行脚本时后面跟的第1个位置参数
$2 执行脚本时后面跟的第2个位置参数
$3 执行脚本时后面跟的第3个位置参数
$* 执行脚本时后面跟的所有位置参数
$# 执行脚本时后面跟的所有位置参数的个数
$$ 随机的进程号
$? 判断上一条指令是否成功,0是成功,非0是失败
export发布全局变量
局部变量 ,仅当前解释器进程中可以使用的变量
全局变量,解释器进程产生的子进程也可以使用的变量
a=10 //创建变量,默认是局部变量
export a //将已有的局部变量发布为全局变量
export b=20 //创建全局变量
export -n b //将全局变量恢复成局部变量
注意,测试时要在父进程创建变量,然后可以执行bash进入 子进程测试效果,如果要返回父进程要执行exit指令
shell中的运算
1,expr 可以运算并输出
expr 1 + 1 //加法运算,运算符号两边要加空格
expr 2 - 1
expr 2 '*' 2 //使用单引号屏蔽*的特殊功能即可实现乘法
expr 2 \* 2 //使用转义符号屏蔽*的特殊功能
expr 4 / 2
expr 10 % 3
a=10
b=20
expr $a + $b 还能进行变量的运算
expr $a + 100
expr $a + $a
2,使用$[ ] 或者 $(( ))
echo $[1+1]
echo $[2-1]
echo $[2*2]
echo $[2/2]
echo $[2%2]
echo $[a+a]
3,使用let命令,不显示结果,通常用于变量的创建于自增减
功能一:let a=1+1 //变量的创建,然后可以用echo $a查结果
功能二:对变量进行自增减
常规写法 主流写法 let a=a+1 let a++ 变量的自增减,将变量a的值加1 let a=a-1 let a-- 变量a减1 let a=a+2 let a+=2 变量a加2 let a=a-2 let a-=2 变量a减2 let a=a*10 let a*=10 变量a乘以10
4,使用bc计算器,可以进行小数运算
echo "1.1+1" | bc //非交互的方式使用bc工具
echo "scale=3;10/3" | bc //scale可以定义小数点后面的长度
条件测试
条件测试,可以为脚本赋予智能判断的效果
使用格式:
1, test 表达式
2, [ 表达式 ]
1.对字符串进行测试
== 判断两边是否相等 != 判断两边是否不等
test a == a test a == b [ a == a ] //使用常量判断,再用echo $?测试结果 [ a == b ] [ $a == $b ] //使用变量判断两个变量的值是否相等 [ $a != $b ] //使用变量判断两个变量的值是否不相等
-z 判断变量是否为空 ! -z 判断变量是否非空或-n
a=10 [ -z $a ] //判断变量a是否为空,如果为空则判断正确 [ ! -z $a ] //判断变量a中是否有值,有值则判断正确
2.逻辑符号,可以连接条件测试或者指令,来决定之后如何操作
&& 之前指令执行成功才会执行之后指令
|| 之前指令执行失败才会执行之后指令
3.数字测试
-eq 是否相等 -ne 是否不等 -gt 是否大于
-ge 是否大于等于 -lt 是否小于 -le 是否小于等于
[ 1 -eq 1 ] //判断1是否等于1 [ 3 -ge 5 ] //判断3是否大于等于5 a=10 b=20 [ $a -ne $b ] //判断变量a是否不等于变量b
4.文件(当前用户的测试)
-e 判断文件是否存在,不关心类型
-f 判断文件是否存在,必须是普通文件
-d 判断文件是否存在,必须是目录
-r 判断当前用户对文件是否有读权限,对root无效
-w 判断当前用户对文件是否有写权限,对root无效
-x 判断当前用户对文件是否有执行权限(目录是否可以进入)
if分支
1.单分支
if 条件测试;then //如果条件测试成功,那就执行下面的所有指令(指令可以有很多)
执行指令
fi
#!/bin/bash if [ $USER == root ];then echo "你是管理员~" fi
2.双分支
stty -echo 屏蔽回显
stty echo 恢复回显
reset 恢复回显
if 条件测试;then //如果条件测试成功,就执行下面的所有指令(指令可以有很多)
执行指令
else
执行指令 //如果上述条件测试失败,那就执行下面的指令
fi
#!/bin/bash if [ $USER == root ];then echo "你是管理员~" else echo "你不是管理员~" fi
3.多分支
if 条件测试;then //如果条件测试成功,就执行下面的所有指令(指令可以有很多)
执行指令
elif 条件测试;then //如果条件测试成功,就执行下面的指令
执行指令
elif 条件测试;then //如果条件测试成功,就执行下面的指令
执行指令
。。。。
else
执行指令 //如果上述条件测试失败,那就执行下面的指令
fi
for循环
有时我们需要某个或者某群任务反复在服务器中执行很多次,就可以使用循环命 令写成脚本,而无需手工一次次执行
for循环,有次数的循环
for 变量名 in 值1 值2 值3 。。。。 //此处变量名可以自定义,通常习惯用i,值的多少决定了下面do与done之间的任务执行多少次,每个值之间有空格,这里是有3个值,所以就循环执行指令3次
do
循环任务
done
#!/bin/bash for i in {1..100} //执行100次任务的简略写法,但不支持变量 do echo ${i}abc done
#!/bin/bash a=100 for i in $(seq $a) //使用seq支持变量 do echo ${i}abc done
while循环
while循环(while:连用匹配所有,代表死循环)
while 条件测试 //如果条件测试成功,就执行下面的指令,然后再回 来继续看条件测试能否成功,如果成功就继续执行指令,且可以实现无限 循环,一旦发现条件测试失败了,就立刻终止循环
do
执行指令
done
#!/bin/bash while [ 1 -eq 1 ] //故意写一个永远正确的条件测试可以实现无限循环或写“:” do echo abc sleep 0.2 //如果系统执行任务消耗cpu比较多,可以每次稍微休息0.2秒 done
控制循环
通常,在执行循环任务中途如果想退出可以用exit指令,但该指令不但会退出循环,连同脚本也会一并退出,此时可以使用break与continue指令更精细的控制循环。
exit 可以终止循环,但同时也终止脚本
break 可以终止循环,继续执行循环之后的任务
continue 终止当前循环,继续下一次循环
#!/bin/bash x=0 while : do read -p "请输入一个整数求和(0是结束并输出结果)" n [ -z $n ] && continue [ $n -eq 0 ] && echo "结果为$x" && exit let x+=n done
#!/bin/bash x=0 while : //while循环后面写冒号代表永远正确可以无效循环 do read -p "请输入一个整数求和(0是结束并输出结果)" n [ -z $n ] && continue //如果n是空值则重新进行循环任务 [ $n -eq 0 ] && break //如果n是0则退出循环执行循环后任务 let x+=n //不断的将n的值保存在x里 done echo "结果为$x"
case分支
功能类似if,编写时语句比if精简
case 调用变量的名称 in //如果调用的变量内容与下面某个模式一致,就执行模式下面的指令
模式1) //模式可以有很多
执行指令;; //指令需要用双分号结尾,如果一个模式有多个指令,那只需在该模式的最后一条指令后加双分号即可
模式2)
执行指令;;
.... *)
执行指令
esac
#!/bin/bash case $1 in T|t) //如果$1是t就执行touch任务(|或者) touch $2;; m) //如果$1是m就执行mkdir任务 mkdir $2;; r) //如果$1是r就执行rm任务 rm -rf $2;;(最后一条可以不写;) *) echo "请输入t或m或r" esac
echo命令
\r 回车符
\t 水平制表符,也就是Tab键stty -echo 屏蔽回显
stty echo 恢复回显
reset 恢复回显
字颜色:30—–37
echo -e "\033[30m 黑色字 \033[0m"
echo -e "\033[31m 红色字 \033[0m"
echo -e "\033[32m 绿色字 \033[0m"
echo -e "\033[33m 黄色字 \033[0m"
echo -e "\033[34m 蓝色字 \033[0m"
echo -e "\033[35m 紫色字 \033[0m"
echo -e "\033[36m 天蓝字 \033[0m"
echo -e "\033[37m 白色字 \033[0m"
字背景颜色范围:40—–47
echo -e "\033[40;37m 黑底白字 \033[0m"
echo -e "\033[41;37m 红底白字 \033[0m"
echo -e "\033[42;37m 绿底白字 \033[0m"
echo -e "\033[43;37m 黄底白字 \033[0m"
echo -e "\033[44;37m 蓝底白字 \033[0m"
echo -e "\033[45;37m 紫底白字 \033[0m"
echo -e "\033[46;37m 天蓝底白字 \033[0m"
echo -e "\033[47;30m 白底黑字 \033[0m"
最后面控制选项说明
\33[0m 关闭所有属性
\33[1m 设置高亮度
\33[4m 下划线
\33[5m 闪烁
\33[7m 反显
\33[8m 消隐
\33[30m — \33[37m 设置前景色
\33[40m — \33[47m 设置背景色
\33[nA 光标上移n行
\33[nB 光标下移n行
\33[nC 光标右移n行
\33[nD 光标左移n行
\33[y;xH设置光标位置
\33[2J 清屏
\33[K 清除从光标到行尾的内容
\33[s 保存光标位置
\33[u 恢复光标位置
\33[?25l 隐藏光标
\33[?25h 显示光标
函数
使用一个函数名称存储公共的语句块,实现精简脚本方便 后期调用的效果
a(){ //定义函数,函数名是a
echo abc //大括号里面是函数a的所有任务
echo xyz
}
a //调用函数
a //可以反复调用
字符串处理
linux中很多地方都需要这样或着那样的去使用、管理、操作字符,多掌握在linux中字符的控制方法直接决定能否写好脚本与更好的控制linux系统
1.字符串的截取
${变量名称:截取位置:截取的长度}
a=abcdef
echo ${a:0:1} //从变量的第1位截取,截取1位
echo ${a:2:2} //从变量的第3位截取,截取2位x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRST UVWXYZ0123456789 //创建一个变量x,里面有26个 小写字母26个大写字母和10个数字 #!/bin/bash x=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV WXYZ0123456789 //先定义变量x,里面有62个字符 for i in {1..8} //循环8次 do n=$[RANDOM%62] //得到0~61随机数 y=${x:n:1} //得到1个随机字符 a=$a$y //不断往变量a中追加 done echo $a //最后喊出结果
2.字符替换
${变${变量名/旧/新}量名/旧/新}3,字符串的删除
${变量名/旧/新} a=123456 echo ${a/3/2} //将3换成2 echo ${a/23/66} //将23换成66 echo ${a/23/6} a=123123 echo ${a/2/6} //默认情况下如果存在多个旧内容,只替换1个 echo ${a//2/6} //写2个斜杠可以替换所有旧内容 echo ${a/2/} //还可以替换为空,相当于删除
3.字符串的删除
${变量名称#被删除内容} 从左往右删除 掐头
a=abcdef echo ${a#abcde} //从左往右删除到e echo ${a#*e} //效果同上 a=abcabc echo ${a#*b} //从左往右删除到第1个b echo ${a##*b} //从左往右删除到最后1个b ${变量名称%被删除内容} 从右往左删除 去尾 a=abcde echo ${a%cde} //从右往左删除到c echo ${a%bcde} //从右往左删除到b echo ${a%b*} //效果同上 a=abcabc echo ${a%b*} //从右往左删除到第1个b echo ${a%%b*} //从右往左删除到最后1个b
4.定义变量初值(备用值)
${变量名:-初值}
#!/bin/bash read -p "请输入要创建的账户名:" u useradd $u read -p "请输入要配置的密码(默认123456):" p echo ${p:-123456} | passwd --stdin $u //如果没有输入密码直接回车的话密码 就是123456
read交互式输入
-p | 后面跟提示信息,即在输入前打印提示信息 |
-s | 静默输入,在输入字符时不再屏幕上显示,一般都是用于输入密码 |
-n | 后跟一个数字,指定输入的字符长度最大值 |
-r | 屏蔽\,如果没有该选项,则\作为一个转义字符,有的话 \就是个正常的字符了 |
-d | 后面跟一个标志符,其实只有其后的第一个字符有用,作为结束的标志 |
-t | 后面跟秒数,定义输入字符的等待时间n秒,超出n秒没有输入则自动退出 |
小技巧
read A B 111 222 echo $A echo $B read A B <<< "111 222" echo $A echo $B