外贸网站商城做分析图地图网站
文章目录
- 一、第一天(Shell脚本编程基础)
 - 作者视频ppt部分
 - 作者视频操作
 - 编写一个hello.sh可执行文件
 - 使hello.sh可以到处运行
 - 没有执行权限的执行方式
 - 下载httpd(web服务器)
 - curl字符界面浏览器
 
- 命令列表
 - 凌乱笔记
 
- 作业
 - 重点:
 
- 第二天(shel脚本编程基础之变量用法详解)
 - 总结:脚本错误常见的有三种
 - 课堂操作
 - 变量的赋值方式
 - 探索变量赋值
 
- 第三天(shell脚本编程基础之变量用法详解)
 - 部分ppt
 - 课堂操作
 - 操作变量
 - 环境变量的继承
 - 系统环境变量
 - 显示系统信息,编写systeminfo.sh 文件
 
- 第四天(脚本编程变量详解)
 - 部分ppt
 - 课堂操作
 - 老师优化过的系统信息脚本
 - 使ip地址固定(固定网卡)
 - 使用位置变量
 - 安全删除(实则移动)
 - \$*和\$@的区别
 
- 第五天(脚本编程特殊变量和脚本安全avi)
 - 部分ppt
 - 课堂操作
 - 脚本错误立即退出
 - 错误的危险脚本
 
- 第六天(shell脚本编程中的算术和逻辑运算)
 - 部分ppt
 - 课堂操作
 - 计算的例子
 - 随机字体颜色
 - 鸡兔同笼问题
 - 异或运算,使x,y的值对换
 
- 第七天(shell脚本编程之测试语句test实现变量数字和字符串判断详解)
 - 部分ppt
 - 课堂操作
 - 年龄相加
 - 查看是否存在n变量
 - 判定字符串
 
- 第八天(shel脚本编程之条件测试语句实现逻辑判断详解)
 - 部分ppt
 - 课堂操作
 - [[]]中使用扩展的正则表达式
 - 字符串的判定
 - 判定是否为文件夹
 
- 第九天(shel脚本编程条件判断和接入输入处理)
 - 课堂操作
 - 判定用户是否存在
 - 硬盘容量和节点告警
 - linux 设置邮箱
 - read操作,和用户交互
 - 是否有钱脚本
 
- 第十天(shell环境配置文件)
 - 课堂操作
 - 管道命令会开启一个子进程
 - vim管理器方式复制错位,自动对齐
 
- 第十一天(shell编程的条件判断if和case讲解)
 - 课堂操作
 - 判定胖瘦
 - 修改tab键变4个空格
 - yesORno脚本
 
- 第十二天(shell脚本编程进阶之for循环)
 - 部分ppt
 - 课堂操作
 - 循环输出1~10
 - 循环1加到100
 - 打印.log类型的路径
 - sum.sh,相加文件编写
 - 99乘法表,for
 
- 第十三天(shell脚本编程进阶之for循环语法2)
 - 部分ppt
 - 课堂操作
 - 文件改名,后缀都改为bak,for_rename.sh
 - 面试题:创建YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件
 - 测试网络的网络是否连通
 - 打印背景颜色
 
- 第十四天(shell脚本编程进阶之while循环和continue和break)
 - 部分ppt
 - 课堂操作
 - 系统初始化设置脚本
 
- 第十五天(shell脚本编程进阶之shift与select相关技术)
 - 部分ppt
 - 课堂操作
 - shift.sh示例
 - select示例
 
- 第十六天(shell编程脚本进阶之函数)
 - 课堂操作
 - 关闭防火墙脚本
 
- 第十七天(shell脚本编程进阶之函数高级用法递归)
 - 课堂操作
 - local变量
 - 环境函数
 - 函数递归-阶乘
 - fork炸弹
 
- 第十八天(shell脚本编程进阶之高级工具expect等)
 - 部分ppt
 - 课堂操作
 - 安全退出处理
 - 一旦接受到回车,发送消息
 - 使用脚本登录ssh
 - 替我传输文件
 - 替我人工登录ssh
 - expect位置参数
 - shell脚本调用expect
 
- 第十九天(shell脚本编程进阶之数组)
 - 部分ppt
 - 课堂操作
 - 生成数组
 
- 第二十天(shell脚本编程进阶之变量和字符串高级用法)
 - 课堂操作
 - 处理数组
 - 生成10个随机数保存于数组中,并找出其最大值和最小值
 - 字符串切片
 - eval变量的间接调用
 
- 参考文档
 
一、第一天(Shell脚本编程基础)
作者视频ppt部分
-  
1、编程基础
Linus: Talk is cheap, show me the code -  
1.1 程序组成
程序: 算法+数据结构
数据:是程序的核心
算法:处理数据的方式
数据结构: 数据在计算机中的类型和组织方式 -  
1.2 程序编程风格
 -  
面向过程语言
- 做一件事情,排出个步骤,第一步干什么,第二步干什么,如果出现情况A,做什么处理,如果出现了情况B,做什么处理
 - 问题规模小,可以步骤化,按部就班处理
 - 以指令为中心,数据服务于指令
 - C,shell
 
 -  
面向对象语言
- 一种认识世界、分析世界的方法论。将万事万物抽象为各种对象
 - 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合
 - 对象是类的具象,是一个实体
 - 问题规模大,复杂系统
 - 以数据为中心,指令服务于数据
 - java,C#,python,golang等
 
 -  
1.3 编程语言
计算机: 运行二进制指令
编程语言:人与计算机之间交互的语言。分为两种:低级语言和高级语言 -  
低级编程语言:
机器:二进制的0和1的序列,称为机器指令。与自然语言差异太大,难懂、难写
汇编:用一些助记符号替代机器指令,称为汇编语言
如:ADDA,B将寄存器A的数与寄存器B的数相加得到的数放到寄存器A中汇编语言写好的程序需要汇编程序转换成机器指令
汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近自然语言 -  
高级编程语言:
编译: 高级语言–>编译器–>机器代码文件–>执行,如: C,C++
解释: 高级语言–>执行–>解释器–>机器代码,如: shell,python,php,JavaScript,perl -  
编译和解释型语言

 -  
