Shell 编程
1.什么是shell
shell是一个命令解释器, 将人类输入高级语言, 通过 Shell程序 转换为 二进制、
shell分为两种使用方式:
交互: 登录 执行命令 退出
非交互: 执行某个文件, 文件中都是一推命令, 整个文件从上往下依次执行
2.什么是shell 脚本
(1) 将系统命令堆积在一起,顺序执行(简称: 系统命令堆积
(2) 特定的格式 + 特定的语法 + 系统的命令 = 文件
3.shell 脚本能做什么
标准: 1.安装方式一致 2.安装路径一致 3.目录结构一致 4.日志格式一致 5.脚本路径一致 6.能将平时操作脚本化,流程化,自动化 ITIL ppt 人 流程 技术/工具 备份 监控 自动化上线 约束标准
4.shell 脚本书写规范
执行方式分为两种:
1.加执行权限 ./script_filename.sh
2.通过bash直接翻译 bash script_filename.sh
问题: #!/usr/bin/bash 加与不加区别在哪? 1.如果你明确清楚这是一个什么类型的脚本,直接调用对应的解释器执行,没有影响? 2.如果你不清楚是什么类型的脚本, 直接使用./执行,那么会读取该脚本的第一行 如果第一行是#!/usr/bin/bash 或者 没有写该行,那么都将使用默认的bash翻译 问题: 如果我是一个python脚本,没有写开头,那么执行一定会报错 因为默认查找的是bash解释器,而我的文件需要用python解释器来翻译. 添加命令解释器的几种方式: #!/usr/bin/bash #!/usr/bin/sh #!/usr/bin/env bash #!/usr/bin/env python
5.什么是变量
变量是shell中传递数据的一种方法。
简单理解: 就是用一个固定的字符串去表示不固定的值,便于后续引用。
6.定义变量的规范
1.大写开头,后面小写或数字都ok
2.变量具体一定的含义
3.注意 变量的写法 仅支持 a=1 不支持 a = 1
7. 自定义变量
var="hello world"
echo $var
**echo ${var}_log**
8.$* 和 $@ 的区别?
可以看到不加引号时,二者都是返回传入的参数,但加了引号后,此时\(*把参数作为一个字符串整体(单字符串)返回,\)@把每个参数作为一个字符串返回
9.需求1:通过位置传参方式, 创建 Linux 系统账户及密码,执行 var1.sh username password
[root@ansible /scripts/User]# cat var01.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var01.sh #URL: https://www.baozexu.com #Description: #***************************************** useradd $1 echo "$2"|passwd --stdin $1 [root@ansible /scripts/User]sh var01.sh old3 1234
10.需求2:通过位置传参方式, Linux 系统账户及密码,执行 var1.sh username password,控制最多传递两个参数。
[root@ansible /scripts/User]# cat var02.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var02.sh #URL: https://www.baozexu.com #Description: #***************************************** if [ $# -ne 2 ];then echo "USAGE: $0 请传递两个参数[username|password]" exit fi useradd $1 echo $2|passwd --stdin $1 [root@ansible /scripts/User]# sh var02.sh oldxu4 12345
read
需求1:使用read模拟Linux登陆页面。
[root@ansible /scripts/User]# cat var03.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var03.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "$(hostnamectl |awk -F ":" '/Operating System:/ {print $2}')" echo "Kernel $(uname -r) on an $(uname -m)" read -p "$(hostname) Login: " acc read -s -t50 -p "Password: " pw echo "" echo "你输入的用户名: $acc 你输入的密码是: $pw" [root@ansible /scripts/User]# sh var03.sh
需求2:使用 read编写一个备份脚本,需要用户传递2个参数,源和目标。
[root@ansible /scripts/User]# cat var04.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var04.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "--------按照提示进行操作-------------" read -p "请输入你要备份的源文件或者源目录: " Source read -p "请输入你要备份的目录位置是哪里: " Dest echo -e "\t你要输入的源文件为 $Source" echo -e "\t你要输入的目标文件为 $Dest" read -p "你确定要拷贝吗?[y|n]" action if [ $action == y ];then cp -rp $Source $Dest fi [root@ansible /scripts/User]# sh var04.sh
需求3:使用read编写一个探测主机存活脚本,需要用户传递测试的IP地址。
1.提示用户输入IP地址
2.对用户输入的IP地址进行探测是否存活
3.判断探测结果是否成功
成功则输出成功的结果
失败则输出失败的结果
[root@ansible /scripts/User]# cat var05.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var05.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "-------按照提示进行操作----------" read -p "请输入你的ip地址" ip ping -W1 -c1 $ip &>/dev/null if [ $? -eq 0 ];then echo "$ip is ok" else echo "$ip is error" fi [root@ansible /scripts/User]# sh var05.sh -------按照提示进行操作---------- 请输入你的ip地址10.0.0.51 10.0.0.51 is error
需求4:使用read编写一个修改系统主机名称脚本。
1.打印当前的主机名称
2.提示用户输入新的主机名称
3.询问用户是否修改?
4.确定修改,执行修改命令
5.不确定修改,退出脚本
[root@ansible /scripts/User]# cat var06.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var06.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "---------按照提示进行操作----------" echo "当前的主机名为$(hostname)" read -p "将主机名要修改为 $new_host" new_host read -p "是否修改主机名[y|n]" action if [ $action == y ];then hostnamectl set-hostname $new_host echo "你的主机名已经修改为 $new_host" fi [root@ansible /scripts/User]# sh var06.sh ---------按照提示进行操作---------- 当前的主机名为ansbile 将主机名要修改为 ansible 是否修改主机名[y|n]y 你的主机名已经修改为 ansible
变量替换
[root@manager ~]# url=www.sina.com.cn [root@manager ~]# echo $url www.sina.com.cn [root@manager ~]# echo $url | awk -F '.' '{print $2,$3,$4}' sina com cn [root@manager ~]# echo ${url} www.sina.com.cn ------------# [root@manager ~]# echo ${url#*.} #从头开始匹配,最短匹配 sina.com.cn [root@manager ~]# echo ${url##*.} #从头开始匹配,最长匹配 cn ------------% [root@manager ~]# echo ${url%.*} www.sina.com [root@manager ~]# echo ${url%%.*} www -------------/ [root@manager ~]# echo ${url/c/C} www.sina.Com.cn [root@manager ~]# echo ${url//c/C} www.sina.Com.Cn
需求1:如何替换 $PATH 中的/bin/替换为/BIN/
[root@ansible /scripts/User]# echo "${PATH//bin/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,可以执行对应项的功能
[root@ansible /scripts/User]# cat var07.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var07.sh #URL: https://www.baozexu.com #Description: #***************************************** string="Bigdata process is Hadoop, Hadoop is open source project" echo "(1)、打印string长度" echo "(2)、删除字符串中所有的Hadoop" echo "(3)、替换第一个Hadoop为Linux" echo "(4)、替换全部Hadoop为Linux" echo "用户输入数字1|2|3|4,可以执行对应项的功能" read -p "请输入数字" number if [ $number -eq 1 ];then echo "它的长度为 ${#string}" fi if [ $number -eq 2 ];then echo "${string//Hadoop/}" fi if [ $number -eq 3 ];then echo "${string/Hadoop/Linux}" fi if [ $number -eq 4 ];then echo "${string//Hadoop/Linux}" fi sh var07.sh (1)、打印string长度 (2)、删除字符串中所有的Hadoop (3)、替换第一个Hadoop为Linux (4)、替换全部Hadoop为Linux 用户输入数字1|2|3|4,可以执行对应项的功能
需求3:查看内存/当前使用状态,如果使用率超过80%则报警发邮件,思路如下:
1.当前内存使用百分比是多少
2.进行判断比对
如果大于80% 则触发邮件
否则,over
已使用的内存 / 总内存 * 100 = 使用的百分比
[root@ansible /scripts/User]# vim var08.sh 1 #!/bin/bash 2 #***************************************** 3 #name: baozexu 4 #QQ: 2897374243 5 #Date: 2019-10-28 6 #FileName: var08.sh 7 #URL: https://www.baozexu.com 8 #Description: 9 #***************************************** 10 mem_free=$(free -m|awk 'NR==2{print $3/$2*100}') 11 echo "当前内存的百分比为${mem_free}" 12 if [ ${mem_free%.*} -ge 5 ];then 13 echo "你的内存已超标 目前的状态是$mem_free" 14 fi [root@ansible /scripts/User]# sh var08.sh 当前内存的百分比为12.963 你的内存已超标 目前的状态是12.963
需求4:根据系统时间,打印今年和明年时间。
[root@ansible /scripts/User]# cat var09.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var09.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "今年的时间为$(date +%Y)" echo "明年的时间为$(($(date +%Y)+1))" [root@ansible /scripts/User]# sh var09.sh 今年的时间为2019 明年的时间为2020
需求5:根据系统时间获取今年还剩下多少星期,已经过了多少星期。思路如下:
date +%j 已经过了多少天
一年有365天 已经过了 301 = 还剩下 365-301 = 64 / 7 = 还剩下多少周
已经过了 301 天 / 7 = 已经过了多少周
[root@ansible /scripts/User]# cat var010.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var010.sh #URL: https://www.baozexu.com #Description: #***************************************** Date=$(date +%j) echo "已经过了 ${Date}天" echo "已经过了$(( ${Date}/7))周" echo "还剩下$[ (365-${Date})/7]周" [root@ansible /scripts/User]# sh var010.sh 已经过了 301天 已经过了43周 还剩下9周
需求3:完成一个计算器功能: 传入2个值,然后对传入的值进行 加 减 乘 除,思路如下:
1.使用read让用户传值: $1 $2
2.对传入的值进行运算:
3.输出对应的结果.
[root@ansible /scripts/User]# cat var011.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var011.sh #URL: https://www.baozexu.com #Description: #***************************************** echo "欢迎使用计算机" read -p "请输入你的值 " number read -p "请输入你的值 " num echo "$number+$num=$((number+num))" echo "$number-$num=$((number-num))" echo "$number*$num=$((number*num))" echo "$number/$num=$((number/num))" [root@ansible /scripts/User]# sh var011.sh 欢迎使用计算机 请输入你的值 1 请输入你的值 2 1+2=3 1-2=-1 1*2=2 1/2=0
需求4:使用Shell脚本打印,系统版本、内核版本平台、虚拟平台、静态主机名、eth0网卡IP地址、lo网卡IP地址、当前主机的外网IP地址curl icanhazip.com
[root@ansible /scripts/User]# cat var012.sh #!/bin/bash #***************************************** #name: baozexu #QQ: 2897374243 #Date: 2019-10-28 #FileName: var012.sh #URL: https://www.baozexu.com #Description: #***************************************** Centos=$(hostnamectl|awk -F ": " 'NR==7{print $2}') Kernel=$(hostnamectl|awk -F ": " 'NR==9{print $2}') Hostname=$(hostname) ip=$(ip a|grep lo|awk 'NR==3{print $2}') echo "系统版本为: ${Centos}" echo "内核为: ${Kernel}" echo "主机名为: ${Hostname}" echo "lo网卡地址为: ${ip}" [root@ansible /scripts/User]# sh var012.sh 系统版本为: CentOS Linux 7 (Core) 内核为: Linux 3.10.0-957.el7.x86_64 主机名为: ansible lo网卡地址为: 127.0.0.1/8