shell脚本知识点1

Shell-day01

1. Shell的课程大纲


Shell脚本必须要会,并且要精通。

1. Shell的基本概述

2. Shell的变量

3. Shell的数值运算

4. Shell的流程控制    ifthen  fi

5. Shell的循环语句    for  while

6. Shell的数组函数

7. Shell的正则表达式

	Grep  Sed   Awk  命令的使用     Awk数组

8. Shell练习题   100多道练习题  

2. 什么是Shell


	Shell是一个命令解释器  
	
	Shell分为交互式和非交互式
	
	$-   通过此变量可以获取到你的Shell的执行方式是交互式还是非交互式
	
#交互式
[root@shell ~]# echo  $-
himBH

#非交互式
[root@shell ~]# vim test.sh
[root@shell ~]# cat test.sh
#!/bin/bash
echo $-
[root@shell ~]# sh test.sh
hB


h		hashall     #Shell会记录你执行过的命令路径,避免每次都要查询  

i		interactive	#这个选项就是说明你是一个交互式Shell

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. 脚本的第一行加上幻数  指定哪一个命令解释器进行解释脚本的命令   #!/bin/bash   默认以bash执行   

5. 开头的#!/bin/bash   #!称之为幻数     /bin/bash 就是命令解释器   必须放在代码的第一行 在其他行都是注释

6. 写脚本的时候附带作者和版权信息  

7. 脚本注释  #后面的内容都是注释    最好不要使用中文  建议使用英文    禁止使用拼音   

8. 成对的符号,要一次书写完成   ""  {}  ''  [] 

9. 成对的语法格式,要一次书写完成  ifthen  fi    for  i  in   do  done


shell种类
[root@shell ~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

[root@shell ~]# ll /etc/profile.d/
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]# ll
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]# sh test.sh
[root@shell ~]# pstree
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 ~]# mkdir  -p  /service/scripts

[root@shell /service/scripts/day01]# cat test.sh
#!/bin/bash
hostname
[root@shell /service/scripts/day01]# bash test.sh
shell
[root@shell /service/scripts/day01]# sh test.sh
shell
[root@shell /service/scripts/day01]# ll test.sh
-rw-r--r-- 1 root root 21 2020-04-20 11:28 test.sh

[root@shell /service/scripts/day01]# cat test.sh 
#!/bin/bash
ping baidu.com &>/dev/null
# 可以通过过滤脚本中执行的命令查看进程
[root@shell ~]# ps aux | grep ping
root       7976  0.0  0.0 149968  1984 pts/0    S+   11:29   0:00 ping baidu.com
# 也可以直接过滤 命令解释器查看正在执行的脚本进程
[root@shell ~]# ps aux | grep  sh
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]# pstree
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 ~]# ps aux | grep  source
root       8074  0.0  0.0 112708   976 pts/1    R+   11:33   0:00 grep --color=auto source
[root@shell ~]# ps aux | grep  ping
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]# ./test.sh
-bash: ./test.sh: Permission denied
[root@shell /service/scripts/day01]# /service/scripts/day01/test.sh  
-bash: /service/scripts/day01/test.sh: Permission denied

[root@shell ~]# ps aux | grep ping
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 ~]# ps aux | grep  test
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 ~]# ps aux | grep  test
root       8124  0.0  0.0 112708   976 pts/1    R+   11:42   0:00 grep --color=auto test
[root@shell ~]# ps aux | grep  ping
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 ~]# ps aux | grep  ping
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 ~]# ps aux | grep  test
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 ~]# bash
.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 ~]# Name=qls
[root@shell ~]# Name=qls qiudao		#变量值出现空格时,使用引号引用起来
-bash: qiudao: command not found
[root@shell ~]# Name='qls qiudao'
[root@shell ~]# Name-1=qls			#变量名不能出现短横岗
-bash: Name-1=qls: command not found
[root@shell ~]# Name1=qls
[root@shell ~]# 1Name=qls			#不能以数字开头
-bash: 1Name=qls: command not found


#引用变量
[root@shell ~]# echo $Name
qls qiudao
[root@shell ~]# echo ${Name}
qls qiudao
[root@shell ~]# echo $Nameage

[root@shell ~]# echo $Name_age

[root@shell ~]# echo ${Name}_age
qls qiudao_age
[root@shell ~]# Num=10
[root@shell ~]# echo $Num%    #%是特殊字符可以识别
10%


#查看所有的变量
set
#显示局部变量 
[root@shell ~]# set | grep Name
Name='qls qiudao'

#显示全局变量和进程正在运行中的变量     显示系统的环境变量 
[root@shell ~]# env | grep Name
[root@shell ~]# echo $USER
root

#取消变量
unset
[root@shell ~]# Name=qls
[root@shell ~]# 
[root@shell ~]# unset  Name
[root@shell ~]# echo $Name


单双引号和不加引号及反引号的区别

反引号,先执行反引号里面的命令,将执行的结果交给外面的命令  里面必须是命令
[root@shell ~]# Name=$(hostname)
[root@shell ~]# echo $Name
shell
[root@shell ~]# Name=`hostname`
[root@shell ~]# echo $Name
shell

单引号  强引用  单引号里面是什么,得到的也是什么  
[root@shell ~]# Name='$(hostname)'
[root@shell ~]# echo $Name
$(hostname)