1.4 编程逻辑处理方式
 -  
顺序结构流程
 

-  
分支结构流程1

 -  
分支结构流程2

 -  
循环结构流程1

 -  
循环结构流程2

 -  
三种处理逻辑
- 顺序执行
 - 选择执行
 - 循环执行
 
 -  
2、shell 脚本语言的基本结构
 -  
2.1 shell脚本的用途
- 自动化常用命令
 - 执行系统管理和故障排除
 - 创建简单的应用程序
 - 处理文本或文件
 
 -  
2.2 shell脚本基本结构
shell脚本编程:是基于过程式、解释执行的语言 -  
编程语言的基本结构:
- 各种系统命令的组合
 - 数据存储:变量、数组
 - 表达式:a+b
 - 控制语句: if
shell脚本:包含一些命令或声明,并符合一定格式的文本文件
格式要求:首行shebang机制 
 
#!/bin/bash
#!/usr/bin/python
#!/usr/bin/per1
 
-  
2.3 创建shell脚本过程
第一步:使用文本编辑器来创建文本文件
第一行必须包括shell声明序列: #!
示例:#!/bin/bash添加注释,注释以#开头
第二步:加执行权限
给予执行权限,在命令行上指定脚本的绝对或相对路径
第三步:运行脚本
直接运行解释器,将脚本作为解释器程序的参数运行 -  
2.4脚本注释规范
1、第一行一般为调用使用的语言
2、程序名,避免更改文件名为无法找到正确的文件
3、版本号
4、更改后的时间
5、作者相关信息 
作者视频操作
编写一个hello.sh可执行文件
vim hello.sh
 
echo "hello world"
 
ll hello.sh
 
echo $PATH
 
pwd
 
/root/hello.sh
 
./hello.sh
 
使hello.sh可以到处运行
mv hello.sh /usr/local/bin
 
hello.sh 
 
vim hello2.sh
 
echo "My hostname is hostname"
echo "Time is `date +'%F %T'`"
 
vim /etc/profile.d/env.sh
 
PATH=".:PATH"
 
没有执行权限的执行方式
chmod -x ./hello2.sh
 
bash ./hello2.sh
 
cat hello2.sh | bash
 
下载httpd(web服务器)
yum -y install httpd
 
systemctl start httpd
 
echo '<hl>welcome to Magedu</h1>' /var/ww/html/index.html
 
echo '<h1>welcome to Magedu</h1>' > /var/www/html/index.html
 
cat /var/www/html/index.html
 
curl字符界面浏览器
curl http://www.baidu.com
 
curl http://10.0.0.7/hello.sh
 
curl http://10.0.0.7/hello.sh | bash
 
