一、Shell基本介绍
1.shell介绍
shell是一个命令解析器,主要用来接受用户的指令,进入驱动操作系统,或硬件
2.shell存在交互和非交互(创建100个用户)
- 交互:登录Linux、useradd、passwd(重复100次)
- 非交互:创建100个用户的操作写入至一个文件中,然后去执行。(全程不需要用户参与)
3.什么是shell脚本
- 将系统命令堆积在一起,顺序执行(简称:系统命令堆积)
- 特定的格式+特定的语法+系统的命令=文件(Shell脚本文件)
二、学习Shell预备知识
- 熟练使用vim编辑器
- 熟练使用系统基础命令(useradd、w、awk…)
- 熟悉使用Linux、grep、awk、sed
如何学好Shell?
- 基础命令+基础服务+练习题+(思路)
- 能看懂——>照着抄写——>能修改——>能编写——>能优化脚本
三、Shell书写方式
- Shell脚本名称必须要含有a.sh、b.sh。建议命名的方式最好在30个字以内解决check_memory.sh
- shell脚本的格式(建议在文件的首行添加#!/bin/bash、#!/user/bash)
- shell脚本建议添加一些个注释
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
所有注释可以自动生成,vimrc
vimrc的应用
四、Shell执行方式
添加 #!/bin/bash 的作用
- 不添加
- 默认./运行时,系统会调bash来运行该脚本。
- 缺点:如果写的时python脚本,直接调用bash来运行则会报错
- 添加
- ./运行脚本,默认会读取该文件第一行,来确定使用什么解释器运行。
- 直接调用解释器运行(无需在意文件首行指定的解释器)
- python check_shell.sh
- bash check_shell.sh
(日常使用最多,确定了是一个shell脚本,所以会选择直接使用bash解析器运行该脚本文件)
五、shell变量
- 什么是变量
- 变量其实是shell传递数据的一种方式。以一个固定的字符串去表示一个不固定的值。便于后续的复原,以及维护。
- 变量的命名规范
- 命名规范:大小写、下划线拼接变量名尽量字母开头。(变量最好有含义,如果没有,容易忘记这个变量是做什么的。)
- 变量如何定义:变量名=变量值,等号是赋值。
- 变量定义的几种方式
- 用户自定义变量
[root@web01 ~]# var="hello world" # 定义变量(等号两边没有空格)
[root@web01 ~]# echo $var #$变量名
hello world
#使⽤$变量名 ${变量名} 区别?
[root@web01 ~]# echo $var_log
[root@web01 ~]# echo ${var}_log
hello world_log
# 单引号和双引号的区别?
[root@web01 ~]# var2=Iphone
[root@web01 ~]# echo "$var2 is good"
Iphone is good #双引号会解析中的$符号
[root@web01 ~]# echo '$var2 is good'
$var2 is good #写什么就是什么
什么时候使用单引号和双引号
- 如果你输出的结果中包含变量名需要解析,则建议使⽤双引号。
- 如果你输出的结果仅仅只是⼀个字符串,但⾥⾯存在特殊字符,那么你可以选择使⽤单引号。
- 系统环境变量,保存的是和系统操作环境相关的,所有⽤户都可以调⽤。
#系统已经定义好了⼀些个变量,供我们使⽤。(所有的⽤户都可以使⽤)
[root@web01 ~]# cat check_env.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
echo "⽤户的家⽬录: $HOME"
echo "当前主机名是: $HOSTNAME"
echo "当前所在⽬录: $PWD"
echo "当前SSH连接: $SSH_CONNECTION"
- 位置参数变量,向脚本进⾏传递参数的,变量名不能⾃定义,变量作⽤也是固定的。
#在执行脚本时,可以对脚本进行参数的传递
[root@web01 ~]# cat variables.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
#!/bin/bash
echo "#当前shell脚本的⽂件名: $0"
echo "#第1个shell脚本位置参数:$1"
echo "#第2个shell脚本位置参数:$2"
echo "#第3个shell脚本位置参数:$3"
echo "#所有传递的位置参数是: $*"
echo "#所有传递的位置参数是: $@"
echo "#总共传递的参数个数是: $#"
echo "#当前程序运⾏的 PID 是: $$"
echo "#上⼀个命令执⾏的返回结果: $?"
[root@web01 ~]# sh variables.sh 11 22 33 44
#当前shell脚本的⽂件名: variables.sh
#第1个shell脚本位置参数:11
#第2个shell脚本位置参数:22
#第3个shell脚本位置参数:33
#所有传递的位置参数是: 11 22 33 44
#所有传递的位置参数是: 11 22 33 44
#总共传递的参数个数是: 4
#当前程序运⾏的 PID 是: 4159
#上⼀个命令执⾏的返回结果: 0
- 实例:通过位置变量创建 Linux 系统账户及密码,执⾏ var1.sh username password,控制 最多传递两个参数。【这个脚本仅root能执⾏,其他普通⽤户⽆法执⾏创建⽤户脚本。】
#1.如何知道他传递了多少个参数? $#
#2.判断他传递的参数是否⼤于我想设定的参数? if
# ⼤于:则报错提示
# 刚好:执⾏脚本
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
#1.判断他是什么⽤户身份在执⾏这个脚本
if [ $UID -ne 0 ];then
echo "$USER ⽤户你没有权限,请切到Root⽤户在执⾏"
exit
fi
#2.判断⽤户传递的的参数是否满⾜2个
if [ $# -ne 2 ];then
echo "Please Input Parameters [ username && exit
fi
#3.添加⽤户
useradd $1
#4.为⽤户设定密码
echo "$2" | passwd --stdin $1
- 变量赋值的方法式read(交互式传递变量)
[root@web01 ~]# cat read-1.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
#-s 不回显,就是不显示输⼊的内容
#-n 指定字符个数
#-t 超时时间
read -p "Login: " acc
read -s -t10 -n6 -p "Passwd: " pw
echo "login: $acc passwd: $pw"
read实例:
- 使⽤read模拟Linux登陆⻚⾯
#1.你先得知道linux的登陆⻚⾯是啥样⼦的?
[root@web01 ~]# cat read-2.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
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"
-
使⽤read编写⼀个修改系统主机名称脚本。【询问:是否修改,y修改、n退出脚本 不修改】
脚本⼤概内容应该如下: 1.先输出当前系统的主机名称: 2.询问需要修改为新的主机名称是什么? test01 3.确定要将原主机名称变更为test01 吗? [ y| n ] 4.判断⽤户输⼊的是y还是n y:使⽤hostnamectl 变更主机名称 n:直接退出此脚本
[root@web01 ~]# cat read-5.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
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
-
变量的替换
在不改变原来变量的值情况下,进⾏变量的替换
#和双##
[root@web01 ~]# url=www.sina.com.cn [root@web01 ~]# echo ${url} www.sina.com.cn
[root@web01 ~]# echo ${url#*.} sina.com.cn
[root@web01 ~]# echo ${url#*.*.} com.cn
[root@web01 ~]# echo ${url##*.} cn
# %和双%%
[root@web01 ~]# echo ${url%.*} www.sina.com
[root@web01 ~]# echo ${url%.*.*}
www.sina
[root@web01 ~]# echo ${url%%.*}
www
# / 与 //
[root@web01 ~]# echo ${url}
www.sina.com.cn
root@web01 ~]# echo ${url/sina/SINA}
www.SINA.com.cn
[root@web01 ~]# echo ${url//c/C}
www.sina.Com.Cn
- 实例:
变量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@web01 ~]# cat vars.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
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
-
变量的运算
root@web01 ~]# num1=10
[root@web01 ~]# num2=20
[root@web01 ~]#
[root@web01 ~]# expr $num1 + $num2
30
[root@web01 ~]#
[root@web01 ~]# echo $(( $num1 + $num2 )) 30
[root@web01 ~]# echo $[ $num1 + $num2 ] 30
[root@web01 ~]# echo $[ $num1 - $num2 ] -10
[root@web01 ~]# echo $[ $num1 * $num2 ] 200
[root@web01 ~]# echo $[ $num1 / $num2 ] 0
- 根据系统时间获取今年还剩下多少个星期,已经过了多少个星期。
1.获取今年是⼀年中的第多少天? date +%j
2.通过获取已过的天数,/7 就能得到已经过了多少周了。
3.通过(365 - 100)/7 还剩下多少周。
[root@web01 ~]# cat vars-2.sh
#!/bin/bash
#********************************************************************
#Author: xu
#QQ: 779115590
#Date: 2020-06-03
#FileName: read.sh
#Description: The test script
#********************************************************************
echo "今年已经过了 $(date +%j) days"
echo "记你已经过了 $(( $(date +%j) /7 ))weeks"
echo "距离新年还剩多少周 $(( ( 365 - $(date +%j) ) /7 )) weeks"