双引号  弱引用  里面是什么内容,也会得到什么内容  但是他会解析变量  解析特殊字符
[root@shell ~]# Name="$(hostname)"
[root@shell ~]# echo $Name
shell


不加引号   当变量的值出现空格时,不会将值看做是一个整体,不支持通配符 

[root@shell ~]# Name=qls qiudao
-bash: qiudao: command not found

[root@shell ~]# Name={1..10}
[root@shell ~]# echo {1..10}
1 2 3 4 5 6 7 8 9 10
[root@shell ~]# echo $Name
{1..10}


[root@shell ~]# Name=hj
[root@shell ~]# echo $Name
hj
[root@shell ~]# echo $Name money is $10000000000
hj money is 0000000000
[root@shell ~]# echo "$Name money is $10000000000"
hj money is 0000000000
[root@shell ~]# echo '$Name money is $10000000000'
$Name money is $10000000000
[root@shell ~]# echo $Name money is '$10000000000'
hj money is $10000000000
[root@shell ~]# echo "$Name money is \$10000000000"
hj money is $10000000000
[root@shell ~]# echo $Name money is \$10000000000
hj money is $10000000000


系统环境变量  全局生效的 

如何自定义环境变量 ,在当前环境下和子shell环境下生效
# 使用export 命令定义变量可以实现

[root@shell ~]# Name=qls
[root@shell ~]# echo $Name
qls
[root@shell ~]# vim test.sh 
[root@shell ~]# cat test.sh
#!/bin/bash
echo $Name
[root@shell ~]# sh test.sh

[root@shell ~]# export Name=qls
[root@shell ~]# echo $Name
qls
[root@shell ~]# sh test.sh 
qls

使用export命令只能在当前环境下和当前环境下的子shell环境生效,但是export命令设置的变量只能临时生效,退出登录后再次登录变量会失效。
只有将变量写入到环境变量配置文件中,才会全局生效  当前用户和所有用户生效 


[root@shell ~]# echo $USER
root
[root@shell ~]# echo $UID
0
[root@shell ~]# echo $HOME
/root
[root@shell ~]# echo $HOSTNAME
shell
[root@shell ~]# echo $PWD
/root
[root@shell ~]# cd /opt/
[root@shell /opt]# echo $PWD
/opt
[root@shell /opt]# echo $SHELL
/bin/bash

位置变量   

[root@shell ~]# cat test.sh
#!/bin/bash
echo $1 $2 $4
[root@shell ~]# sh test.sh

[root@shell ~]# sh test.sh 1 2 3 
1 2
[root@shell ~]# sh test.sh 1 2 3 4
1 2 4

$1  $2  $3 ..  $N    ${10}   位置变量出现两位数的时候,需要使用花括号括起来  


预定义的变量  

$0   $*   $@  $#  $?  $$ 

[root@shell /service/scripts/day01]# cat test.sh
#!/bin/bash
echo "当前Shell的脚本文件名为:$0"
echo "当前Shell运行的PID号为:$$"
echo "当前Shell的第一个位置变量为:$1"
echo "当前Shell的第二个位置变量为:$2"
echo "当前Shell的第三个位置变量为:$3"
echo "当前传递的所有位置参数为:$*"
echo "当前传递的所有位置参数为:$@"
echo "当前总共传递的位置参数的个数为:$#"
echo "上条命令的执行结果为:$?"
[root@shell /service/scripts/day01]# sh /service/scripts/day01/test.sh  linux  nginx php
当前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]# cat test1.sh
#!/bin/bash
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]# sh test1.sh
未加引号,二者是相同的
linux nginx mysql
linux nginx mysql
加入引号对比
linux nginx mysql
###################
linux
nginx
mysql


没有加入引号之前,两者是相同的

加入引号之后呢

$*  把参数作为一个字符串整体进行输出返回

$@  把每个参数作为一个一个字符串返回


[root@shell /service/scripts/day01]# echo $(date +%F)
2020-04-20

[root@shell /service/scripts/day01]# touch  qls{1..9}.txt
[root@shell /service/scripts/day01]# ll
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]# tar czf  qls.tar.gz  *.txt
[root@shell /service/scripts/day01]# ll
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]# tar cvzf  qls.tar.gz  *.txt
qls1.txt
qls2.txt
qls3.txt
qls4.txt
qls5.txt
qls6.txt
qls7.txt
qls8.txt
qls9.txt

嵌套变量
[root@shell /service/scripts/day01]# File=$(tar czf qls.tar.gz  $(find  ./ -name "*.txt"))
[root@shell /service/scripts/day01]# 
[root@shell /service/scripts/day01]# 
[root@shell /service/scripts/day01]# echo $File

[root@shell /service/scripts/day01]# tar czf qls.tar.gz  $(find  ./ -name "*.txt")
[root@shell /service/scripts/day01]# ll
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]# File=$(tar czvf qls.tar.gz  $(find  ./ -name "*.txt"))
[root@shell /service/scripts/day01]# echo $File
./qls1.txt ./qls2.txt ./qls3.txt ./qls4.txt ./qls5.txt ./qls6.txt ./qls7.txt ./qls8.txt ./qls9.txt


posted @   zbzSH  阅读(40)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示