shell 编程
一 、shell简介
1.shell的作用 shell能做什么?
1)准备服务器 购买服务器 购买云主机 托管的硬件服务器 虚拟化 DOCKER ESXI
2) 安装操作系统 手动安装方式 自动化 安装操作系统 Kickstart cobbler 配置文件
3)优化操作系统
关闭selinux 优化firewalld 公网IP 优化SSH 修改默认端口
安装常用的服务命令 加大文件描述符 修改主机名 修改默认YUM源 时间同步
4)安装服务 使用shell脚本安装不同版本不同服务
5)配置服务 Ansible
6)启动服务 使用脚本启动 停止 重启 重载 可被 systemd管理的服务
第三方软件 自研发软件
例如 :python服务运行
python3.6/server/python/test.py --redis=10.0.0.51 --port=6379 --mysql=10.0.0.52
python3.6/server/python/test.py --redis=10.0.0.51 --port=6379 --mysql=10.0.0.52
python3.6/server/python/test.py --redis=10.0.0.51 --port=6379 --mysql=10.0.0.52
停止python脚本
ps axu |grep test.py |grep -v grep |awk ‘{print $2}’| xargs kill -9
8)监控服务运行状态 监控端口 监控日志等 定时任务+三剑客+shell脚本
9 )代码上线 通过shell脚本自动化发布
10 )日志切割 日志统计 脚本+定时任务实现
mv 移动 不要copy 移动走服务开启情况下 磁盘空间不释放 进程占用
重新加载 或者重新启动服务即可 业务低谷期
日志展示 ELK
日志统计分析 三剑客 +定时任务
11 ) 跳板机 辅助开发的程序正常运行 系统底层的业务
2.学习shell用到的基础知识
1)熟练掌握基础命令
2 )熟悉远程连接工具 Xshell CRT
3 )熟练掌握vim编辑器
切换最后一行 G 切换到首行gg 1G 切换100行 100G
快速复制当前光标所在的行yy 粘贴到10行 p
粘贴100行 100P 批量服务10行
4)熟练掌握 awk sed grep
3. 如何学习shell编程
1)掌握基础命令 变量基础 条牛表达式 if判断 for while case 数组 函数 控制语句
2)学习shell 有一本适合自己的教材 学习shell编程 或者详细的笔记
3) 要有编程思维建立熟练的基础上
4) 一定先模仿着写 模仿书本上的写 修改脚本 完善脚本 安装服务 上不去网 没有yum 没有命令怎么办 如果上不去网怎么办 写自己的脚本
5) 切记拿来即用 一定要熟练变成自己的 从简单的入手 由简单变成复杂
二 、shell入门
- 什么是shell
shell 是命令解释器 解释用户输入的命令或者程序
交互式 :和人交互 shell 等待用户输入命令并且执行 执行成功返回给用户,登录输入命令 ,退出后shell也就终止了。
非交互式 :不和人交互 执行定义好的文件中的内容 执行到文件结尾 shell就结束了 这种叫非交互式。
Linux 默认的shell 为bash
2)什么事shell 脚本
把可执行的命令 放入文本中称为shell脚本 包含了if判断 for循环等语句 - 编程语言的种类
编译型语言 c++ 、c、Delph
解释型语言 Python 、Perl、Shell
脚本语言
其他语言 :HTML
Shell和Python的区别:
Shell解决系统底层的业务 启动 停止 运行 自动安装常用软件 不同版本的 数据统计 shell优先 。
python 软件安装 数据统计 比较笨重 优势 :自动化管理平台 自动化运维工具 页面展示
三 、shell基础入门
1.shell 脚本的规范
注意事项:
1)shell脚本存放固定的目录 :/server/scripts 方便自动化管理
2)脚本的开头需要指定解释器 #!/bin/bash #!/bin/sh
运行命令的时候默认使用什么解释器运行 如果开头不指定 则使用Linux默认的解释器运行bash
3)脚本中有注释 作者信息 版本信息
4)脚本的结尾必须使用.sh结尾
[root@localhost ~]# echo pwd >day.txt
[root@localhost ~]# sh day.txt
/root
5)注释尽量不要出现中文
6)成对的符号和判断循环语句一次性书写完毕
7)脚本中注意符号必须是英文
2.第一个脚本
[root@localhost scripts]# cat tesh.sh
#!/bin/bash ------------指定解释器
#Author zhx -----------------作者信息
#Version V1.O -------------版本信息
#QQ 1105816259 ------------------联系方式
# print Hello world! ---------------内容注释
# 输出世界你好
echo "Hello World!!" --------------具体执行命令
3.常用的执行脚本的三种方式
第一种常用执行脚本方式:
[root@localhost scripts]# sh tesh.sh
Hello World!!
-x 查看脚本执行的过程
[root@localhost scripts]# sh -x tesh.sh
+ echo 'Hello World!!'
Hello World!!
第二种执行脚本的方式:全路径方式执行
错误的执行方式没有加x执行权限
[root@localhost scripts]# /server/scripts/tesh.sh
-bash: /server/scripts/tesh.sh: Permission denied
[root@localhost scripts]# chmod +x tesh.sh 授予所有人执行权限
[root@localhost scripts]# ll tesh.sh
-rwxr-xr-x. 1 root root 122 Jul 24 09:42 tesh.sh
[root@localhost scripts]# chmod -x tesh.sh 取消权限
[root@localhost scripts]# ll
total 4
-rw-r–r--. 1 root root 122 Jul 24 09:42 tesh.sh
[root@localhost scripts]# chmod u+x tesh.sh 只授予root执行权限
[root@localhost scripts]# ll
total 4
-rwxr–r--. 1 root root 122 Jul 24 09:42 tesh.sh
全路径方式也有两种:
1)使用绝对路径执行
[root@localhost scripts]# /server/scripts/tesh.sh
Hello World!!
2)使用相对路径执行
[root@localhost scripts]# ./tesh.sh
Hello World!!
第三种执行脚本的方式 :使用source 或者 点 . 执行 父 shell执行 第一次登录是父shell
[root@localhost scripts]# . tesh.sh
Hello World!!
[root@localhost scripts]# sh tesh.sh
Hello World!!
------------------------------------------------父shell子shell
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
name=zhx
echo $name
[root@localhost scripts]# sh tesh.sh
Hello World!!
zhx
[root@localhost scripts]# echo $name
[root@localhost scripts]# . tesh.sh
Hello World!!
zhx
[root@localhost scripts]# echo $name
zhx
脚本的引用过程
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
. /server/scripts/name.sh
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
echo $name
[root@localhost scripts]# ll
total 8
-rw-r–r--. 1 root root 10 Jul 24 10:17 name.sh
-rw-r–r--. 1 root root 160 Jul 24 10:19 tesh.sh
[root@localhost scripts]# sh tesh.sh
Hello World!!
zhx
其他执行脚本方式
[root@localhost scripts]# echo useradd test|bash
[root@localhost scripts]# id test
uid=1000(test) gid=1000(test) groups=1000(test)
[root@localhost scripts]# cat 1.txt
ls
[root@localhost scripts]# cat 1.txt |bash
1.txt name.sh tesh.sh
[root@localhost scripts]# sh < 1.txt
1.txt name.sh tesh.sh
四、shell脚本基础变量
1.什么是变量
用一个固定的值表示不固定的值称为变量
IP=10.0.0.31
IP=10.0.0.51
X=1 y=x+1
在变量中 x和y 都是变量的名称 后面就是变量的值= 是赋值的意义
变量的种类
环境变量=(全局变量) 全局生效 类似国家的法律 针对所有的shell
环境变量=(局部变量) 局部生效 类似家规 针对指定的shell脚本
变量的生存周期的分类:
永久性:写入/etc/profile 或者脚本中
[root@localhost scripts]# grep ‘export name=zhx’ /etc/profile
export name=zhx ---------------------针对所有的父shell子shell生效
如何让新加到/etc/profile中的变量生效
1)退出重连
2)使用. 或者source
临时性:在当前的命令行中直接定义的变量
2.系统变量的生效顺序
1)系统环境变量都是大写
2)查看使用env 搜索 或者使用set
执行顺序:
1)/etc/profile
2).bash_profile
3)~/.bashrc
4)/etc/bashrc
生效顺序:谁在最后谁生效,后面的会覆盖前面的变量 重复赋值
3.定义环境变量
变量名定义
1)字母 数字 下划线的组合
2)使用字母或者下划线开头
3)不允许使用数字开头
4)等号两端不允许有空格
5)变量尽量不要使用命令
6)见名知其义
[root@localhost ~]# name=oldboy
[root@localhost ~]# echo $name
oldboy
[root@localhost ~]# _name=oldboy
[root@localhost ~]# echo $name
oldboy
[root@localhost ~]# 1name=oldboy
-bash: 1name=oldboy: command not found
名称写法 :
系统写法大写 USER BASH
全部小写
name_age
全部大写
NAME_AGE
大驼峰语法
Name_Age
小驼峰写法
name_Age
注意:所有的变量可被所有的命令直接调用
shell脚本中超过两条相同的内容 定义为变量
变量值定义:
三种定义的定义:
1.数字的定义
age=18 ----------------------------连续的数字 如果不连续必须加引号
[root@localhost ~]# age=19
[root@localhost ~]# echo $age
19
[root@localhost ~]# age=1 10
-bash: 10: command not found
[root@localhost ~]# age='1 20'
[root@localhost ~]# echo $age
1 20
[root@localhost ~]# for i in $age;do echo $i;done
1
20
[root@localhost ~]# age='1 20 30 40 50'
[root@localhost ~]# echo $age
1 20 30 40 50
[root@localhost ~]# for i in $age;do echo $i;done
1
20
30
40
50
2.字符串定义
name=zhx
dir=/test
mkdir echo /test
3.命令的定义
错误的写法:
[root@localhost ~]# time='date +%F'
[root@localhost ~]# echo $time
date +%F
[root@localhost ~]# time="date +%F"
[root@localhost ~]# echo $time
date +%F
正确的写法:
注意:时间的变化不会发生变化
[root@localhost ~]# time=`date +%F`
[root@localhost ~]# echo $time
2022-07-24
[root@localhost ~]# time=$(date +%F)
[root@localhost ~]# echo $time
2022-07-24
[root@localhost ~]# date +%F-%S
2022-07-24-31
[root@localhost ~]# time=`date +%F-%S`
[root@localhost ~]# echo $time
2022-07-24-49
[root@localhost ~]# echo $time
2022-07-24-49
[root@localhost ~]# echo $time
2022-07-24-49
时间发生变化:
[root@localhost ~]# time='date +%F-%S'
[root@localhost ~]# echo $time
date +%F-%S
[root@localhost ~]# echo `$time`
2022-07-24-21
[root@localhost ~]# echo `$time`
2022-07-24-23
[root@localhost ~]# echo `$time`
2022-07-24-24
[root@localhost ~]# echo `$time`
2022-07-24-25
注意:单引号和双引号中的变量值都是普通的字符串
不加引号和加双引号类似 都可以解析变量
单引号 所见即所得 定义的什么 输出的是什么
[root@localhost ~]# echo $name
oldboy
[root@localhost ~]# time='$name_date+%F-%H-%M-%S'
[root@localhost ~]# echo $name
oldboy
[root@localhost ~]# echo $time
$name_date+%F-%H-%M-%S
[root@localhost ~]# time="$name_date+%F-%H-%M-%S"
[root@localhost ~]# echo $time
+%F-%H-%M-%S
[root@localhost ~]# time="$name date+%F-%H-%M-%S"
[root@localhost ~]# echo $time
oldboy date+%F-%H-%M-%S
[root@localhost ~]# time="{$name}_date+%F-%H-%M-%S"
[root@localhost ~]# echo $time
{oldboy}_date+%F-%H-%M-%S
[root@localhost ~]# time="${name}_date+%F-%H-%M-%S"
[root@localhost ~]# echo $time
oldboy_date+%F-%H-%M-%S
定义变量:加export 和不加export区别
不加export 只对当前打开的窗口的父shell或者子shell生效
加上export 只对当前打开窗口的所有的shell生效
五 、shell核心变量
$0 表示当前的脚本名称 加上全路径则表示带路径的脚本名称
$n 脚本的第n个参数 n为数字 0是脚本名称 所有从1开始 1是脚本的第一个参数
$9 以后需要加上花括号 { } 作为一个整体
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
. /server/scripts/name.sh
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
echo $0
[root@localhost scripts]# sh tesh.sh
Hello World!!
tesh.sh
[root@localhost scripts]# sh /server/scripts/tesh.sh
Hello World!!
/server/scripts/tesh.sh
grep只查找$0的字符串 而不是变量的使用单引号
只获取脚本名称 如果全路径执行也是获取不带路径的脚本名称
[root@localhost scripts]# /etc/init.d/network
Usage: /etc/init.d/network {start|stop|status|restart|force-reload}
[root@localhost scripts]# grep $0 /etc/init.d/network
^C
[root@localhost scripts]# grep ‘$0’ /etc/init.d/network
$0 stop
$0 start
echo $“Usage: $0 {start|stop|status|restart|force-reload}”
$n 脚本的第n个参数 n为数字 0是脚本名称 所有从1开始 1是脚本的第一个参数
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
. /server/scripts/name.sh
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
echo $1
[root@localhost scripts]# sh tesh.sh
Hello World!!
[root@localhost scripts]# sh tesh.sh zhx
Hello World!!
zhx
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
. /server/scripts/name.sh
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
echo $1
echo $1
[root@localhost scripts]# sh tesh.sh zhx zhuixin
Hello World!!
zhx
zhx
$9 以后需要加上花括号{ } 作为一个整体
[root@localhost scripts]# cat tesh.sh
#!/bin/bash
. /server/scripts/name.sh
#Author zhx
#Version V1.O
#QQ 1105816259
print Hello world!
输出世界你好
echo “Hello World!!”
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
[root@localhost scripts]# sh tesh.sh {a…z}
Hello World!!
a b c d e f g h i j k