Day...1

大纲

基础变量 bash

shell执行方式 if判断 for循环 while循环 until循环

条件控制语句 exit continue break 函数 数组

1.Shell可以做什么?

1)安装操作系统 CentOS6.X 、CentOS7.X 手动方式安装 克隆方式

自动化安装、cobbler、kickstart 底层都是shell脚本实现

2)shell脚本可以优化

优化SSH、关闭Selinux、优化防火墙(Firewalld)、放行Nginx(80)、HTTPS(443)、SSH端口、zabbix监控(10051)数据库Mysql仅本地连接(127.0.0.1)、企业与个人需求放行的端口、加大文件描述符、时间同步(硬件时间clock、软件时间date)、默认YUM源......

3)安装服务

Nginx、Apache、Tomcat、PHP、MySQL、Redis、Mongo、docker.....

集群中,即有安装PHP5.4又有安装PHP7.1,可以写入shell脚本,自动化安装不同版本的服务

4)代码上线

shell脚本自动化发布、自动化回滚

5)zabbix监控

硬件、软件、进程、端口号、自定义监控......---> shell脚本+定时任务

6)日志分析

日志统计--->三剑客+定时任务+shell脚本

日志展示--->ELK

7)业务层面shell编写业务框架

8)辅助开发程序

python nohup python3.5 test.py & nohup.out 大量的日志,辅助清空

2.Shell用到的基础知识

1)vim编辑器快捷键

2)Linux常用命令,60个左右

3)三剑客 awk sed grep find

4)xshell、Crt 连接工具

鼠标Xshell粘贴快捷键

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执行命令,执行完,使用者退出,bash结束

非交互式: 把命令写入到文件中,bash执行文件中的内容,执行到末尾 bash结束

通过xshell登录到系统中,当前的位置属于父shell,所有的文件在执行时调用子shell执行,执行结束子shell退出

6.Shell脚本

命令的堆积

将命令写入到一个文本中 shell脚本 语法格式 if判断 for循环 while 函数 数组......

7.Shell脚本入门、规范

1)脚本统一存放固定的目录 /server/scripts ,统一化是为自动化铺垫

2)脚本命令结尾以.sh结尾,LINUX中的后缀给自己看,区分文件用

3)shell脚本的开头 写解释器 #!/bin/bash或#!/bin/sh

# sh 为 bash 的软连接
[root@shell:~]# ll /bin/bash
-rwxr-xr-x. 1 root root 964536 Apr  1  2020 /bin/bash
[root@shell:~]# ll /bin/sh
lrwxrwxrwx. 1 root root 4 Aug 26 01:35 /bin/sh -> bash

4)脚本最好有注释、说明 #Author 时间 电话 QQ...

5)说明尽量用英文,最好用中文

6)成对的符号、循环语句一次性书写完毕

8.第一个shell脚本

