课程大纲:
基础变量 bash 执行方式 if判断 for循环 while循环 unitl循环 条件控制语句 exit continue break 函数 数组
1.为什么学习Shell
Shell能做什么?
1)安装操作系统 CentOS6.X CentOS7.X 手动方式安装 克隆方式
自动化安装 cobbler kickstart 底层都是shell脚本实现
2)优化 SSH 关闭Selinux 优化防火墙 放行 80 443 SSH端口 127.0.0.1 zabbix监控 10051 个人需求 加大文件描述符 时间同步
硬件时间 软件时间 YUM源...... 写入shell脚本
3)安装服务 Nginx Apache Tomcat PHP MySQL Redis Mongo docker.....
PHP5.4 PHP7.1 写入shell脚本 自动化安装不同版本的服务
4)代码上线 shell脚本自动化发布自动化回滚
5)zabbix监控 硬件 软件 进程 端口号 自定义监控 shell脚本+定时任务
6)日志分析日志统计 三剑客+定时任务+shell脚本 日志展示-->ELK
7)业务层面
8)辅助开发程序 python nohup python3.5 test.py & nohup.out 大量的日志
2.学习Shell用到的基础知识
1)vim编辑器
2)Linux常用命令 60个左右
3)三剑客 awk sed grep (find)
4)xshell Crt 连接工具
3.如何Shell编程
1)重点掌握前面的内容 变量 判断 bash 彻底理解
2)先看懂 读懂shell脚本
3)讲完 判断 前面学过的脚本进行完善
4)自己写简单的脚本 小的项目 生活中 随机点餐 大保健 会员办理 消费 服务 对应价格不同 结账 会员账号 密码 密码丢失
5)有基本适合自己的教材 跟老男孩学习Shell编程 或者完善的文档
6)不能拿来及用 搞懂 变成自己 吸收了后
学完Shell编程 解决企业中大部分的shell问题
4.编程语言
Shell Python Go ruby c c++ javascript perl...
编译型语言 只编译一次 后面直接运行代码即可
解释型语言 运行一次 解释一次
shell和python区别
shell处理系统底层的内容 程序运行 启动 系统运行 shell脚本
python php主要作用搭建web 自动化CMDB 处理底层的效率低
5.什么是Shell
笔试题: lINUX中默认的shell是: bash
两个工作方式:
交互式: 我们输入命令 bash执行命令 执行完 我们退出 bash结束
非交互式: 把命令写入到文件中 bash执行文件中的内容 执行到末尾 bash结束
通过xshell登录到系统中 当前的位置属于父shell 所有的文件 在执行的时候调用子shell执行 执行结束子shell退出
6.什么是Shell脚本
将命令写入到一个文本中 shell脚本 语法格式 if判断 for循环 while 函数 数组......
7.Shell脚本入门
书写Shell脚本的规范
1)脚本统一存放固定的目录 /server/scripts 统一化 自动化铺垫
2)脚本命令结尾以.sh结尾 LINUX中的后缀是给我们自己看的 区分文件用的
3)shell脚本的开头 写解释器 #!/bin/bash
4)脚本最好有注释 说明 #Author lzy log conut 20202020时间 QQ 110 ...
5)说明尽量用英文 最好用中文
6)成对的符号一次性书写完毕 循环语句
小结: shell用处 如何学习shell 用到的基础知识
8.第一个shell脚本
[root@shell scripts]# cat test.sh
#!/bin/bash
echo "Hello World!"
执行脚本的三种常用的方式
1.使用bash或者sh通过解释器执行脚本 在子shell中执行命令
[root@shell scripts]# sh test.sh
Hello World!
[root@shell scripts]# bash test.sh
Hello World!
2.使用路径方式 全路径执行方式 或者当前路径 必须给x权限 开机自动加载一个shell脚本 /etc/rc.local 在子shell中执行命令
[root@shell scripts]# chmod +x test.sh
[root@shell scripts]# /server/scripts/test.sh
Hello World!
[root@shell scripts]# ./test.sh
Hello World!
3.使用source或者.的方式 在父shell中执行命令
[root@shell scripts]# . test.sh
Hello World!
[root@shell scripts]# source test.sh
Hello World!
其他shell的执行方式
[root@shell scripts]# cat test.sh|bash
/server/scripts
[root@shell scripts]# echo ls
ls
[root@shell scripts]# echo ls|bash
test.sh
[root@shell scripts]# bash < test.sh
/server/scripts
9.shell的变量基础
什么是变量?
用一个固定的字符串表示不固定的值称为变量
x=1 y=x+1 y=2
变量的种类:
环境变量(全局变量) 针对全局生效 针对所有的shell生效
普通变量(局部变量) 针对当前某个shell生效
PS1 PATH LANG 全局变量
查看全局变量 env
按照生命周期区分
永久: 写入/etc/profile 每次使用xshell连接系统 都会自动加载/etc/profile
临时的: 使用export声明即可
加export: 对当前打开窗口的所有shell生效
不加export区别: 只对当前的shell生效
[root@shell ~]# age=18
[root@shell ~]# echo $age
18
[root@shell ~]# export name=oldboy
[root@shell ~]# echo $name
oldboy
[root@shell ~]# bash
[root@shell ~]# echo $name
oldboy
案例: rsync -avz hosts rsync_backup@10.0.0.41::backup
rsync的内置变量 export RSYNC_PASSWROD
和环境变量相关的文件
变量的执行加载顺序 不一定是生效顺序 变量谁最后定义的谁优先生效 重复赋值
1./etc/profile
2..bash_profile 家目录中隐藏文件
3..bashrc 家目录中的隐藏文件
4./etc/bashrc
10.定义环境变量
name=oldboy
变量名的定义方式: 要求字符串下划线数字的组合 下划线或者字符串开头 不能以数字开头 名称见名知其意 等号两端不允许有空格
变量名的书写方式:
NAME_AGE= 全大写 系统默认的变量都是大写
Name_Age 大驼峰语法
name_Age 小驼峰语法
name_age 全小写
变量值的定义
三种值:
字符串定义 必须是连续的字符串 值不允许有空格
[root@shell ~]# name=Iamlizhenya
[root@shell ~]# name='I am lizhenya'
[root@shell ~]# echo $name
I am lizhenya
[root@shell ~]# name="I am lizhenya"
[root@shell ~]# echo $name
I am lizhenya
双引号和单引号的区别 双引号解析变量 单引号所见即所得不能解析变量 不加引号可以解析变量
数字的定义
[root@shell ~]# age="12 23 432"
[root@shell ~]# echo $age
12 23 432
命令的定义 使用`` $()
[root@shell ~]# date +%F-%H-%M-%S
2021-10-18-15-39-36
[root@shell ~]# time=`date +%F-%H-%M-%S`
[root@shell ~]# echo $time
2021-10-18-15-40-03
[root@shell ~]# echo $time # 会变的举手打赌 鱼头泡王八
2021-10-18-15-40-03
[root@shell ~]# time=$(date +%F-%H-%M-%S)
[root@shell ~]# echo $time
2021-10-18-15-43-12
时间是固定 每次调用都相同
[root@shell ~]# cat 1.sh
#!bin/bash
time=`date +%F-%H-%M-%S`
echo $time
sleep 2
echo $time
[root@shell ~]# sh 1.sh
2021-10-18-15-44-45
2021-10-18-15-44-45
时间是不固定的 每次调用都不相同 都是当前的时间
[root@shell ~]# cat 1.sh
#!bin/bash
time='date +%F-%H-%M-%S'
echo `$time`
sleep 2
echo `$time`
变量可以定义变量
[root@shell ~]# ip=`ifconfig eth0|awk 'NR==2{print $2}'`
[root@shell ~]# echo $ip
10.0.0.7
[root@shell ~]# dir=$ip_$time
[root@shell ~]# echo $dir
2021-10-18-15-43-53
[root@shell ~]# dir=${ip}_${time}
[root@shell ~]# echo $dir
10.0.0.7_2021-10-18-15-43-53
[root@shell ~]# mkdir $dir
[root@shell ~]# ll
total 4
drwxr-xr-x 2 root root 6 Oct 18 15:50 10.0.0.7_2021-10-18-15-43-53
当shell脚本中出现2条以上相同的命令 写成变量
核心位置变量
$0 获取shell脚本的名称 执行如果带全路径 则$0带全路径 *****
$n n为数字 从1开始 $1为脚本的第一个参数 从$9往后 我们需要加${10} *****
$# 获取脚本传参的总个数 针对传入的个数进行判断 *****
$* 获取脚本传参的所有的参数 在循环体中不同 加上顺引号视为单个字符串 了解
$@ 获取脚本传参的所有的参数 在循环体中不同 加上双引号视为独立的参数 了解
$? 获取上一条命令的返回值 0为成功 非0失败 *****
$$ 获取脚本的PID进程号 **
$! 获取上一个在后台运行脚本的PID号 测试常用 **
$_ 获取脚本的最后一个参数或者是东东 类似esc . 了解
$0
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $0
[root@shell scripts]# sh test.sh
test.sh
[root@shell scripts]# /server/scripts/test.sh
/server/scripts/test.sh
$0的使用方法
[root@shell scripts]# grep \$0 /etc/init.d/network
$0 stop
$0 start
echo $"Usage: $0 {start|stop|status|restart|force-reload}"
[root@shell scripts]# grep '$0' /etc/init.d/network
$0 stop
$0 start
echo $"Usage: $0 {start|stop|status|restart|force-reload}"
在脚本给予用户提示 如何使用脚本
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $0
echo $"Usage: $0 {start|stop|status|restart|force-reload}"
basename 只获取脚本的名称 了解
[root@shell scripts]# basename /server/scripts/test.sh
test.sh
$n 脚本的参数
[root@shell scripts]# sh test.sh oldboy
oldboy
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $1
[root@shell scripts]# sh test.sh oldboy lidao yin
oldboy
序列传参
[root@shell scripts]# sh test.sh {a..z}
c
[root@shell scripts]# sh test.sh {A..Z}
C
[root@shell scripts]# sh test.sh {1..10}
3
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
[root@shell scripts]# sh test.sh {a..z}
a b c d e f g h i j k
$#
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
echo $#
[root@shell scripts]# sh test.sh 1 2 3
1 2 3
3
[root@shell scripts]# sh test.sh a b c
a b c
3
[root@shell scripts]# sh test.sh {a..z}
a b c d e f g h i j k
26
[root@shell scripts]# sh test.sh {1..10000}
1 2 3 4 5 6 7 8 9 10 11
10000
[root@shell scripts]# cat test.sh
#!/bin/bash
echo name=$1
echo age=$2
[root@shell scripts]# sh test.sh oldboy 18
name=oldboy
age=18
[root@shell scripts]# cat test.sh
#!/bin/bash
[ $# -ne 2 ] && echo "请输入两个参数" && exit
echo name=$1
echo age=$2
[root@shell scripts]# sh test.sh {1..10}
name=1
age=2
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8 9 10
[root@shell scripts]# sh test.sh {a..z}
name=a
age=b
a b c d e f g h i j k l m n o p q r s t u v w x y z
a b c d e f g h i j k l m n o p q r s t u v w x y z
测试$* $@在循环体中家双引号
[root@shell scripts]# set -- "I am" lizhenya teacher
[root@shell scripts]# echo $*
I am lizhenya teacher
[root@shell scripts]# echo $@
I am lizhenya teacher
[root@shell scripts]# echo "$@"
I am lizhenya teacher
[root@shell scripts]# echo "$*"
I am lizhenya teacher
[root@shell scripts]# for i in $*;do echo $i;done
I
am
lizhenya
teacher
[root@shell scripts]# for i in $@;do echo $i;done
I
am
lizhenya
teacher
[root@shell scripts]# for i in "$*";do echo $i;done
I am lizhenya teacher
[root@shell scripts]# for i in "$@";do echo $i;done
I am
lizhenya
teacher
$?
[root@shell scripts]# echo $?
0
[root@shell scripts]# llllllllllllll
bash: llllllllllllll: command not found
[root@shell scripts]# echo $?
127
案例:
[root@shell ~]# ping -c1 -W1 www.baidu.com &>/dev/null
[root@shell ~]# echo $?
0
[root@shell ~]# cat ping.sh
#!/bin/bash
ping -c1 -W1 $1 &>/dev/null
[ $? -eq 0 ] && echo "$1 通的" || echo "$1 不通"
[root@shell ~]# sh ping.sh www.baidu.com
www.baidu.com 通的
[root@shell ~]# sh ping.sh www.baidu.commmmmm
www.baidu.commmmmm 不通
[root@shell ~]# sh ping.sh 10.0.0.5
10.0.0.5 不通
[root@shell ~]# sh ping.sh 10.0.0.1
10.0.0.1 通的
$$ 在有多个相同名称的shell环境中使用
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $$ > /tmp/nginx_pid # 将当前的pid号写入文本中
脚本传参的三种方式
第一种方式:
直接传参
[root@shell scripts]# cat test.sh
#!/bin/bash
echo $1 $2
[root@shell scripts]# sh test.sh oldboy 100
oldboy 100
第二种方式:
赋值传参
[root@shell scripts]# cat test.sh
#!/bin/bash
name=$1
age=$2
echo $name
echo $age
[root@shell scripts]# sh test.sh oldboy 200
oldboy
200
[root@shell scripts]# cat test.sh
#!/bin/bash
name=$1
age=$2
echo 姓名: $name
echo 年龄: $age
[root@shell scripts]# sh test.sh oldboy 100
姓名: oldboy
年龄: 100
第三种方式:
read读入
[root@shell scripts]# read name
oldboy
[root@shell scripts]# echo $name
oldboy
[root@shell scripts]# read -p "请输入你的姓名" name
请输入你的姓名oldboy
[root@shell scripts]# echo $name
oldboy
[root@shell scripts]# read -p "请输入你的姓名: " name
请输入你的姓名: HEHE
[root@shell scripts]# echo $name
HEHE
第一种书写方式
[root@shell scripts]# cat test.sh
#!/bin/bash
read -p "请输入你的姓名: " name
read -p "请输入你的年龄: " age
echo name=$name
echo age=$age
[root@shell scripts]# sh test.sh
请输入你的姓名: hehe
请输入你的年龄: 1
name=hehe
age=1
第二种书写方式
[root@shell scripts]# cat test.sh
#!/bin/bash
read -p "请输入你的姓名和年龄: " name age
echo name=$name
echo age=$age
[root@shell scripts]# sh test.sh
请输入你的姓名和年龄: oldboy 20
name=oldboy
age=20
[root@shell scripts]# cat test.sh
#!/bin/bash
read -p "输入要备份的目录: " dir
tar zcf test.tar.gz $dir
作业: 使用三种传参方式修改IP地址和主机名称 read 注意双引号和单引号的用法 sed
1.传参传入新的主机名
2.使用命令进行修改
IP地址
2.IP配置文件 sed s#10.0.0.7#10.0.0.200#g /etc/sysconfig/network-scripts/ifcfg-eth0 先获取当前IP做变量
1.传入新的IP地址
[root@shell scripts]# cat hostname.sh
#!/bin/bash
#修改主机名称
read -p "输入主机名称: " name
hostnamectl set-hostname $name
#修改IP地址
#获取当前的IP地址
ip_dir=/etc/sysconfig/network-scripts/ifcfg-eth0
sip=`awk -F. '/IPADDR/{print $NF }' $ip_dir`
read -p "输入主机名称: " ip
sed -i "s#$sip#$ip#g" $ip_dir
grep $ip $ip_dir
小结:
1.学习shell
2.基础知识
3.规范
4.语言种类
5.shell执行的三种方式
6.变量分类 export区别 变量相关的文件
7.变量的定义 名字定义 值的定义 命令的定义 date
8.核心位置变量 $0 $n $# $?
9.传参的三种方式 直接传参 赋值传参 read读入
笔试题: echo $user结果是: 空
[root@shell ~]# cat test.sh
user=`whoami`
[root@shell ~]# sh test.sh
[root@shell ~]# echo $user
[root@shell ~]# . test.sh
[root@shell ~]# echo $user
root