Shell-day01
1. Shell的课程大纲
Shell脚本必须要会,并且要精通。
1. Shell的基本概述
2. Shell的变量
3. Shell的数值运算
4. Shell的流程控制 if ;then fi
5. Shell的循环语句 for while
6. Shell的数组函数
7. Shell的正则表达式
Grep Sed Awk 命令的使用 Awk数组
8. Shell练习题 100多道练习题
2. 什么是Shell
Shell是一个命令解释器
Shell分为交互式和非交互式
$- 通过此变量可以获取到你的Shell的执行方式是交互式还是非交互式
[root@shell ~]
himBH
[root@shell ~]
[root@shell ~]
echo $-
[root@shell ~]
hB
h hashall
i interactive
m monitor
B braceexpand
H history
3. 什么是Shell脚本
1. 系统的命令的堆积,按照顺序执行
2. 特定的格式 + 特定的语法 + 系统的命令 = 文件
3. 建议以.sh为结尾 .py
4. 为什么要学习Shell编程
运维人员必须要会
提升你的工作效率
减少不必要的重复性的工作
5. 学习Shell编程需要哪些知识
1. 对vim能够熟练的使用 熟悉.vimrc的配置
2. 要有linux的命令基础, 至少要掌握80个以上的常用命令并能够熟练使用
3. 要熟练掌握正则表达式及三剑客命令
4. 熟练常见的服务上面的配置 服务部署 优化 日志分析 排错
6. 如何学习好Shell
1. 阅读、模仿、阅读、模仿
2. 核心: 多练 多思考 坚持
3. 掌握Shell脚本的常见语法
4. 形成自己的脚本风格
5. 从简单做起,简单判断,简单循环
6. 学会分析问题,逐渐的形成编程思维
7. 变量名要规范,采用驼峰式语法 HostIp=xxx Host_Ip=xxx
8. 不要拿来主义,特别是针对新手
7. Shell脚本能干什么
1. 基础的配置 系统的初始化 系统更新 内核调整 网络 时区 优化
2. 安装软件程序 LNMP LAMP Nginx PHP MySQL Redis Rsync NFS
3. 配置的变更 Nginx PHP Redis MySQL conf 配置文件的变更
4. 业务的部署 Shell配合Git、jenkins实现自动化的部署 代码上线 回滚
5. 日常备份 脚本备份+定时任务 企业的备份
6. 信息采集 Zabbix监控 + Shell取值 对硬件 系统状态 服务
7. 日志分析 ELK 取值 排序 去重 统计 分析
8. 服务的扩容或者缩容
扩容: 添加集群节点 监控CPU 负载 内存 >80% 触发的动作 脚本
缩容: 减少集群节点 监控CPU 负载 内存 <20% 触发的动作 把某一个节点进行移除
8. Shell脚本的规范及习惯
1. 脚本放在统一的一个目录
/service/scripts/
2. 推荐使用vim进行编辑脚本 高亮显示
3. 以.sh为结尾
4. 脚本的第一行加上幻数 指定哪一个命令解释器进行解释脚本的命令
5. 开头的
6. 写脚本的时候附带作者和版权信息
7. 脚本注释
8. 成对的符号,要一次书写完成 "" {} '' []
9. 成对的语法格式,要一次书写完成 if ;then fi for i in do done
shell种类
[root@shell ~]
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
[root@shell ~]
total 72
-rw-r--r--. 1 root root 771 2018-10-31 06:57 256term.csh
-rw-r--r--. 1 root root 841 2018-10-31 06:57 256term.sh
-rw-r--r--. 1 root root 660 2014-06-10 08:05 bash_completion.sh
-rw-r--r--. 1 root root 196 2017-03-25 00:39 colorgrep.csh
-rw-r--r--. 1 root root 201 2017-03-25 00:39 colorgrep.sh
-rw-r--r--. 1 root root 1741 2018-10-30 22:37 colorls.csh
-rw-r--r--. 1 root root 1606 2018-10-30 22:37 colorls.sh
-rw-r--r-- 1 root root 185 2020-04-20 17:07 color.sh
-rw-r--r--. 1 root root 80 2018-10-31 03:48 csh.local
-rw-r--r--. 1 root root 1706 2018-10-31 06:57 lang.csh
-rw-r--r--. 1 root root 2703 2018-10-31 06:57 lang.sh
-rw-r--r--. 1 root root 123 2015-07-31 08:47 less.csh
-rw-r--r--. 1 root root 121 2015-07-31 08:47 less.sh
-rw-r--r--. 1 root root 81 2018-10-31 03:48 sh.local
-rw-r--r--. 1 root root 105 2019-08-09 11:17 vim.csh
-rw-r--r--. 1 root root 269 2019-08-09 11:17 vim.sh
-rw-r--r--. 1 root root 164 2014-01-28 04:47 which2.csh
-rw-r--r--. 1 root root 169 2014-01-28 04:47 which2.sh
centos中的shell种类 (实际上是一种shell 它们之间是软链接关系)
root@shell /usr/bin]# ll
lrwxrwxrwx. 1 root root 4 2020-02-11 23:00 sh -> bash
[root@shell /bin]
total 119828
lrwxrwxrwx. 1 root root 4 2020-02-11 23:00 sh -> bash
9. Shell脚本的执行方式
Shell脚本是从上到下、从左到右依次执行每一行的命令 执行完一条命令之后,再执行下一条命令。如果在脚本中遇到镶嵌脚本(子脚本)时,先执行子脚本,执行子脚本之后再去执行父脚本剩下的内容
执行方式:
1. bash script-name 或者 sh script-name
[root@shell /service/scripts/day01]
[root@shell ~]
systemd─┬─VGAuthService
├─abrt-watch-log
├─abrtd
├─agetty
├─auditd───{auditd}
├─crond
├─dbus-daemon
├─master─┬─pickup
│ └─qmgr
├─polkitd───6*[{polkitd}]
├─rpcbind
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───bash───sh───ping
│ └─sshd───bash───pstree
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
└─vmtoolsd───{vmtoolsd}
[root@shell ~]
[root@shell /service/scripts/day01]
hostname
[root@shell /service/scripts/day01]
shell
[root@shell /service/scripts/day01]
shell
[root@shell /service/scripts/day01]
-rw-r--r-- 1 root root 21 2020-04-20 11:28 test.sh
[root@shell /service/scripts/day01]
ping baidu.com &>/dev/null
[root@shell ~]
root 7976 0.0 0.0 149968 1984 pts/0 S+ 11:29 0:00 ping baidu.com
[root@shell ~]
root 7975 0.0 0.0 113176 1196 pts/0 S+ 11:29 0:00 sh test.sh
2. source script-name 或者 . script-name
[root@shell /service/scripts/day01]
systemd─┬─VGAuthService
├─abrt-watch-log
├─abrtd
├─agetty
├─auditd───{auditd}
├─crond
├─dbus-daemon
├─master─┬─pickup
│ └─qmgr
├─polkitd───6*[{polkitd}]
├─rpcbind
├─rsyslogd───2*[{rsyslogd}]
├─sshd─┬─sshd───bash───pstree
│ └─sshd───bash───ping
├─systemd-journal
├─systemd-logind
├─systemd-udevd
├─tuned───4*[{tuned}]
└─vmtoolsd───{vmtoolsd}
[root@shell ~]
root 8074 0.0 0.0 112708 976 pts/1 R+ 11:33 0:00 grep --color=auto source
[root@shell ~]
root 8070 0.0 0.0 149968 1984 pts/0 S+ 11:33 0:00 ping baidu.com
3. path/script-name 或者 ./script-name
[root@shell /service/scripts/day01]
-bash: ./test.sh: Permission denied
[root@shell /service/scripts/day01]
-bash: /service/scripts/day01/test.sh: Permission denied
[root@shell ~]
root 8099 0.0 0.0 149968 1984 pts/0 S+ 11:39 0:00 ping baidu.com
root 8103 0.0 0.0 112708 976 pts/1 S+ 11:39 0:00 grep --color=auto ping
[root@shell ~]
root 8098 0.0 0.0 113176 1192 pts/0 S+ 11:39 0:00 /bin/bash /service/scripts/day01/test.sh
root 8105 0.0 0.0 112708 976 pts/1 R+ 11:39 0:00 grep --color=auto test
4. cat script-name | bash
[root@shell ~]
root 8124 0.0 0.0 112708 976 pts/1 R+ 11:42 0:00 grep --color=auto test
[root@shell ~]
root 8122 0.0 0.0 149968 1984 pts/0 S+ 11:42 0:00 ping baidu.com
root 8126 0.0 0.0 112708 972 pts/1 R+ 11:42 0:00 grep --color=auto ping
5. bash < script-name 或者 sh < script-name
[root@shell ~]
root 8130 0.0 0.0 149968 1992 pts/0 S+ 11:43 0:00 ping baidu.com
root 8132 0.0 0.0 112708 976 pts/1 R+ 11:43 0:00 grep --color=auto ping
[root@shell ~]
root 8134 0.0 0.0 112708 976 pts/1 R+ 11:43 0:00 grep --color=auto test
10. 登录式Shell和非登录式Shell
登录式Shell 通过用户和密码的方式进行登录进入的Shell
非登录式Shell 不需要用户和密码的方式进入的Shell bash
执行exit命令时, 可以退出登录式Shell和非登录式hell
执行logout命令时, 只能退出登录式Shell,不能退出非登录式Shell
脚本就是一个非登录式Shell
非登录式Shell不会执行/etc/profile这个文件
配置文件的执行顺序
/etc/profile
/etc/profile.d/*sh
/root/.bash_profile
/etc/bashrc
/root/.bashrc
登录式Shell的配置文件执行顺序
/etc/profile
/etc/profile.d/*sh
.bash_profile
.bashrc
/etc/bashrc
非登录式Shell的配置文件的执行顺序
[root@shell ~]
.bashrc
/etc/bashrc
/etc/profile.d/*sh
11. Shell的变量介绍
什么是变量
就是传递数据的一种方法,
简单理解: 用一个固定的字符串去表示一个不固定的内容,便于后期引用
变量名的规范
采用驼峰法书写
变量的名称不要跟系统中的命令或者变量有冲突
名称要求: 字母、数字、下划线组成 尽量使用字母开头,变量名称最好具有一定的含义
ip=10.0.0.80
IP=xxxx
ip1=10.0.0.80
hostip=xxx
Hostip=xxxx
HostIp=xxxx
Host_Ip=xxxx
host_ip=xxxxxx
前面是变量名称 = 等号是赋值 后面的就是定义的值 等号两边不能存在空格。
变量的定义方式
1、用户自定义变量: 用户自己定义的变量
2、系统环境变量: 系统已经定义好的变量,变量记录的是操作系统的一些信息 全部是由大写字母组成的
全局变量 和 局部变量
3、位置参数变量: 向脚本中进行传递参数,变量名不能自己定义,变量的作用也是固定的 $1 $2
4、预定义变量: bash已经定义好的变量,变量名不能自己定义,变量的作用也是固定的,值不是自己设置的 $@ $* $? $0
12. 变量的定义实践
1. 用户自定义变量,只在当前环境生效
[root@shell ~]
[root@shell ~]
-bash: qiudao: command not found
[root@shell ~]
[root@shell ~]
-bash: Name-1=qls: command not found
[root@shell ~]
[root@shell ~]
-bash: 1Name=qls: command not found
[root@shell ~]
qls qiudao
[root@shell ~]
qls qiudao
[root@shell ~]
[root@shell ~]
[root@shell ~]
qls qiudao_age
[root@shell ~]
[root@shell ~]
10%
set
[root@shell ~]
Name='qls qiudao'
[root@shell ~]
[root@shell ~]
root
unset
[root@shell ~]
[root@shell ~]
[root@shell ~]
[root@shell ~]
单双引号和不加引号及反引号的区别
反引号,先执行反引号里面的命令,将执行的结果交给外面的命令 里面必须是命令
[root@shell ~]
[root@shell ~]
shell
[root@shell ~]
[root@shell ~]
shell
单引号 强引用 单引号里面是什么,得到的也是什么
[root@shell ~]
[root@shell ~]
$(hostname)
双引号 弱引用 里面是什么内容,也会得到什么内容 但是他会解析变量 解析特殊字符
[root@shell ~]
[root@shell ~]
shell
不加引号 当变量的值出现空格时,不会将值看做是一个整体,不支持通配符
[root@shell ~]
-bash: qiudao: command not found
[root@shell ~]
[root@shell ~]
1 2 3 4 5 6 7 8 9 10
[root@shell ~]
{1..10}
[root@shell ~]
[root@shell ~]
hj
[root@shell ~]
hj money is 0000000000
[root@shell ~]
hj money is 0000000000
[root@shell ~]
$Name money is $10000000000
[root@shell ~]
hj money is $10000000000
[root@shell ~]
hj money is $10000000000
[root@shell ~]
hj money is $10000000000
系统环境变量 全局生效的
如何自定义环境变量 ,在当前环境下和子shell环境下生效
[root@shell ~]
[root@shell ~]
qls
[root@shell ~]
[root@shell ~]
echo $Name
[root@shell ~]
[root@shell ~]
[root@shell ~]
qls
[root@shell ~]
qls
使用export命令只能在当前环境下和当前环境下的子shell环境生效,但是export命令设置的变量只能临时生效,退出登录后再次登录变量会失效。
只有将变量写入到环境变量配置文件中,才会全局生效 当前用户和所有用户生效
[root@shell ~]
root
[root@shell ~]
0
[root@shell ~]
/root
[root@shell ~]
shell
[root@shell ~]
/root
[root@shell ~]
[root@shell /opt]
/opt
[root@shell /opt]
/bin/bash
位置变量
[root@shell ~]
echo $1 $2 $4
[root@shell ~]
[root@shell ~]
1 2
[root@shell ~]
1 2 4
$1 $2 $3 .. $N ${10} 位置变量出现两位数的时候,需要使用花括号括起来
预定义的变量
$0 $* $@ $# $? $$
[root@shell /service/scripts/day01]
echo "当前Shell的脚本文件名为:$0"
echo "当前Shell运行的PID号为:$$"
echo "当前Shell的第一个位置变量为:$1"
echo "当前Shell的第二个位置变量为:$2"
echo "当前Shell的第三个位置变量为:$3"
echo "当前传递的所有位置参数为:$*"
echo "当前传递的所有位置参数为:$@"
echo "当前总共传递的位置参数的个数为:$#"
echo "上条命令的执行结果为:$?"
[root@shell /service/scripts/day01]
当前Shell的脚本文件名为:/service/scripts/day01/test.sh
当前Shell运行的PID号为:8932
当前Shell的第一个位置变量为:linux
当前Shell的第二个位置变量为:nginx
当前Shell的第三个位置变量为:php
当前传递的所有位置参数为:linux nginx php
当前传递的所有位置参数为:linux nginx php
当前总共传递的位置参数的个数为:3
上条命令的执行结果为:0
[root@shell /service/scripts/day01]
test() {
echo "未加引号,二者是相同的"
echo $*
echo $@
echo "加入引号对比"
for i in "$*"
do
echo $i
done
echo '###################'
for j in "$@"
do
echo $j
done
}
test linux nginx mysql
[root@shell /service/scripts/day01]
未加引号,二者是相同的
linux nginx mysql
linux nginx mysql
加入引号对比
linux nginx mysql
linux
nginx
mysql
没有加入引号之前,两者是相同的
加入引号之后呢
$* 把参数作为一个字符串整体进行输出返回
$@ 把每个参数作为一个一个字符串返回
[root@shell /service/scripts/day01]
2020-04-20
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
total 8
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls1.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls2.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls3.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls4.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls5.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls6.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls7.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls8.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls9.txt
-rw-r--r-- 1 root root 280 2020-04-20 16:11 test1.sh
-rw-r--r-- 1 root root 451 2020-04-20 16:03 test.sh
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
total 12
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls1.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls2.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls3.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls4.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls5.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls6.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls7.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls8.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls9.txt
-rw-r--r-- 1 root root 177 2020-04-20 16:19 qls.tar.gz
-rw-r--r-- 1 root root 280 2020-04-20 16:11 test1.sh
-rw-r--r-- 1 root root 451 2020-04-20 16:03 test.sh
[root@shell /service/scripts/day01]
qls1.txt
qls2.txt
qls3.txt
qls4.txt
qls5.txt
qls6.txt
qls7.txt
qls8.txt
qls9.txt
嵌套变量
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
total 12
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls1.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls2.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls3.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls4.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls5.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls6.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls7.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls8.txt
-rw-r--r-- 1 root root 0 2020-04-20 16:19 qls9.txt
-rw-r--r-- 1 root root 180 2020-04-20 16:21 qls.tar.gz
-rw-r--r-- 1 root root 280 2020-04-20 16:11 test1.sh
-rw-r--r-- 1 root root 451 2020-04-20 16:03 test.sh
[root@shell /service/scripts/day01]
[root@shell /service/scripts/day01]
./qls1.txt ./qls2.txt ./qls3.txt ./qls4.txt ./qls5.txt ./qls6.txt ./qls7.txt ./qls8.txt ./qls9.txt
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现