shell脚本01(基本介绍)
1. shell基本介绍
#1.shell介绍
shell是一个命令解释器,主要用来接收用户的指令,进入驱动操作系统,或硬件
#2.shell存在交互和非交互 ( 创建100个用户 )
交互:登陆Linux、useradd、passwd ( 重复100次 )
非交互: 创建100个用户的操作写入至一个文件中,然后去执行。( 全程不需要用户参与 )
#3.什么是shell脚本
1) 将系统命令堆积在一起,顺序执行(简称: 系统命令堆积)
2) 特定的格式 + 特定的语法 + 系统的命令 = 文件 ( Shell脚本文件)。
#!/usr/bin/bash #特定的格式
for i in {1..100} #特定的语法
do
useradd oldboy{1..10} #系统的命令
done
2.shell的书写方式
-
1.Shell脚本名称必须要有含义 a.sh、b.sh、建议命名的方式最好在30个字节以内解决。
check_memory.sh
-
2.shell脚本的格式 (建议在文件的首行添加 #!/bin/bash、#!/usr/bin/bash )
-
3.shell脚本建议添加一些个注释
#!/usr/bin/bash #申明系统在执行时使用bash解释器翻译该文件的内容 # Author: tony、123456789@qq.com # Create Time 2021/05/03 # Script Description: 这个脚本是用来检查系统内存使用情况。 # 所有的注释可以自动生成,可以研究一下vimrc
3.shell执行方式
添加 #!/bin/bash
的作用。
- 1.不添加
- 默认 ./运行时,系统会调bash来运行该脚本。
- 缺点:如果我写的是python脚本,直接调用bash来运行则会报错。
- 2.添加
- ./运行脚本,默认会读取该文件第一行,来确定使用什么解释器运行。
- 3.直接调用解释器运行 ( 无需在意文件首行指定的解释器 )
- python check_shell.sh
- bash check_shell.sh #日常使用最多( 我确定他是一个shell脚本,所以我会选择直接使用bash解释器翻译该脚本文件 )
4.shell变量
-
1.什么是变量
-
变量其实是Shell传递数据的一种方式。以一个固定的字符串去表示一个不固定的值。便于后续的复用,以及维护。
-
2.变量的命名规范 ( 熟悉 )
-
变量命令规范:大小写、下划线拼接变量名、尽量字母开头。( 变量最好有含义,如果没有,容易忘记这个变量是做什么的。 )
-
变量如何定义: 变量名=变量值,等号是赋值。 a=123 a变量 123值
-
变量定义参考:
ip=10.0.0.1 #小写,会容易与系统的命令冲突
ip1=10.0.0.1 #小写+数字
Hostname_Ip=10.0.0.1 #驼峰式命名 大写开头小写结束_大写开头_小写结束
Hostname_IP=10.0.0.1 #开头大写,_后面全大写
-
”变量名称“ 首字母大写的原因是为了避免与系统的命令产生冲突。
3.变量定义的几种方式 ( 使用61服务器 )
-
1.用户自定义变量,自己随意定义变量。
-
[root@web01 ~]# var="hello world" #定义变量 ( 等号两边没有空格 ) [root@web01 ~]# echo $var #$变量名 ${变量名} hello world #使用$变量名 ${变量名} 区别? [root@web01 ~]# echo $var_log [root@web01 ~]# echo ${var}_loghello world_log # 单引号和双引号的区别? [root@web01 ~]# var2=Iphone [root@web01 ~]# echo "$var2 is good" #双引号会解析中的$符号Iphone is good [root@web01 ~]# echo '$var2 is good' #写什么就是什么$var2 is good #什么时候使用 单引号和双引号: 如果你输出的结果中包含变量名需要解析,则建议使用双引号。 如果你输出的结果仅仅只是一个字符串,但里面存在特殊字符,那么你可以选择使用单引号。
-
2.系统环境变量,保存的是和系统操作环境相关的,所有用户都可以调用。
-
#系统已经定义好了一些个变量,供我们使用。(所有的用户都可以使用)
[root@oldboy ~]# cat check_env.sh
#!/bin/bash
echo "用户的家目录:$HOME"
echo "当前用户的主机名:$HOSTNAME"
echo "当前所在目录:$PWD"
echo "当前ssh连接:$SSH_CONNECTION"
[root@oldboy ~]# cat get_system_info.sh
#!/bin/bash
if [ $UID -ne 0 ]
then
echo "$USER没有权限执行该脚本!!"
exit
fi
echo "系统状态指标获取完毕!!!"
3.位置参数变量,向脚本进行传递参数的,变量名不能自定义,变量作用也是固定的。
[root@oldboy ~]# cat variables.sh
#!/bin/bash
echo "#当前shell脚本的文件名:$0"
echo "#第一个shell脚本位置参数:$1"
echo "#第二个shell脚本位置参数:$2"
echo "#第三个shell脚本位置参数:$3"
echo "#所有传递的位置参数是:$*"
echo "#所有传递的位置参数是:$@"
echo "#总共传递的参数个数是:$#"
echo "#当前程序运行的pid是:$$"
echo "#上一个命令执行的返回结果:$?"
需求1:通过位置变量创建 Linux 系统账户及密码,执行 var1.sh username password
[root@oldboy ~]# cat create_user_1.sh
#!/bin/bash
#1.添加用户
useradd $1
#2.为用户设定密码
echo "$2" | passwd --stdin $1
需求2:通过位置变量创建 Linux 系统账户及密码,执行 var1.sh username password,控制最多传递两个参数。【这个脚本仅root能执行,其他普通用户无法执行创建用户脚本。】
[root@oldboy ~]# cat create_user_2.sh
#!/bin/bash
#判断他是什么用户身份在执行这个脚本
if [ $UID -ne 0 ]
then
echo "$USER 用户没有权限执行,请切到root用户在执行"
exit
fi
#判断用户传递的参数是否满足2个
if [ $# -ne 2 ]
then
echo "please input parameters [ username && password ]"
exit
fi
# 添加用户
useradd $1
#为用户创建密码
echo "$2" | passwd --stdin $1
4.变量赋值的方式read (交互式传递变量)
[root@oldboy ~]# cat read-1.sh
#!/bin/bash
read -p "Login: " acc
read -p "passwd: " pw
echo "login:$acc passwd:$pw"
#################################################################################
[root@oldboy ~]# cat read-1.1.sh
#!/bin/bash
#-s 不回显,就是不显示输入的内容
#-n 指定字符个数
#-t 超时时间
read -p "Login:" acc
read -s -t10 -n6 -p "passwd:" pw
echo "login:$acc passwd:$pw"
需求1:使用read模拟Linux登陆页面
[root@oldboy ~]# cat read-2.sh
#!/bin/bash
hostnamectl | awk -F ':' '/System/ {print $2}'
echo "Kernel $(uname -r) an $(uname -m)"
echo ""
read -p "$(hostname) login:" acc
read -s -p "Passwd:" pw
echo ""
echo "Login:$acc passwd: $pw"
需求2:使用 read编写一个备份脚本,需要用户传递2个参数,源和目标。
[root@oldboy ~]# cat read-3.sh
#!/bin/bash
read -p "你要备份的文件或目录路径:" src
read -p "你要备份到那个目录下存储:" dest
read -p "你确定要将 $src 备份到 $dest 吗?[ y | n ]" action
#判断用户输入的是y还是n 则进行备份,n则提示没有备份
if [ $action == "y" ]
echo "---------------------备份开始----------------------"
cp -rp $src $dest
sleep 3
echo "----------------------备份结束---------------------"
else
echo "----------------------备份退出---------------------"
exit
fi
需求3:使用 read编写一个探测主机存活脚本,需要用户传递测试的IP地址。 [并没有说使用传参,而是让其使用read的方式]
[root@oldboy ~]# cat read-4.sh
#!/bin/bash
read -p "请输入你要探测的主机IP地址:" IP
ping -c2 $IP &>/dev/null
if [ $? -eq 0 ]
echo "$IP 存活"
else
echo "$IP 不存活"
fi
需求4:使用read编写一个修改系统主机名称脚本。【询问:是否修改,y修改、n退出脚本不修改】
[root@oldlai ~]# cat read-5.sh
#!/bin/bash
old_host=$(hostname)
echo "当前系统的主机名称是:${old_host} "
read -p "你想修改的主机名称是:" new_host
read -p "你确定要将 ${old_host} 变更为 ${new_host} 名称吗?[ y | n ] " action
if [ $action == "y" ]
then
echo "---------------------------正在修改主机名称---------------------------"
hostnamectl set-hostname ${new_host}
sleep 1
echo ""
echo "----------------------------主机名称修改完毕---------------------------"
fi
5.变量的替换
#和双##
[root@oldboy ~]# url=www.sina.com.cn
[root@oldboy ~]# url=www.sina.com.cn
[root@oldboy ~]# echo "${url}"
www.sina.com.cn
[root@oldboy ~]# echo ${url#*.}
sina.com.cn
[root@oldboy ~]# echo ${url#*.*.}
com.cn
[root@oldboy ~]# echo ${url##*.}
cn
# %和双%%
[root@oldboy ~]# echo ${url%.*}
www.sina.com
[root@oldboy ~]# echo ${url%.*.*}
www.sina
[root@oldboy ~]# echo ${url%%.*}
www
# / 与 //
[root@oldboy ~]# echo ${url}
www.sina.com.cn
[root@oldboy ~]# echo ${url/sina/SINA}
www.SINA.com.cn
[root@oldboy ~]# echo ${url//c/C}
www.sina.Com.Cn
1.希望把$PATH中的/bin全部都替换为 /BIN
[root@web01 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@web01 ~]# echo ${PATH//bin/BIN}
/usr/local/sBIN:/usr/local/BIN:/usr/sBIN:/usr/BIN:/root/BIN
需求2:变量string="Bigdata process is Hadoop, Hadoop is open source project",执行脚本后,打印输出string变量,并给出用户以下选项:
1)、打印string长度
2)、删除字符串中所有的Hadoop
3)、替换第一个Hadoop为Linux
4)、替换全部Hadoop为Linux
用户输入数字1|2|3|4,可以执行对应项的功能,输入q|Q则退出交互模式
[root@oldboy ~]# cat vars.sh
string="Bigdata process is Hadoop, Hadoop is open source project"
echo "$string"
cat <<EOF
1)、打印string长度
2)、删除字符串中所有的Hadoop
3)、替换第一个Hadoop为Linux
4)、替换全部Hadoop为Linux
EOF
read -p "请输入你想执行的操作 [ 1 | 2 | 3 | 4 | q ]" action
if [ $action -eq 1 ]
then
echo "string变量的长度:${#string}"
fi
if [ $action -eq 2 ]
then
echo "${string//Hadoop/}"
fi
if [ $action -eq 3 ]
then
echo "${string/Hadoop/Linux}"
fi
if [ $action -eq 4 ]
then
echo "${string//Hadoop/Linux}"
fi
2.查看内存/当前使用状态,如果使用率超过80%则报警发邮件
[root@oldboy ~]# cat check_memory.sh
#!/bin/bash
Mem_Use=$(free -m | awk '/^Mem/ {print $3/$2*100}')
if [ ${Mem_Use%.*} -ge 80 ]
then
echo "内存已经超过所设定得阈值,请尽快处理,当前已使用内存为 ${Mem_Use}"
else
echo "内存当前状态良好,当前已使用内存为 ${Mem_Use%.*}%"
fi
[root@oldboy ~]# bash check_memory.sh
内存当前状态良好,当前已使用内存为 15%
6变量的运算
- 1.什么是变量运算? 小学学习的 + - x /
- 2.为什么要学习呢?
- 3.shell使用什么方式来实现变量的运算呢?
- 1.expr
- 2.$(())
- 3.$[]
- 4.bc、awk 小数运算
- % 余数如果为0,说明两者之间整除
[root@oldboy ~]# num1=10
[root@oldboy ~]# num2=20
[root@oldboy ~]# expr $num1 + $num2
30
[root@oldboy ~]# echo $(( $num1 + $num2 ))
30
[root@oldboy ~]# echo $[ $num1 + $num2 ]
30
[root@oldboy ~]# echo $[ $num1 - $num2 ]
-10
[root@oldboy ~]# echo $[ $num1 * $num2 ]
200
[root@oldboy ~]# echo $[ $num1 / $num2 ]
0
1.根据系统的时间,打印今年和明年时间。
[root@oldboy ~]# echo "This is $(date +%Y) year"
This is 2021 year
[root@oldboy ~]# echo "This is $(( $(date +%Y) +1 ))"
This is 2022
2.根据系统时间获取今年还剩下多少个星期,已经过了多少个星期。
[root@oldboy ~]# cat vars-2.sh
#!/bin/bash
echo "今年已经过了 $(date +%j) days"
echo "今年已经过去了 $(( $(date +%j) / 7 )) weeks"
echo "距离新年孩剩下多少周 $(( ( 365 - $(date +%j) ) / 7 )) weeks"
3.完成一个 "简单" 的计算机功能,通过read方式传入2个值【而不是传参的方式】,进行 加、减、乘、除:
[root@oldboy ~]# cat vars-3.sh
#!/bin/bash
read -p "请输入你要计算得第一个数字:" num1
read -p "请输入你要计算得第二个数字:" num2
echo "$num1 + $num2 = $(( $num1 + $num2))"
echo "$num1 - $num2 = $(( $num1 - $num2))"
echo "$num1 * $num2 = $(( $num1 * $num2))"
echo "$num1 / $num2 = $(( $num1 / $num2))"