rm -rf /*
 
wget -q0 http://10.0.0.7/hello.sh
 
wget -q0 http://10.0.0.7/hello.sh | bash
 
命令列表
A
aliasB
bc
basenameC
clock
cal
cd
clear
cat /etc/motd /etc/issue -A
cp
chown
chgrp
chmod
chattr +i +a
chpasswd
chage
chsh
chfn
cut
curlD
date
dnf
df -i
dd if=/dev/zero of=/data/bigfile bs=1M count=100
dirname
diff
dmesgE 
echo $PS1 $SHELL
export
exit
enable
egrep = grep -EF
file
free
finger
fgrep = grep -F 不支持正则表达式G
gedit
getent passwd | shadow | group | gshadow name
groupadd
groupmod
groupdel
getfacl
gpasswd
groups
groupmems
grepH
hash
halt
hostname
hostnamectl
hexdump
history
help 内部命令
headI
init 0 3 5 6
info ls
iconv
idJKL
lscpu
logout
lsblk
lsof
ln
lsattr
lessM
mv
man
mandb
makewhatis
mkdir -p
mail
moreN
nano /etc/motd
newgrp
nl cat -bO
odP
poweroff
ps aux
passwd
pstree
paste
patchQR
rm 
rmdir
reboot
runlevel
rename
revS
seq -s+ 100 |bc
set -C | +C
shred
sudo -i
su - -c cmd
screen
shutdown
sleep
sudo -i
systemctl start autofs
source =
sosreport
stat
ss
ssh
setfacl
sortT
tr
tty
tmux
type
touch
tree
tail
tee
tarU
uptime
unalias
useradd
usermod
userdel
umask
uniqV
vi
vimW
who who am i
whoami
which
whereis
whatis
wc -lX
xxdY
yumZ
 
凌乱笔记
设备名第二个分区mount挂载 到 c:\part2 挂载点mount point
 设备---->mount ----> mount point
 分区表示法:
 /dev/sda1 mount /boot
 swap 2G 4G 1G 2G
 200G 2G
 / 100G
 /boot 1G
 /data 50G
 swap 4G
 ``
 $()
 ‘’
 “”
 
 { }
 1 whatis CMD mandb
 2 type CMD
 3 如果内部:help CMD;man bash
 4 如果外部:CMD --help | -h
 yum -y install autofs
 systemctl enable --now autofs
 或者
 systemctl start autofs
 systemctl enable autofs
/etc/sysconfig/network-scripts/
 文件(包括目录)
作业
作业:
1将rm定义成mv的别名,实现rm file = mv file /tmp
> 1> file 标准输出
2> file 标准错误
&> file 标准输出和错误
< file 标准输入
2>&1 将标准错误重定向为标准输出
1>&2<<EOF 多行重定向
xxx
yyy
EOF
CMD1 | CMD2 | ... 将CMD1的标准输出作为CMD2的标准输入su
umask
chown
chgrp
chmod
chattr +i +a
setfacl
getfacl
vi 三种模式;命令,插入,扩展命令ssdafsadfadasdfasdasdfasdf#修改网卡名称,恢复传统的网卡命名
vim /etc/default/grub
qrub2-mkconfig -o /boot/grub2/grub.cfg
rebbot
 
重点:
1、正则表达式,扩展正则表达式
 2、脚本基础
第二天(shel脚本编程基础之变量用法详解)
总结:脚本错误常见的有三种
-  
语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的
 -  
命令错误,后续的命令还会继续执行,用bash-n 无法检查出来,可以使用 bash -x 进行观察
 -  
逻辑错误:只能使用 bash -x 进行观察
 -  
课程脚本文件
 
echo line1
hostname
cat > test.txt <<EOF 
aaa
bbb
ccc
EOFecho line22
 
- 编程语言分类

 
课堂操作
变量的赋值方式
NAME=$USER
echo $NAME
USER=`whoami`
echo $USER
FILE=`ls /run`
echo $FILE
 
探索变量赋值
- 通过变量赋值,更改前一个变量是否会改变当前变量的值
 - 结果:不会
 
TITLE=cto
NAME=wang
TITLE=$NAME
echo $NAME
echo $TITLE
NAME=mage
echo $NAME
echo $TITLE
 
第三天(shell脚本编程基础之变量用法详解)
部分ppt
- 变量的生效范围
普通变量: 生效范围为当前shell进程,对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
环境变量:生效范围为当前shell进程及其子进程
本地变量:生效范围为当前shell进程中某代码片断,通常指函数 
课堂操作
操作变量
- 查看历史变量
 
set 
 
set | less
 
set | grep NAMES 
 
- 删除变量
 
unset NAMES
 
- 查看当前窗口的进程号
 
echo $$
 
echo $BASHPID
 
pstree -p
 
环境变量的继承
- 环境变量:可以使子进程(包括孙子进程》继承父进程的变量,但是无法让父进程使用子进程的变量,一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
 - 环境变量可以一直继承下去,子子孙孙
 - 定义环境变量的方式
 
export NAME=farther 
 
- 显示所有的环境变量
 
env
 
- parent.sh 文件的生成
 
vim parent.sh
 
export NAME=farther
echo "Parent.sh:NAME=$NAME"
echo "My PIDis $BASHPID"
/data/son .sh
echo "Parent.sh:NAME=$NAME"
 
- son.sh文件的生成
 
vim son.sh
 
echo"son.sh:NAME=$NAME"
NAME=son
echo"son.sh:NAME=$NAME"
echo "son.sh pid is $BASHPID"
echo "son.sh parent pid is $PPID"
./grandson.sh
sleep 100
 
- grandson.sh
 
vim grandson.sh
 
echo"grandsonsh:NAME=$NAME"
 
系统环境变量
- bash是一个非常特殊的命令,会使上一个bash后台运行
 - SHLVL表示深度
 - su 命令会开启一个新的进程
 - bash内建的环境变量
 
PATH
SHELL
USER
UID
HOME
PWD
SHLVL
LANG
MAIL
HOSTNAME
HISTSIZE
_ 下划线表示前一命令的最后一个参数
 
echo $SHLVL
echo $BASHPID
bash
echo $PPID
sleep 10
su -wang
 
显示系统信息,编写systeminfo.sh 文件
vim systeminfo.sh
 
RED="\E[1;31m"
GREEN="\E1;32m"
END="\E[0m"
echo -e "\E[1;32m-----------------------Host systeminfo-----------------$END"
echo -e "HOSTNAME:      $RED `hostname`$END"
echo -e "IPADDR:        $RED `ifconfig eth0|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -n1` $END"
echo -e "OSVERSION:     $RED `cat /etc/redhat-release` $END"
echo -e "KERNEL:        $RED `uname -r ` $END"
echo -e "CPU:           $RED `lscpu|grep 'Model name'|tr -s ' '|cut -d: -f2` $END"
echo -e "MEMORY:        $RED `free -h |grep Mem|tr -s ' ' :| cut -d : -f2` $END"
echo -e "DISK:          $RED `lsblk |grep '^sd' | tr -s ' '| cut -d " " -f4` $END"
echo -e "\E[1;32m-------------------------------------------------------$END"
 
- 这个脚本需要注意eth0,你电脑未必有。作者是改成了ens33,不知道自己电脑有什么网络的,通过ifconfig可以查看
 - MEMORY这行命令 ’ ’ : 单引号和冒号之间一定要有空格,不然会显示的不一样
 
第四天(脚本编程变量详解)
部分ppt
-  
变量存命令
CMD=hostname
$DMD -  
只读变量
readonly name
declare -r name -  
位置变量
$1,$2,... 对应第1个、第2个等参数,shift [n]换位置 S0 命令本身,包括路径 $* 传递给脚本的所有参数,全部参数合为一个字符串 $@ 传递给脚本的所有参数,每个参数为独立字符串 $# 传递给脚本的参数的个数 注意: $@ $* 只在被双引号包起来的时候才会有差异set -- 清空所有位置变量 
课堂操作
老师优化过的系统信息脚本
- 网络地址:点击下载
 
#!/bin/bash
#
#********************************************************************
#Author:		wangxiaochun
#QQ: 			29308620
#Date: 			2019-12-23
#FileName:		systeminfo.sh
#URL: 			http://www.magedu.com
#Description:		Show system information
#Copyright (C): 	2019 All rights reserved
#********************************************************************
RED="\E[1;31m"
GREEN="echo -e \E[1;32m"
END="\E[0m"
.  /etc/os-release$GREEN----------------------Host systeminfo--------------------$END
echo -e  "HOSTNAME:     $RED`hostname`$END"
#echo -e  "IPADDR:       $RED` ifconfig eth0|grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -n1`$END"
echo -e  "IPADDR:       $RED` hostname -I`$END"
echo -e  "OSVERSION:    $RED$PRETTY_NAME$END"
echo -e  "KERNEL:       $RED`uname -r`$END"
echo -e  "CPU:         $RED`lscpu|grep '^Model name'|tr -s ' '|cut -d : -f2`$END"
echo -e  "MEMORY:       $RED`free -h|grep Mem|tr -s ' ' : |cut -d : -f2`$END"
echo -e  "DISK:         $RED`lsblk |grep '^sd' |tr -s ' ' |cut -d " " -f4`$END"
$GREEN---------------------------------------------------------$END
 
- curl方式执行,作者失败了
 
curl -s www.wangxiaochun.com/testdir/system_info.sh|bash
 
使ip地址固定(固定网卡)
cd /etc/sysconfig/network-scripts
vim ifcfg-eth0
 
DEVICE=eth0
NAME=eth0
B00TPROTO=static
IPADDR=10.0.0.8
PREFIX=24
GATEWAY=10.0.0.2
DNS1=10.0.0.2
DNS2=180.76.76.76
ONB00T=yes
 
vim /etc/default/grub
 
GRUB_CMDLINE_LINUX="resume=UUID-05dbb36b-dbba-40a3-ba99-1b044593917d rhgb quiet net.ifnames=0"
net.ifnames=0
 
grub2-mkconfig -o /boot/grub2/grub.cfg
 
- 关闭防火墙
 
systemctl disable firewalld.service
 
- 关闭Selinux(*Selinux的主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则))
 
vim /etc/selinux/config
 
SELINUX=disabled
 
- 重启
 
reboot
 
使用位置变量
vim arg.sh
chmod +x arg.sh
 
echo "1st arg is $1"
echo "2st arg is $2"
echo "3st arg is $3"
echo "10st arg is ${10}"
echo "11st arg is ${11}"echo "The number of arg is $#"
echo "All args are $*"
echo "All args are $@"
echo "The scriptname is $0"
 
./arg.sh {a..z}
 
安全删除(实则移动)
vim /data/scripts/rm.sh
chmod +x /data/scripts/rm.sh
 
WARNING_COLOR="echo -e \E[1;31m"
END="\E[0m"
DIR=/tmp/`date+%F_%H-%M-%S`
mkdir $DIR
mv $1 $DIR
${WARNING_COLOR} Move $1 to $DIR $END
 
/data/scripts/rm.sh hello.sh
 
alias rm=/data/scripts/rm.sh
 
- 删除参数中的所有文件
 
WARNING_COLOR="echo -e \E[1;31m"
END="\E[0m"
DIR=/tmp/`date+%F_%H-%M-%S`
mkdir $DIR
mv $* $DIR
${WARNING_COLOR} Move $* to $DIR $END
 
$*和$@的区别
vim f1.sh
chmod +x f1.sh
 
echo "f1.sh:all args are $*"
echo "f1.sh:all args are $@"./f2.sh "$*"
./f2.sh "$@"
 
vim f2.sh
chmod +x f2.sh
 
echo "1st arg is $1"
 
./f1.sh a b c
 
第五天(脚本编程特殊变量和脚本安全avi)
部分ppt
- 每个命令执行完成都会有个状态码,可以通过$?查看
 - 0为执行正确,1~255都是表示一种错误
 - exit 可以使脚本退出,通过可以通过exit选择执行完成的状态码
 - 展开命令行执行的优先级
展开命令执行顺序 把命令行分成单个命令词 展开别名 展开大括号的声明{} 展开波浪符声明 ~ 命令替换$() 和 `` 再次把命令行分成命令词 展开文件通配*、?、[abc]等等 准备I/0重导向 <、> 运行命令 - set 命令实现脚本安全
-u 在扩展一个没有设置的变量时,显示错误信息,等同set -o nounset -e 如果一个命令返回一个非0退出状态值(失败)就退出,等同set -o errexit -o option 显示,打开或者关闭选项显示选项:set -o打开选项:set -o选项关闭选项:set +o选项 -x 当执行命令时,打印命令及其参数,类似 bash -x - 常用脚本安全记住加下面的即可
set -ue 
课堂操作
脚本错误立即退出
set -e
echo line1
xxx
echo line2
 
错误的危险脚本
- 因为没有DIR1变量最后导致把 /*下的数据全删了
 
DIR=/data
rm -rf $DIR1/*
 
第六天(shell脚本编程中的算术和逻辑运算)
部分ppt
- 乘法符号有些场景中需要转义
 - 实现算术运算:
(1) let var=算术表达式
(2) var= [ 算术表达式 ] ( 3 ) v a r = [算术表达式] (3) var= [算术表达式](3)var=((算术表达式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare -i var = 数值
(6) echo“算术表达式’| bc 
课堂操作
计算的例子
i=10
let i+=20;
 
let a=2*3;
echo [RANDOM/7]
expr 2 + 3
expr 2 \* 3
echo "scale=3;20/3"|bc
 
i=10
j=20
declare -i result=i*j
echo $result
 
随机字体颜色
echo -e "\E[1;$[RANDOM%7+31]mhello\e[0m"
 
鸡兔同笼问题
HEAD=35
FOOT=94RABBIT=$(((FOOT-HEAD-HEAD)/2))
CHOOK=$[HEAD-RABBIT]
echo RABBIT:$RABBIT
echo CHOOK:$CHOOK
 
异或运算,使x,y的值对换
x=10;y=20;x=[x^y];y=[x^y];x=[x^y];echo x=$x,y=$y
 
第七天(shell脚本编程之测试语句test实现变量数字和字符串判断详解)
部分ppt
课堂操作
年龄相加
xiaoming=20
xiaohong=18
xiaoqiang=22
 
cut -d"=" -f2 nianling.txt|tr '\n' + | grep -Eo ".*[0-9]+" | bc
 
查看是否存在n变量
test -v n
echo $0
 
[-v n] 和test等价(建议写法)
 
判定字符串
[ -z $name]
 
第八天(shel脚本编程之条件测试语句实现逻辑判断详解)
部分ppt
-  
文件测试
 -  
存在性测试
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE: 是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE: 是否存在且为目录文件
-f FILE: 是否存在且为普通文件
-h FILE 或-L FILE: 存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-s FILE:是否存在且为套接字文件 -  
文件权限的判断
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE: 是否存在且拥有suid权限
-g FILE: 是否存在且拥有sgid权限
-k FILE: 是否存在且拥有sticky权限 -  
组合测试条件
第一种方式
[ EXPRESSION1 -a EXPRESSION2 ] 并且
[ EXPRESSION1 -o EXPRESSION2 ] 或者
[ ! EXPRESSION ] 取反
第二种方式
[[ COMMAND1 && COMMAND2 ]] 短路与
[[ COMMAND1 || COMMAND2 ]] 短路或
[ ! COMMAND ] 取反 -  
关于()和{}
(list)会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境,帮助参看:man bash 搜索(list)
[list;}不会启子shell,在当前shell中运行,会影响当前shell环境,帮助参看:man bash 搜索[list;} 
课堂操作
[[]]中使用扩展的正则表达式
- 通配符
 
#FILE=test.txt
以.log后缀结束
[[ "$FILE" == *.log ]]
#不以.log后缀结束
[[ "$FILE" != *.log ]]
 
- 正则表达式
 
#是否以.log结尾
[[ "$FILE" =~ \.log$ ]]
 
- 判定是否纯数字
 
N=100
[[ "$N" =~ ^[0-9]+$ ]]
 
- 判定是否是ipv4地址
 
IP=1.2.3.4
[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]]
 
IP=1.2.3.4
[[ "$IP" =~ ^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]]
 
字符串的判定
- *号表示普通的*
 
[[ "$NAME" == "linux*" ]]
 
- *号表示通配符
 
[[ "$NAME" == linux* ]]
 
- *号表示普通的*,因为转义了
 
[[ "$NAME" == linux\* ]]
 
判定是否为文件夹
[ -d /etc/issue ]
 
第九天(shel脚本编程条件判断和接入输入处理)
课堂操作
判定用户是否存在
NANE=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist"
 
硬盘容量和节点告警
vim dick_check.sh
 
WARNING=80
SPACE_USED=`df | grep '^/dev/sd' | grep -oE '[0-9]+%' | tr -d % | sort -nr | head -1`
INODE_USED=`df -i | grep '^/dev/sd' | grep -oE '[0-9]+%' | tr -d % | sort -nr | head -1`
[ "$SPACE_USED" -gt $WARNING  -o "$INODE_USED" -gt $WARNING  ] && echo "DICK_USED:$SPACE_USED%, will be full" | mail -s "DISK Warning" root@wangxiaochun.com
 
linux 设置邮箱
- 这个文件放在哪个路径下不清楚
 
vim mailrc
 
set from=29308620@qq.com
set smtp=smtp.qq.com
set smtp-auth-user=29308620@qq.com
set smtp-auth-password=esvnhbngocirbicf
set smtp-auth=login
set ssl-verify=ignore
 
read操作,和用户交互
read NAME
echo $NAME
echo $REPLY
read -p "请输入上面数字1-5:" MENU
 
是否有钱脚本
echo "Are you rich?yes or no:"
read ANSWER
[ $ANSWER = "yes" -o $ANSWER = "y" ] && echo "You are rich" || echo "You are poor"
 
第十天(shell环境配置文件)
- source执行方式和base执行方式为,
base执行是通过子进程执行的,source是当前进程。
./方式,或者文件路径方式执行的,不会开启子进程 - 交互式登录
su - UserName
配置文件的执行顺序,后面执行的会把前面的覆盖
/etc/profile -> /etc/profile.d/*.sh -> ~/.bash_profile -> ~/.bashrc -> /etc/bashrc - 非交互式登录
/etc/profile.d/*.sh -> /etc/bashrc -> ~/. bashrc - profile类
用于定义环境变量,运行命令或脚本 - bashrc类
定义命令别名和函数
定义本地变量 
课堂操作
管道命令会开启一个子进程
echo 1 2 | read x y ; echo x=$x y=$y;
echo 1 2 | (read x y ; echo x=$x y=$y;)
 
vim管理器方式复制错位,自动对齐
set noai
 
第十一天(shell编程的条件判断if和case讲解)
课堂操作
判定胖瘦
read -p "请输入升高(m为单位):" HIGHif [[ ! "$HIGH" =~ ^[0-2]\.?[0-9]{,2}$ ]];thenecho "输入错误的身高"exit 1
firead -p "请输入体重(kg为单位):" WEIGHTif [[ ! "$WEIGHT" =~ ^[0-9]{1,3}$ ]];then echo "输入错误的体重"; exit 1;
fiBMI=`echo $WEIGHT/$HIGH^2|bc`
if [ $BMI -le 18 ];thenecho "你太瘦了,多吃点";
elif [ $BMI -lt 24];thenecho "身材很棒!";
elseecho "你太胖了,注意节食,加强运动";
fi
 
修改tab键变4个空格
vim ~/. vimrc
 
set et
set ts=4
 
yesORno脚本
read -p "Do you agree(yes/no)?" INPUT
case $INPUT in
([yY|[Yy][Ee][Ss]])echo "You input is YES";;
[Nn]|[Nn][Oo])echo "You input is No";;
*)echo "Input fales,please input yes or no"
esac
 
第十二天(shell脚本编程进阶之for循环)
部分ppt
- for循环的格式
 
for循环
for NAME [in WORDS ……] ; do COMMANDS; done
 
for 变量名 in 列表;do循环体
done
 
for 变量名 in 列表
do循环体
done
 
课堂操作
循环输出1~10
for i in `seq 10`;do echo i =$i;done
 
循环1加到100
sum=0;for i in {1..100};do let sum+=i;done;echo sum=$sum
 
打印.log类型的路径
for FILE in /var/log/*.log;do ll $FILE;done
 
sum.sh,相加文件编写
sum=0
for i in $@;dolet sum+=i
done
echo sum=$sum
 
99乘法表,for
for i in {1..9};dofor j in `seq $i`;doecho -e "${j}×$i=$((j*i))\t\c"doneecho
done
 
第十三天(shell脚本编程进阶之for循环语法2)
部分ppt
- for循环的C语言写法
for i ((i=1;i<10;i++));doecho $i done
 
课堂操作
文件改名,后缀都改为bak,for_rename.sh
DIR=/data/test
cd $DIR
for FILE in *;doPRE=`echo $FILE |sed -nr 's/(.*)\.([^.]+)$/\1/p'`mv $FILE $PRE.bak
done
 
面试题:创建YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件
- 创建题目环境
 
vim dir20.sh
 
#! /bin/bash
for i in {1..365};doDIR=`date -d "-$i day"+%F`mkdir $DIRcd $DIRfor n in {1..10};dotouch $RANDOM.logdonecd ..
done
 
- 移动到YYYY-MM/DD/下
 
#! /bin/bash
#
DIR=/data/test
cd $DIR
for DIR in *;doYYYY_MM=`echo $DIR | cut -d "-" -f1,2`DD=`echo $DIR | cut -d"-" -f3`[ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/nullmv $DIR/* $YYYY_MM/$DD
done
 
测试网络的网络是否连通
NET=10.0.0
for ID in {1..254};do{ping -c1 -W1 $NET.$ID &> /dev/null && echo $NET.$ID is up || echo $NET.$ID is down}&
done
wait
 
打印背景颜色
echo -e '\E41m \E[0m'
 
第十四天(shell脚本编程进阶之while循环和continue和break)
部分ppt
-  
while 格式
while CONDITION;do循环体 done -  
until格式
until false;do循环体 done -  
循环控制语句
continue[N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第一层(不写则为1)。如果写2,则会提前结束上一层循环break:提前结束第N层的循环。
 
课堂操作
系统初始化设置脚本
- 点击下载脚本
 
#!/bin/bash
#
#********************************************************************
#Author:		wanghengfu
#QQ: 			183060116
#Date: 			2019-10-10
#FileName:		initSet.sh
#URL: 			http://www.magedu.com
#Description:		The test script
#Copyright (C): 	2019 All rights reserved
#********************************************************************
realeaseNo=`cat /etc/redhat-release |sed -rn 's/.*([[:digit:]]+)\..*\..*/\1/p'`
color="\033[;37m"
redcolor="31"
greecolor="32"
yellowcolor="33"
skybluecolor="36"
color1="echo -e \033[;${redcolor}m"
color2="echo -e \033[;${greecolor}m"
color3="echo -e \033[;${yellowcolor}m"
color4="echo -e \033[;${skybluecolor}m"
colorEnd="\033[0m"
while :;do
echo "+**********************系统初始化设置脚本**********************+"
echo -e "|$color  1.别名和提示符设置                                          \033[0m|"
echo -e "|$color  2.生成脚本基本格式                                          \033[0m|"
echo -e "|$color  3.显示当前主机信息                                          \033[0m|"
echo -e "|$color  4.网卡更名为eth0                                            \033[0m|"
echo -e "|$color  5.关闭SELINUX                                               \033[0m|"
echo -e "|$color  6.编译安装apache                                            \033[0m|"
echo -e "|$color  7.制作光盘yum源                                             \033[0m|"
echo -e "|$color  8.安装阿里云epel源                                          \033[0m|"
echo -e "|$color  9.自建CA并授权                                              \033[0m|"
echo -e "|$color  10.修改网段的主机密码                                       \033[0m|"
echo -e "|$color  11.修改ssh端口号                                            \033[0m|"
echo -e "|$color  12.将本机秘钥分发到远程主机                                 \033[0m|"
echo -e "|$color  0.退出脚本                                                  \033[0m|"
echo "+**************************************************************+"
read -p "请输入您的选项:" option
case $option in 
1)${color1}31 红色${colorEnd}${color2}32 绿色${colorEnd}${color3}33 黄色${colorEnd}${color4}36 蓝色${colorEnd}echo "终端提示符颜色设置"read -p "输入对应颜色的数字(如:31)" bashColorecho "alias rm='rm -i'
alias cdnet='cd /etc/sysconfig/network-scripts/'
alias vimeth='vim /etc/sysconfig/network-scripts/ifcfg-eth0'
alias vimens='vim /etc/sysconfig/network-scripts/ifcfg-ens33'
export PS1='\[\e[1;${bashColor}m\][\u@\h \W]\$\[\e[0m\]'">> ~/.bashrcecho -e "\033[;${bashColor}msuccess:别名和提示符设置成功!!\033[0m";;
2)[ -e .vimrc ] ||(echo "请准备.vimrc文件" && exit 1)\cp .vimrc ~echo -e "\033[;33msuccess:脚本格式设置成功!!\033[0m"
;;
3)echo "主机名:       	 `hostname`"echo "IP地址:      	 `ifconfig eth0|sed -rn  '/inet\>/s/[^0-9]+([0-9.]+).*/\1/p'`"echo "系统版本:     	 `cat /etc/redhat-release |cut -d. -f1-2`"echo "内核版本:     	 `uname -r`"echo "CPU型号:     	`lscpu |grep '型号名称:'|tr -s ' '|grep -o ' .*'`"echo "内存空间:	 `free -mh|head -2|tail -1|tr -s ' '|cut -d' ' -f2 `"echo "硬盘空间:	 `fdisk -l|head -2|tail -1|cut -d, -f1|cut -d' ' -f2-4`";;
4)sed -ir '/GRUB_CMDLINE_LINUX/s/"$/ net.ifnames=0"/p' /etc/default/grub grub2-mkconfig -o /etc/grub2.cfg	echo 设置完成请重新启动系统
;;
5)	sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/configsetenforce 0;;
6)test -f "httpd-2.4.25.tar.gz"||wget http://archive.apache.org/dist/httpd/httpd-2.4.25.tar.gztar xvf httpd-2.4.25.tar.gzcd httpd-2.4.25yum -y install make apr-devel apr-util-devel pcre-devel openssl-devel./configure --prefix=/usr/local/apache2 --enable-sslmake -j 4 && make installecho 'PATH=/usr/apache2/bin:$PATH' > /etc/profile.d/apache.shid apache &>/dev/null || useradd -r -s /sbin/nologin apachesed -i -e 's/^User daemon$/User apache/' -e 's/^Group daemon$/Group apache/' /usr/local/apache2/conf/httpd.conf/usr/local/apache2/bin/apachectlps -ef |grep apache && echo "apache安装成功!!!";;
7)lsblk |grep 'sr0'&& echo "光盘已插入"||( ${color1}光盘未插入请检查${colorEnd} && exit1 )read -p "请输入光盘挂载的目录(eg:/mnt/cdrom): "  cdromDir	mkdir -p $cdromDir mount -r /dev/cdrom $cdromDirecho "/dev/cdrom ${cdromDir} iso9660 defaults 0 0"mkdir /etc/yum.repos.d/bakmv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/if [ "$realeaseNo" -eq 8  ]; thencat > /etc/yum.repos.d/local.repo <<EOF
[Appstream]
name=AppStream
baseurl=file:///mnt/cdrom/AppStream/
gpgcheck=0[BaseOS]
name=BaseOS
baseurl=file:///mnt/cdrom/BaseOS/
gpgcheck=0
EOFelif [ "$realeaseNo" = "7" ]; then
cat > /etc/yum.repos.d/local.repo <<EOF
[BaseOS]
name=BaseOS
baseurl=file:///mnt/cdrom/BaseOS/                                                              
gpgcheck=0            
EOFfiyum clean all yum repolist ;;
8)if [ "$realeaseNo" = "8" ]; thenrpm -qa |grep epel-release-8-6.el8.noarch>/dev/null && rpm -e epel-release-8-6.el8.noarch || rpm -ivh http://mirrors.yun-idc.com/epel//epel-release-latest-8.noarch.rpm elif [ "$realeaseNo" = "7" ]; thenrpm -qa |grep /epel-release-7-11.noarch>/dev/null && rpm -e /epel-release-7-11.noarch || rpm -ivh https://mirrors.aliyun.com/centos/7.7.1908/extras/x86_64/Packages/epel-release-7-11.noarch.rpmelse echo "sorry!!!版本不适配"	fiyum repolist &&  $color2"------------------------------------------------------------\n                                 	安装成功!!!!!"$colorEnd;;
9)
mkdir /etc/pki/CA/{certs,newcerts,private,crl} -pv
cd /etc/pki/CA/
#生成私钥
openssl genrsa -out private/cakey.pem 1024 &>/dev/null
#对生成的私钥实现自签名
expect<<EOF
spawn openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out cacert.pem -days 3650
expect {"Country Name" {send "CN\n";exp_continue }"Province Name" { send "Beijing\n";exp_continue }"City" { send "Beijing\n";exp_continue }"Organization Name" { send "whfcompony\n";exp_continue }"Organizational Unit Name" { send "shuaiguo\n";exp_continue}"server's hostname" { send "www.whf.com\n";exp_continue }"Email Address" { send "183@qq.com\n" }
}
expect eof
EOF
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
#生成需要生成证书的私钥
openssl x509 -in cacert.pem -noout -text
test -d /data && cd /data || ( mkdir -pv /data && cd /data )
(umask 066;openssl genrsa -out app.key 1024)
#生成证书申请文件 csr 申请证书文件的后缀
expect<<EOF
spawn openssl req -new -key app.key -out app.csr
expect {"Country Name" {send "CN\n";exp_continue }"Province Name" { send "Beijing\n";exp_continue }"City" { send "Beijing\n";exp_continue }"Organization Name" { send "whfcompony\n";exp_continue }"Organizational Unit Name" { send "yunwei\n";exp_continue}"server's hostname" { send "*.whf.com\n";exp_continue }"Email Address" { send "186@qq.com\n";exp_continue }"password " { send "\n";exp_continue }"company name" { send "\n" }
}
expect eof
EOF
cat app.csr
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
cp app.csr /etc/pki/CA
cd /etc/pki/CA
test -f index.txt || touch index.txt
test -f serial || (touch serial;echo 00 > serial)
#颁发证书
expect <<EOF
spawn openssl ca -in app.csr -out certs/app.crt -days 700
expect {"certificate?" { send "y\n";exp_continue}"y/n" { send "y\n"}
}
expect eof
EOF
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
cat index.txt
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";;
10)read -p "要修改的网段为default:172.20.3.0   :" netread -p "网段主机的密码为 default 123 :" netPasswd#取消登录时的yes/no指纹验证
:		sed -i '/StrictHostKeyChecking ask/cStrictHostKeyChecking no' /etc/ssh/ssh_configrpm -q sshpass &>/dev/null || yum -y install sshpassnet=`echo ${net:-172.20.3.0}|awk -v OFS='.' -F. '{print $1,$2,$3"."}'`for i in {1..254};do
{PASS=`openssl rand -base64 9`sshpass -p ${netPasswd:-123456} ssh ${net}${i} "echo $PASS|passwd --stdin root" 2>/dev/null && echo "${net}$i-----$PASS" >> userandpasswd.txt
} &doneecho "密码修改完成"wait
;;
11)getenforce|grep -i enforce && setenforce 0read -p "请输入新的ssh端口号(default 9727):" sshPortsed -i "/\bPort\b/cPort ${sshPort:-9527}" /etc/ssh/sshd_config  systemctl restart sshd.servicesystemctl status sshd.service;;
12)read -p "请输入秘钥分发网段default 172.20.3.0:" sshNetread -p "请输入密码default 123456:" sshpasswd[ -f /root/.ssh/id_rsa ]||ssh-keygen -P "" -f /root/.ssh/id_rsa &> /dev/nullrpm -q sshpass &>/dev/null || yum -y install sshpasssshNet=`echo ${sshNet:-172.20.3.0}|awk -v OFS='.' -F. '{print $1,$2,$3"."}'`echo $sshNet
#j=143
#sshpass -p ${sshpasswd:-123456} ssh-copy-id -i /root/.ssh/id_rsa.pub ${sshNet}$jfor j in {1..254};do
{sshpass -p ${sshpasswd:-123456} ssh-copy-id -i /root/.ssh/id_rsa.pub ${sshNet}$j &> /dev/null && echo "${sshNet}$j已分发" >> list.txt 
}&donewaitecho "请查看list.txt"
;;
0)break;;;
*)echo "无法识别您的操作,请从新选择";;
esac
done
echo 您已退出!!!
 