[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo "Hello World!" 

执行脚本的三种常用的方式:

注意:子shell生命周期特别短暂,父shell相当于在命令行输入

1.bash或sh方式,通过解释器执行脚本--->在子shell中执行命令

[root@shell /server/scripts]# sh test.sh 
Hello World!
[root@shell /server/scripts]# bash test.sh 
Hello World!

2.路径方式 全路径或当前路径,必须给x权限,开机自动加载一个shell脚本 /etc/rc.local--->在子shell中执行命令

[root@shell /server/scripts]# chmod +x test.sh
[root@shell /server/scripts]# /server/scripts/test.sh
Hello World!
[root@shell /server/scripts]# ./test.sh
Hello World!

3.source或 . 方式--->在父shell中执行命令

[root@shell /server/scripts]# . test.sh 
Hello World!
[root@shell /server/scripts]# source test.sh
Hello World!

4.子shell与父shell证明,子shell调用周期特别短暂,调用结束失效,父shell调用时间长

[root@shell ~]# cat 1.sh
#!/bin/bash
name=majunnan
[root@shell ~]# sh 1.sh             # 在子shell中执行
[root@shell ~]# echo $name          # 显示变量
                                       # 空                                        

[root@shell ~]# source 1.sh         # 在父shell中执行
[root@shell ~]# echo $name          # 显示变量
majunnan

5.使用其他shell的执行方式

[root@shell /server/scripts]# cat test.sh
pwd
[root@shell /server/scripts]# cat test.sh|bash
/server/scripts
[root@shell /server/scripts]# echo ls
ls
[root@shell /server/scripts]# echo ls|bash
test.sh

# 读入的方式,把文件中的内容传入到bash中,一行一行读取,一边读取,一边执行
[root@shell /server/scripts]# bash < test.sh
/server/scripts

9.shell的变量基础

什么是变量?

用一个固定的字符串表示不固定的值,称为变量

 

变量的种类: 查看全局变量 env

环境变量(全局变量) 针对全局生效,对所有的shell生效,例:PS1、PATH、LANG

普通变量(局部变量) 针对当前某个shell生效

 

按照生命周期区分:

永久的: 写入/etc/profile,每次使用xshell连接系统,都会自动加载/etc/profile

临时的: 使用export声明即可

添加export区别: 对当前打开窗口的所有shell生效 (无论父shell、子shell)

不加export区别: 只对当前的shell生效(即使父shell,资源也无法下发)

[root@shell ~]# age=18           # 只对当前父shell有效
[root@shell ~]# echo $age
18
[root@shell ~]# cat 1.sh 
echo $age
[root@shell ~]# sh 1.sh 
                            空   # 只对上面的父shell生效,未对当前子shell生效
[root@shell ~]# export name=nn   # 对当前打开的所有窗口生效
[root@shell ~]# echo $name
nn
[root@shell ~]# cat 2.sh
echo $name
[root@shell ~]# sh 2.sh
nn
[root@shell ~]# echo $name      # 另开一台xshell窗口,$name未生效
                            空

案例: rsync -avz hosts rsync_backup@10.0.0.41::backup

rsync的内置变量 RSYNC_PASSWROD 区别 export RSYNC_PASSWROD
前第一个仅对父shell生效,父shell下发子shell任务,子shell中仍无法调用变量
后第二个当前所有shell生效,子shell工作时,可以调用变量

 

和环境变量相关的文件:内置变量生效有先后顺序
变量的执行加载顺序不一定是生效顺序,变量最后定义的优先生效,因为重复赋值原因
1./etc/profile
2..bash_profile   家目录中的隐藏文件
3..bashrc            家目录中的隐藏文件
4./etc/bashrc

10.定义环境变量name=nn

变量名称的定义方式: 要求字符串、下划线、数字的组合,下划线或者字符串开头,不能以数字开头
[root@shell ~]# _name=nn
[root@shell ~]# echo $_name
nn
[root@shell ~]# 1name=mm
-bash: 1name=mm: command not found
*名称见名知其意,等号两端不允许有空格
变量名称的书写方式:
NAME_AGE=  全大写 系统默认的变量都是大写
Name_Age   大驼峰语法
name_Age   小驼峰语法
name_age   全小写
变量值的定义:
三种值:

1.字符串定义:必须是连续的字符串,值不允许有空格

双引号和单引号的区别:双引号解析变量,单引号所见即所得,不能解析变量,不加引号可以解析变量

[root@shell ~]# name=majunnan            # 连续,不允许有空格
[root@shell ~]# name='I am majunnan'     # 使用单引号,允许有空格
[root@shell ~]# echo $name
I am majunnan
[root@shell ~]# name="I am majunnan"     # 使用双引号,允许有空格
[root@shell ~]# echo $name
I am majunnan
2.数字的定义:
[root@shell ~]# age="12 23 432"
[root@shell ~]# echo $age
12 23 432
3.命令的定义:使用`` $()
[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                  # 不会变,time成为定值,调用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
如果脚本设置变量为time=`date +%F-%H:%M`, 那么在后面脚本使用$time过程中,时间变量的值不会变,因为脚本从上往下执行,第一遍执行的时候就会执行反引号`date+%F`中的命令,然后将结果赋值给time,所以后面再调用$time的值不会发生改变,相反,如果脚本开始定义time=‘date +%F’,在后面脚本中调用时使用`$time`会再次执行date命令,则每次的时间都会不一样

时间是固定,每次调用时间都相同

[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 ~]# sh 1.sh
2022-09-05-14-57-14
2022-09-05-14-57-16
变量可以定义变量
[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                    # IP没有,没办法分辨IP与时间
[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条以上相同的命令,写成变量

11.核心位置变量

$0 获取shell脚本的名称,执行如果带全路径,则$0带全路径*****

$n n为数字,从1开始,$1为脚本的第一个参数,从$9往后,需要加${10} *****

$# 获取脚本传参的总个数,针对传入的个数进行判断*****

$* 获取脚本传参的所有的参数,在循环体中不同,加上双引号视为单个字符串

$@ 获取脚本传参的所有的参数,在循环体中不同,加上双引号视为独立参数

$? 获取上一条命令的返回值,0为成功,非0失败*****

$$ 获取脚本的PID进程号,当有多个相同名称的shell环境中使用**

$! 获取上一个在后台运行脚本的PID号,测试常用**

$_ 获取脚本的最后一个参数或是某个东西 类似esc .

 

$0:获取shell脚本名称

[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo $0
[root@shell /server/scripts]# sh test.sh
test.sh
[root@shell /server/scripts]# /server/scripts/test.sh
/server/scripts/test.sh
# 让脚本给予提示,如何使用脚本
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
echo $0
echo $"Usage: $0 {start|stop|status|restart|force-reload}"

$0在Linux脚本中的使用方法:

[root@shell /server/scripts]# /etc/init.d/network 
Usage: /etc/init.d/network {start|stop|status|restart|force-reload}

# 过滤$0,使用撬棍转译或单引号所见即所得,不让他代表特殊含义 [root@shell /server/scripts]# grep \$0 /etc/init.d/network $0 stop $0 start echo $"Usage: $0 {start|stop|status|restart|force-reload}" [root@shell /server/scripts]# grep '$0' /etc/init.d/network $0 stop $0 start echo $"Usage: $0 {start|stop|status|restart|force-reload}"

basename 只获取脚本的名称

[root@shell /server/scripts]# basename /server/scripts/test.sh
test.sh

$n 脚本的参数:

[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
echo $1
[root@shell /server/scripts]# sh test.sh mm
mm
[root@shell /server/scripts]# sh test.sh mm jj nn
mm

序列传参:从$9往后,需要加${10}

[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
echo $3
[root@shell /server/scripts]# sh test.sh {A..Z}
C
[root@shell /server/scripts]# sh test.sh {1..10}
3
[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11
[root@shell /server/scripts]# sh test.sh {a..z}
a b c d e f g h i a0 a1                       # 出现错误,只能识别$1

[root@shell /server/scripts]# cat test.sh     # 加上{},使10、11成为一体
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
[root@shell /server/scripts]# sh test.sh {a..z}
a b c d e f g h i j k

$#获取脚本传参的总个数:

[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11}
echo $#
[root@shell /server/scripts]# sh test.sh a b c
a b c
3
[root@shell /server/scripts]# sh test.sh {a..z}
a b c d e f g h i j k
26
[root@shell /server/scripts]# sh test.sh {1..10000}
1 2 3 4 5 6 7 8 9 10 11
10000
[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo name=$1
echo age=$2
[root@shell /server/scripts]# sh test.sh mm 18
name=mm                               # 此时显示mm只是代表字符串,未对name进行赋值
age=18                                # 此时显示18也只是代表字符串,未对age进行赋值
[root@shell ~]# [ 10 -eq 10 ]               # 10等于10 

[root@shell ~]# echo $?                     # 查看运行的结果,如果结果返回等于0,则上一条运行结果成立
0
[root@shell ~]# [ 10 -ne 10 ]               # 10不等于10
[root@shell ~]# echo $?                     # 查看运行的结果,如果结果返回不等于0,则上一条运行结果不成立
1
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
[ $# -ne 2 ] && echo "请输入两个参数" && exit   # 参数总个数不为2,输出文字并退出
echo name=$1
echo age=$2
[root@shell /server/scripts]# sh test.sh test  # 输入一个参数时,输出文字,退出
请输入两个参数
[root@shell /server/scripts]# sh test.sh test 18
name=test
age=18

$* $@:获取脚本传参的所有参数

[root@shell /server/scripts]# cat test.sh
name=$1
age=$2
$*
$@
[root@shell /server/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 /server/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 /server/scripts]# set -- "I am" majunnan    # 设置变量
[root@shell /server/scripts]# echo $*
I am majunnan
[root@shell /server/scripts]# echo $@
I am majunnan
[root@shell /server/scripts]# echo "$@"
I am majunnan
[root@shell /server/scripts]# echo "$*"
I am majunnan
[root@shell /server/scripts]# for i in $*;do echo $i;done
I
am
majunnan
[root@shell /server/scripts]# for i in $@;do echo $i;done
I
am
majunnan
[root@shell /server/scripts]# for i in "$*";do echo $i;done
I am majunnan                            # 加双引号,视为单个字符串
[root@shell /server/scripts]# for i in "$@";do echo $i;done
I am                                     # 加双引号,视为独立个体
majunnan

$?:获取上一条命令的返回值

[root@shell /server/scripts]# ll
[root@shell /server/scripts]# echo $?
0
[root@shell /server/scripts]# llllllllllllll
bash: llllllllllllll: command not found
[root@shell /server/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 通的

$$ 获取脚本的PID进程号,当有多个相同名称的shell环境中使用

[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
echo $$                      # 显示当前进程PID,当多人登录使用一个服务时,可知自己进程PID
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
echo $$ > /tmp/nginx_pid     # 将当前的PID号写入文本中,可查看确定自己使用的服务

$! 获取上一个在后台运行脚本的PID号,测试常用**

[root@shell ~]# cat test.sh 
#!/bin/bash
echo $$ > /tmp/nginx_pid
[root@shell ~]# sh test.sh
[root@shell ~]# kill -9 $!
kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]

$_ 获取脚本的最后一个参数或是某个东西 类似esc .

[root@shell ~]# ll 1234567 89 10
ls: cannot access 1234567: No such file or directory
ls: cannot access 89: No such file or directory
ls: cannot access 10: No such file or directory
[root@shell ~]# echo $_                                 # 上一行输入最后一个是10,所以取10
10

12.脚本传参的三种方式

第一种方式:直接传参

[root@shell /server/scripts]# cat test.sh
#!/bin/bash
echo $1 $2
[root@shell /server/scripts]# sh test.sh mm 100
mm 100

第二种方式:赋值传参

[root@shell /server/scripts]# cat test.sh
#!/bin/bash
name=$1
age=$2
echo $name
echo $age
[root@shell /server/scripts]# sh test.sh mm 200
mm
200
[root@shell /server/scripts]# cat test.sh
#!/bin/bash
name=$1
age=$2
echo 姓名: $name
echo 年龄: $age
[root@shell /server/scripts]# sh test.sh nn 100
姓名: nn
年龄: 100

第三种方式:read读入,交互式

[root@shell /server/scripts]# read name
nn                                     # 写入nn
[root@shell /server/scripts]# echo $name
nn                                     # 出现nn
[root@shell /server/scripts]# read -p "请输入你的姓名" name
请输入你的姓名nn                        # 写入nn
[root@shell /server/scripts]# echo $name
nn                                     # 出现nn
[root@shell /server/scripts]# read -p "请输入你的姓名: " name
请输入你的姓名: HEHE                   # 写入HEHE
[root@shell /server/scripts]# echo $name
HEHE                                  # 出现HEHE
read第一种书写方式:一个一个
[root@shell /server/scripts]# cat test.sh
#!/bin/bash
read -p "请输入你的姓名: " name 
read -p "请输入你的年龄: " age
echo name=$name
echo age=$age 
[root@shell /server/scripts]# sh test.sh
请输入你的姓名: hehe       # 书写
请输入你的年龄: 1          # 书写
name=hehe                 # 显示
age=1                     # 显示
read第二种书写方式:一起
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
read -p "请输入你的姓名和年龄: " name age 
echo name=$name
echo age=$age 
[root@shell /server/scripts]# sh test.sh
请输入你的姓名和年龄: nn 20        # 书写
name=nn                          # 显示
age=20                           # 显示
[root@shell /server/scripts]# cat test.sh 
#!/bin/bash
read -p "输入要备份的目录: " dir
tar zcf test.tar.gz $dir
[root@shell /server/scripts]# sh test.sh
输入要备份的目录: /etc
[root@shell /server/scripts]# ll

-rw-r--r-- 1 root root        86 Jul 20 20:23 test.sh
-rw-r--r-- 1 root root  11571902 Jul 20 20:23 test.tar.gz

13.小结

1.学习shell

2.基础知识

3.规范

4.语言种类

5.shell执行的三种方式

6.变量分类 export区别 变量相关的文件

7.变量的定义 名字定义 值的定义 命令的定义

8.核心位置变量 $0 $n $# $?

9.传参的三种方式 直接传参 赋值传参 read读入 

——————————————————————————————————————————————————————————————————————————

                                                                                                                         无敌小马爱学习

posted on 2024-09-18 17:32  马俊南  阅读(3)  评论(0编辑  收藏  举报