day62 shell的实战开发
day62 shell 实战的开发
实战开发
开发脚本的3部曲
1.拿到一个需求
2.拿到需求先去分析,写别着急写
3,精准分析之后,有了思路,一步一步写出脚本
1. 编写脚本
- 通过位置参数的形式
- 免交互的形式创建linux用户和密码
拿到需求
写分析需求,要看清楚,在开始写代码
user.sh $1 $2 $3
拆解,分析需求,然后考虑用什么命令去做
1.接收位置参数,传来的账号,密码
2.在系统中,创建相对应useradd用户,密码(echo "密码" | passwd --stdin username)
3.需求分析到这,就产出代码。
[root@master-61 ~]# cat user_pwd.sh
#!/bin/bash
# ***************************************************************************
# *
# * @file:user_pwd.sh
# * @author:www.yuchaoit.cn
# * @date:2025-05-02 10:02
# * @version 1.0
# * @description: Shell script
# * @Copyright (c) all right reserved
#*
#**************************************************************************/
exit 0
# 养成好的习惯,脚本中给自己添加注释,以后回头看的时候,有注释在很快就能看懂。
# 1.接受的位置的参数
# bash user_pwd.sh yzk01 yzk666
username="${1}"
pwd="${2}"
# 2.数据已经写入变量,可以调用变量,创建对应用户的信息
# useradd ${1}
useradd "${username}"
#他们这个都是一个的意思
#创建密码
echo "${pwd}" | passwd --stdin "${username}"
编写通过参数的位置,自动的修改主机名的脚本
[root@m-61 ~/part3-shell]#cat change_hostname.sh
#!/bin/bash
# ***************************************************************************
# *
# * @file:change_hostname.sh
# * @author:www.yuchaoit.cn
# * @date:2022-06-22 11:59
# * @version 1.0
# * @description: Shell script
# * @Copyright (c) all right reserved
#*
#**************************************************************************/
# 接收新的主机名
new_hostname=$1
# 设置修改主机名
hostnamectl set-hostname ${new_hostname}
# 查看新的主机名
# 写在 $() 里面的,就是linux的命令了,而不是普通的字符串。
echo "当前新的主机名是 :$(hostname)"
# 这个脚本看懂 刷 1111
交互式参数传递(read命令)
利用read命令,接收用户的收入,从键盘读取标准的输入
语法
read -p "提示信息"变量名