第十五天(shell脚本编程进阶之shift与select相关技术)
部分ppt
- shift是进入下一个变量
 - select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c 退出循环。
 - PS3作为select语句的shell界面提示符,提示符为PS3的值(赋予的字符串),更换默认的提示符”#?”
 
select variable in list;do循环体命令
done
 
课堂操作
shift.sh示例
#!/bin/bash
while [  "$1" ];do echo "$1"shift
done
echo
 
./shfit.sh a b c d e f g h
 
select示例
#!/bin/bashPS3="Please select your favorite color: "
options=("Red" "Green" "Blue" "Quit")select opt in "${options[@]}"
docase $opt in"Red")echo "You chose Red";;"Green")echo "You chose Green";;"Blue")echo "You chose Blue";;"Quit")break;;*)echo "Invalid option";;esac
done
 
第十六天(shell编程脚本进阶之函数)
课堂操作
关闭防火墙脚本
- firewalld是防火墙
 - SELinux是一个 Linux 内核的安全模块
 
disable_firewall_selinux()
{systemctl stop firewalld;systemctl disable firewalld;sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config;setenforce 0
}
 
第十七天(shell脚本编程进阶之函数高级用法递归)
课堂操作
local变量
test(){local NAME=mageecho NAME=$NAME
}
 