用户信息接收
需求是
1. 程序和用户进行交互,需要用户输入,账户,密码2个数据
2. 程序简单的打印用数据,练习read的用法
[root@m-61 ~/part3-shell]#cat user_info_input.sh
#!/bin/bash
# ***************************************************************************
# *
# * @file:user_info_input.sh
# * @author:www.yuchaoit.cn
# * @date:2022-06-22 12:12
# * @version 1.0
# * @description: Shell script
# * @Copyright (c) all right reserved
#*
#**************************************************************************/
# 接收账号数据
read -p "请输入你的账户:" user
# 接收密码数据,密码,建议隐藏显示,更安全
# -s 将密码和终端颜色保持一致,导致你看不到。
# pwd这么用,对 扣 1不对 扣2
#pwd 属于覆盖系统内置命令,必然不合适。变量命名不规范了!!!
read -s -p "please input your password:" my_pwd
# 打印输入的结果
echo "您的账户是:$user"
echo "您的密码是:$my_pwd"
[root@m-61 ~/part3-shell]#
# 执行测试
备份目录脚本
# 1. 让用户输入要备份的目录 路径
# 2. 程序自动创建备份目录,且复制数据,实现备份
[root@m-61 ~/part3-shell]#cat read-backup.sh
#!/bin/bash
# ***************************************************************************
# *
# * @file:read-backup.sh
# * @author:www.yuchaoit.cn
# * @date:2022-06-22 12:20
# * @version 1.0
# * @description: Shell script
# * @Copyright (c) all right reserved
#*
#**************************************************************************/
# 1. 让用户输入要备份的目录 路径
read -p "请输入要备份的目录绝对路径:" src_dir
# 2. 程序自动创建备份目录,且复制数据,实现备份
read -p "请输入要备份的目的地绝对路径:" dest_dir
# 3.创建备份目录,且把数据拷贝过来,实现备份
# 问,这个命令二次执行会报错吗? 会扣1 不会扣2
# 以咱们目前这个写法
# 解答一波,你要看你自己怎么写。 因为加上 -p参数,因此反复执行,不会导致目录创建报错
# 看懂刷33333
# 在学了 if 条件之后,要在这里判断
# 正确的逻辑应该是,如果目录不存在,则创建
# 存在, 则跳过mkdir的动作
# 理解刷 44444
mkdir -p ${dest_dir} && cp -a ${src_dir} ${dest_dir}
# 4. 脚本查看备份的数据目录信息
echo -e "备份的数据如下:\n$(ls ${dest_dir})"
# 看30s脚本,看懂刷 666
# 先看懂,中午自己练练
[root@m-61 ~/part3-shell]#
[root@m-61 ~/part3-shell]#bash read-backup.sh
请输入要备份的目录绝对路径:/var/log
请输入要备份的目的地绝对路径:/tmp/log/
备份的数据如下:
log
用户输入综合的小的练习(实践)
脚本练习,建议是先自己写写,只要完成结果。
一百个人,能写出100种的风格
需求
接收用户输入 read 的数据,创建系统用户;(账户,密码)
且将用户输入保存到文件/tmp/user_info.log,保存格式为username:pwd 键值对形式
风格1,交互式让用户输入数据
# 接收账户
read -p "please input your account:" your_user
# 接收密码
read -p "please input your password:" your_password
# 用数据, 创建系统用户且设置密码
useradd ${your_user}
echo "${your_password}" | passwd --stdin ${your_user} > /dev/null 2>&1
# 打印数据,写入到文件里
echo "${your_user}:${your_password}" >> /tmp/user_info.log
运行且验证,该需求的写法
-
分析需求
-
写伪代码,写中文注释,捋清楚题目要求,题目细节
-
输出为shell的代码
-
测试执行
1. 查看题目要求的文件
2. 用该用户登录
ssh cc01@172.16.1.61
3.再次添加一个新用户,查看结果
[root@m-61 ~/part3-shell]#bash read_user.sh
please input your account:lubenwei01
please input your password:lubenwei666
[root@m-61 ~/part3-shell]#
[root@m-61 ~/part3-shell]#
[root@m-61 ~/part3-shell]#
[root@m-61 ~/part3-shell]#cat /tmp/user_info.log
cc01:cc666
lubenwei01:lubenwei666
风格2,接收到位置参数的数据$1 $2完成上述的操作

修改主机IP,主机名的脚本(实践)
- 交互式脚本修改,read接收用户输入的ip和主机名
- 非交互式脚本的修改(位置参数),给脚本直接传入ip和主机名,但是要注意参数的顺序
#!/bin/bash
# 代码是自上而下加载的。
read -p "请输入新的主机名:" new_hostname
# 立即修改
hostnamectl set-hostname ${new_hostname}
# 替换ip
read -p "请输入新的ip地址:" new_ip
sed -i "/IPADDR=/c IPADDR=${new_ip}" /etc/sysconfig/network-scripts/ifcfg-eth0
# 显示替换结果
echo -e "当前主机名是:\n$(hostname)"
echo -e "当前的网卡配置文件是:\n$(cat /etc/sysconfig/network-scripts/ifcfg-eth0 )"
# 重启network服务
echo "重启网络服务中。。。。"
systemctl restart network
# 统一的修改
# 修改配置文件,重启network服务
# 方案1,直接用 sed的c命令,整行替换数据
# 方案2,用sed的s命令,替换整个ip
# 方案3,用sed的s命令,只替换ip最后一个的主机位地址。
# 这3个方案,听懂 刷3333
# 方案有很多,随着你代码写的多了,写熟练了,心中自然也就有了很多的解决方案了。
脚本的开发的思路,与实践
思路是很重要的,今天作业就会有需要,需要用其他的方案,有2,3个方案去完成脚本的开发。
定时任务的脚本
用read命令去让用户输入数据
利用位置参数的特殊的变量,直接非交互传入数据
需求
通过非交互式,创建新的定时的任务规则,要求
每十分钟和阿里云时间服务器同步
条条道路通罗马,多可以解决问题
# 通过交互式的脚本,创建新的定时任务的规则
# crontab -e 这是一种交互式的输入,脚本,思考
# 定时任务具体写到文件里
# 方案一 写法简单的粗暴,直接输入完整的语句
read -p "请输入要插入的新定时任务完整规则:" new_crontab
echo "${new_crontab}" >> /var/spool/cron/root
echo "当前的计划任务的规则的列表:"
echo "$(crontab -l)"
# 每十分钟和阿里云时间服务器同步 */10 * * * * ntpdate -u ntp.aliyun.com
纠正,read命令,把用户所有的输入,当作了一个大字符串
# 执行脚本流程如下
[root@master-61 ~]#bash new_crontab.sh
请输入您要插入的新定时任务完整规则:*/10 * * * * ntpdate -u ntp.aliyun.com
当前的计划任务规则列表是:
*/10 * * * * ntpdate -u ntp.aliyun.com
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#
[root@master-61 ~]#crontab -l
*/10 * * * * ntpdate -u ntp.aliyun.com
方案2,规则和命令分开写
#!/bin/bash
read -p "请输入crontab的时间频率:" cron_time
read -p "请输入crontab的具体命令:" cron_job
# 让用户输入生效
echo "#crontab by yuchao at $(date +%F)" >> /var/spool/cron/root
echo "$cron_time $cron_job" >> /var/spool/cron/root
echo -e "当前最新的计划任务是:\n$(crontab -l)"
执行如下的结果,注意命令要用绝对路径来的靠谱
[root@master-61 ~]#
[root@master-61 ~]#bash new2_cron.sh
请输入crontab的时间频率:*/5 * * * *
请输入crontab的具体命令:/usr/sbin/ntpdate -u ntp.aliyun.com
当前最新的计划任务是:
*/10 * * * * /usr/sbin/ntpdate -u ntp.aliyun.com
#crontab by yuchao at 2022-06-22
*/5 * * * * /usr/sbin/ntpdate -u ntp.aliyun.com
练习时间
要求,分别以交互式,非交互式两种方式开发的开发
1. 创建3个用户,设置密码(限定11位密码,且隐藏显示),且记录到文件中/tmp/user_info.log,为如下格式
username:pwd
username:wpd
username:pwd
2. 编写修改主机名和IP的脚本,且立即生效
3. 编写设置定时任务的脚本,每五分钟和阿里云时间服务器同步,且不提示任何日志。
4. 写一个探测主机存活的脚本(提示用$?预定义变量)
定义变量(脚本的位置的参数,位置变量)
刚才练习,基本上是围绕着,交互式的数据
利用read命令,实现用户输入数据,传入变量
针对变量进行后续的操作,
非交互式变量的传入,位置参数。
$1 , $2 , $3
位置参数,以空格分割每一个元素,作为参数
# read 命令,是你所有的输入,被一个大的字符串传入给变量。
#位置变量的玩法不一样
# bash vars.sh cc01 bb01 yzk01 jack01