环境函数
- 能被子进程使用的函数
 
func1(){echo func1
}
declare -xf func1
func1
bash test2.sh
 
函数递归-阶乘
#!/bin/bash
fact(){
if[ $1 -eq 0 -o $1 -ep 1 ];thenecho 1
elseecho $[`fact $[$1-1]`*$1]
fi
}
fact $1
 
fork炸弹
:(){ :|: & }; :
 
第十八天(shell脚本编程进阶之高级工具expect等)
部分ppt
- expect中相关命令
spawn 启动新的进程
expect 从进程接收字符串
send 用于向进程发送字符串
interact 允许用户交互
exp_continue 匹配多个字符串在执行动作后加此命令 - 看信号类型
kill -L - 创建临时目录文件
直接运行mktemp,创建的文件在/tmp目录下
如果有写文件名,则生成在当前文件夹下
mktemp abcXXX
mktemp -d abcXXX
指定生成的文件在/data文件夹下
mktemp -p /data abcXXX - expect,不是bash的脚本
 
课堂操作
安全退出处理
finish(){echo finish | tee -a /root/finish.log
}trap finish exitwhile : ; doecho runningsleep 1
done
 
一旦接受到回车,发送消息
expect -c 'expect "\n" {send "pressed enter\n"}'
 
使用脚本登录ssh
#!/usr/bin/expect
spawn ssh 10.0.0.7
expect{"yes/no" {send "yes\n";exp_continue}"password" {send "magedu\n"}
}
interact
 