难点
几个特殊位置参数变量
$* 接受所有位置参数
$@ 接收所有位置参数
$# 参数的个数
$$ 获取当前进程的PID
$? 返回一个命令的返回值,0是正确,其他都是错误(指的是你的脚本上,查看$?的上一条的命令)
# 分析需求
# 判断主机是否存活,常见的做法是发送icmp的数据包,也就是执行ping命令
#尝试用命令去完成需求
# 1.ping
# 2.查看 echo $?
# 条件判断,机器是否挂了
# 基于if语法
# 中括号,是条件判断的专有语法,以及shell编程中,遇见括号,就得闭合,左右都得有空格。
# 中括号,是条件判断的专有语法,以及shell编程中,遇见括号,就得闭合,左右都得有空格。
# 中括号,是条件判断的专有语法,以及shell编程中,遇见括号,就得闭合,左右都得有空格。
[root@master-61 ~/part3-shell]## 特殊变量 ,完成写法如下,${#} ${*} ${?} 看懂 66666666,和普通变量一样
# 完成脚本开发
#!/bin/bash
# 传入位置参数的玩法
ping -c 1 ${1} &>/dev/null 2>&1
if [ "$?" == "0" ];then
echo "该机器 ${1} 正在运行中!!!"
else
echo "该机器 ${1} 挂掉了!!!!"
fi
执行结果
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#cat check_host.sh
#!/bin/bash
# ***************************************************************************
# *
# * @file:check_host.sh
# * @author:www.yuchaoit.cn
# * @date:2022-06-22 16:19
# * @version 1.0
# * @description: Shell script
# * @Copyright (c) all right reserved
#*
#**************************************************************************/
#!/bin/bash
# 传入位置参数的玩法
ping -c 1 ${1} &>/dev/null 2>&1
if [ "$?" == "0" ];then
echo "该机器 ${1} 正在运行中!!!"
else
echo "该机器 ${1} 挂掉了!!!!"
fi
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#bash check_host.sh 172.16.1.88
该机器 172.16.1.88 挂掉了!!!!
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#bash check_host.sh 172.16.1.7
该机器 172.16.1.7 正在运行中!!!
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]#
[root@master-61 ~/part3-shell]## 该脚本的开发思路、流程、执行结果,看懂刷 11111
You have new mail in /var/spool/mail/root
[root@master-61 ~/part3-shell]#
6.3 获取所有位置参数(难点,是练习$@ 和$*的玩法)
当我们想从脚本运行,传入的参数中获取具体的参数,可以用${n}
但是如果用户传入的参数不固定,你知道到底用 ${数字写多少合适?}
因此这时候,$* 和 $@ 的威力就来了,可以获取所有的位置参数(除了$0)
但是这俩变量虽说都是提取所有参数,但是提取之后的数据构造不一样,具体是什么,看于超老师给你演示一波。。
场景一,不加引导
当用户传入多个参数,都是以空格作为分隔符,获取每一个元素,此时$* 和$@无区别
注意此时,$*和$@这个特殊的变量,都没添加引号

--------------重点(记住如下用法即可)-----------------
1. $@ 和$* 都用于接收不定长的参数
2.在脚本中使用这两个特殊的变量,必须加上双引号,才能发挥器作用
3. 一般都是结合for循环去,找出这两个的特殊存储的所有的元素。
测试脚本如下
echo "----------------测试\$*,给变量添加了引号用法--------------"
for v in "$*"
do
echo "传入的位置参数,分别是${v}"
done
echo "----------------测试\$@,添加了引号用法--------------"
for v in "$@"
do
echo "传入的位置参数,分别是${v}"
done
课后的作业
学编程这一块,学好的诀窍;
- 思考、思考、思考
- 动手、动手、动手
1.写笔记
2.写代码,做练习
1. 你理解的shell脚本是什么,作用,使用场景有哪些;
2. shell脚本书写规范;
3. shell定义变量的方式;
4. shell如何引用变量;
5. shell脚本的预定义变量的含义(面试经常问,笔试题常见)
$0
$1
$2
$*
$@
$#
$$
$?
6. 变量的运算方式有哪些。
7. 今日课堂练习讲解动手练,做笔记;
练习题
8. 写脚本,提取当前机器的静态属性,包括如下,写入文件/tmp/server_info.log
系统版本
内核版本
主机名
eth0网卡ip
eth1网卡ip
当前主机的公网ip
内存使用率
磁盘使用率
CPU使用率
9.开发计算器脚本,支持加减乘除即可。
看看谁的计算器更牛
不怕写的简单,能实现 加减乘除功能就行!!
浙公网安备 33010602011771号