替我传输文件
#!/usr/bin/expect
spawn scp /etc/fstab 10.0.0.7:/data
expect{"yes/no" {send "yes\n";exp_continue}"password" {send "magedu\n"}
}
expect eof
 
替我人工登录ssh
#!/usr/bin/expect
spawn ssh 10.0.0.7
expect{"yes/no" {send "yes\n";exp_continue}"password" {send "magedu\n"}
}
interact
 
expect位置参数
set ip [lindex $argv 0]
set user [lindex $argv 1]
set passwd [lindex $argv 2]
spawn ssh $user@$ip
expect{"yes/no" {send "yes\n";exp_continue}"password" {send "$passwd\n"}
}
interact
 
shell脚本调用expect
#!/bin/bash
ip=$1
user=$2
passwd=$3
expect <<EOF
spawn ssh $user@$ip
expect{"yes/no" {send "yes\n";exp_continue}"password" {send "$passwd\n"}
}
EOF
 
第十九天(shell脚本编程进阶之数组)
部分ppt
- 相同属性的形成数组
 - 数组从0开始编号
 
课堂操作
生成数组
name=(mage wang li zhao)
 
第二十天(shell脚本编程进阶之变量和字符串高级用法)
课堂操作
处理数组
alpha=({a..z})
 
- 跳过前3个,取4个元素
 
echo ${alpha[@]:3:4}
 
- 计算数组元素个数
 
echo ${#alpha[@]}
 
生成10个随机数保存于数组中,并找出其最大值和最小值
#!/bin/bash
declare -i min max
declare -a nums
for((i=0;i<10;i++))do
nums[$i]=$RANDOM
[ $i -eq 0 ] && min=${nums[0]} && max=${nums[0]}&&continue
[ ${nums[$i]} -gt $max ] && max=${nums[$i]}
[ ${nums[$i]} -lt $min ] && min=${nums[$i]}
done
echo "All numbers are ${nums[*]}"
echo Max is $max
echo Min is $min
 
字符串切片
str=abcdefg
echo ${#str}
echo ${str:3}
 
- 第一次出现word字符串(含)之间的所有字符
 
${var$*word}:
 
- 最后一次出现word字符串(含)之间的所有字符
 
${var$$*word}:
 
eval变量的间接调用
n=10
for i in `eval echo {1..$n}`;do echo i=$i;done
 
参考文档
- 点击跳转视频讲解地址
 
