avatar

1.shell编程介绍及变量

shell编程介绍及变量

第1章 如何学好shell编程

1.1 为什么学习shell编程

shell编程在工作中做什么?

shell脚本语言是实现Linux系统管理及自动化运维必须的重要工具。

  1. 安装操作系统(手动安全ISO) 自动化安装(kickstart cobbler)shell脚本

  2. 初始化操作系统 优化(SSH优化 关闭SElinux 优化防火墙 c6.x iptables C7.xfirewalld NTP时间同步 更改默认YUM源 字符集 安装常用的软件 lrzsz net-tools tree.. wget 隐藏版本信息 加大文件描述符 内核优化…)
    初始化写入脚本 自动化执行

  3. 安装服务(Nginx PHP MySQL MariaDB NFS sersync REDIS keepalived docker….zabbix shell 脚本自动选择安装)

  4. 配置文件(优化)

  5. 启动—-停止(centos6.x /etc/init.d/server start centos7 systemctl start server) 系统默认的启动方式 shell脚本
    py写的程序 jumpserver
    python3.5 test.py 传参 –redis 10.0.0.22 –prot 6379 –IPlog – – –
    python3.5 test.py -h
    放入shell脚本命名 log_count.start
    停止py服务 log_count.stop ps axu|grep test.py|grep -v grep|awk ‘{print $2}’|xargs kill -9

  6. 监控 zabbix cacti(流程) nagios ELK (公司研发监控平台)
    监控的值(shell脚本统计)

  7. 日志统计 三剑客 日志切割(脚本+定时任务)

1.2 学习shell编程所需基础知识

学好shell编程并通过shell脚本轻松实现自动化管理企业生产系统必备基础如下:

  1. 熟练使用vim编辑器,熟悉SSH终端及“vimrc”等的配置。

  2. 掌握一定Linux命令基础,至少80个,熟练使用。

  3. 熟练掌握Linux正则表达式及三剑客(grep、sed、awk)

  4. 熟悉常见的Linux网络服务器部署、优化、日志分析和排错

1.3 如何才能学好shell

  1. 掌握Shell基本语法

  2. 掌握常见语法 环境变量—数值比较–条件表达式—if判断—for循环–while循环–case语句–函数–数组—条件控制语句 exit continue break

  3. 修改脚本内容(完善脚本)形成自己的开发风格

  4. 套用 框架(公司中大部分脚本的写法) 熟能生巧,从简单坐骑,简单判断、简单循环

  5. 多模仿、多思考

  6. 学会分析问题,形成编程思维

  7. 编程名字要规范、采用驼峰语法

  8. 不要拿来主义,特别是新手

第2章 shell脚本入门

2.1 什么是shell?

shell 是一个命令解释器

shell存在于操作系统最外层,负责与用户直接对话,对用户的输入解析给操作系统,并处理各种各样的输出结果,然后输出到屏幕返回给用户。

面试题: linux下默认的shell是? bash

命令解释器 pwd ls

bash? 当前的命令行 和shell脚本 文本内有可执行命令 bash

当前的bash 父shell 文本内的命令 子shell

子shell可继承父shell的变量 父shell无法继续子shell的变量

交互式shell shll等待输入 输入命令 shell执行并返回结果 交互式

非交互式 把可执行命令 放入文本中 定时任务执行 称为非交互式

2.2 什么是shell脚本

shell脚本:当命令或程序语句不在命令行下执行,而是通过一个程序文件来执行时,该程序被称为shell脚本。

命令的大礼包 把可执行命令放到文件中 称为shell脚本(判断语句 循环语句 数组….)

2.3 shell脚本语言的种类

1.Bourne shell

2.C shell

常用的脚本语言:

PHP Perl Python Shell

Shell脚本语言 优势在于处理偏系统底层的业务,如:一键自动化、优化、监控报警、软件启动、日志分析等脚本。shell更符合Linux运维简单、易用、高效的三大基本原则。

2.4 Shell的书写规范

1) shell脚本存放统一的目录 /server/scripts

2) 脚本名字的结尾使用.sh

3) 脚本的开头 必须有解释器 #!/bin/bash

4) 脚本内有作者信息 脚本信息

1
2
3
4
5
#Date: 20111111
#Author: wufei
#Blog: #博客
#Descriptsion: #描述
#Version: 1.0 #版本

5) 每段代码块有注释(尽量使用英文)

6) 标点符号 (语法尽量一次性书写完毕

7) 成对的符号 一次性书写完毕

2.5 第1个Shell脚本

1
2
3
[root@backup /server/scripts]# cat hello.sh 
#!bin/bash
echo "hello world!"

执行脚本的三种方法:

1
2
3
4
5
6
7
8
9
10
#方法1:直接使用解释器执行
[root@backup /server/scripts]# bash hello.sh
hello world!
#方法2: 全路径方式执行 需要执行权限
# chmod +x hello.sh
[root@backup ~]# . /server/scripts/hello.sh
hello world!
#方法3 source .执行脚本 子shell中的内容调用到父shell中执行
[root@backup /server/scripts]# source hello.sh
hello world!
1
2
3
4
if 条件内容
then
内容
fi

一次性完成for循环语句格式

1
2
3
4
for
do
内容
done

第3章 Shell变量

3.1 什么是变量?

1
2
3
4
5
[root@backup /server/scripts]# echo $LANG
en_US.UTF-8
[root@backup /server/scripts]# oldboy="i am oldboy"
[root@backup /server/scripts]# echo $oldboy
i am oldboy

3.2 变量类型:

变量可分为两类:环境变量(全局变量)和普通变量(局部变量)

全局变量(环境变量) 针对系统所有用户生效
局部变量(普通变量) 针对当前登录用户生效

变量生存周期分类 两类
临时性 export 声明变量即可 或者 name=oldboy
永久性 修改配置文件 /etc/profile

1
2
3
4
5
6
7
8
9
10
环境变量文件执行顺序
1. /etc/profile
2. .bash_profile
3. .bashrc
4. /etc/bashrc
如果按照文件内容的生效顺序
1. /etc/profile
2. .bashrc
3. /etc/bashrc
4. .bash_profile

3.3 如何定义变量

要求以字母 数字 和下划线组合 只能以字母和_开头 等号两端不允许有空格 名字 见名直其意

1
2
3
4
5
变量名字的定义的语法:
OLDBOY_AGE=18 系统用的变量都是大写
oldboy_age=18 全小写
oldboy_Age=18 小驼峰语法
Oldboy_Age=18 大驼峰语法

普通变量定义:

1
2
3
变量名=value           #赋值时不加引号
变量名='value' #赋值时加单引号
变量名=“value“ #赋值时加双引号

变量值得定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1.数字定义  连续的数字    oldboy=188888
2.字符串定义 连续的字符串 name="oldboy alex lidao" 不知道加什么就加双引号
例子: CODE_DIR=/etc/sysconfig/network-scripts/
name='$oldboy' 所见即所得 不解析变量
[root@backup ~]# name=oldboy
[root@backup ~]# echo "$name"
oldboy
[root@backup ~]# echo '$name'
$name
3.命令的定义
方法1 time=`date +%F`
方法2 time=$(date +%F)
[root@backup /server/scripts]# time=`date +%F-%H-%M-%S`
[root@backup /server/scripts]# echo $time
2019-08-22-22-02-18
[root@backup /server/scripts]# echo $time #第二次运行还是一样
2019-08-22-22-02-18
[root@backup /server/scripts]# time=`date +%F-%H-%M-%S` #重新再次赋值
[root@backup /server/scripts]# echo $time #重新赋值后结果不同
2019-08-22-22-02-28

第4章 特殊的位置参数变量

位置变量 作用说明
$0 获取当前执行的shell脚本的文件名,如果包含路径,则包括脚本路径
$n 获取当前执行脚本的第n个参数值,参数从$1开始 $9 以后需要加{}
$# 获取当前执行的脚本后面接的参数的总个数
$* 获取当前执行脚本所有传参的参数,不加引号和$@相同
$@ 获取脚本的所有的参数 不加双引号和$* 相同 加上双引号则把参数视为独立的(在循环体中)

4.1 设置15个参数,用于传递

1
2
3
4
5
6
7
8
9
10
11
12
[root@backup /server/scripts]# cat n.sh 
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15
[root@backup /server/scripts]# sh n.sh {a..z}
a b c d e f g h i a0 a1 a2 a3 a4 a5

#当位置参数数字>9时,需要用{}将数字括起来,才能正常显示
[root@backup /server/scripts]# cat n.sh
#!/bin/bash
echo $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} ${11} ${12} ${13} ${14} ${15}
[root@backup /server/scripts]# sh n.sh {a..z}
a b c d e f g h i j k l m n o

4.2 特殊变量$0

获取脚本名称及路径

1
2
3
4
5
6
7
8
9
10
[root@backup /server/scripts]# cat n.sh
echo $0
[root@backup /server/scripts]# sh n.sh
n.sh
[root@backup ~]# sh /server/scripts/n.sh
/server/scripts/n.sh
[root@backup /server/scripts]# dirname /server/scripts/n.sh #dirname只获取路径
/server/scripts
[root@backup /server/scripts]# basename /server/scripts/n.sh
n.sh #basename只获取脚本名称

4.3 特殊变量$#

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

1
2
3
4
5
6
[root@backup /server/scripts]# cat n.sh 
echo $1 $2 $3 $4 $5 $6 $7 $8 $9
echo $#
[root@backup /server/scripts]# sh n.sh {a..z}
a b c d e f g h i
26

案例一

1
2
3
4
5
6
[root@backup /server/scripts]# [ $# -eq 2 ] || echo "请重新输入两个参数"
请重新输入两个参数
[root@backup /server/scripts]# [ 3 -ne 2 ] && echo ok|| echo error
ok
[root@backup /server/scripts]# [ 2 -ne 2 ] && echo ok|| echo error
error

案例二

1
2
3
4
5
6
7
8
9
10
11
12
[root@backup /server/scripts]# cat n.sh 
#!/bin/bash
if [ $# -ne 2 ]
then
echo "USAGE:/bin/bash -bash arg1 arg2"
exit 1
fi
echo $1 $2
[root@backup /server/scripts]# sh n.sh
USAGE:/bin/bash -bash arg1 arg2
[root@backup /server/scripts]# sh n.sh oldboy 123456
oldboy 123456

4.4 特殊变量$*和$@

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[root@backup /server/scripts]# set -- "I am" oldboy teacher
[root@backup /server/scripts]# echo $*
I am oldboy teacher
[root@backup /server/scripts]# echo $@
I am oldboy teacher
#在循环中先对比不带“”时,2者无区别
[root@backup /server/scripts]# for i in $*;do echo $i;done
I
am
oldboy
teacher
[root@backup /server/scripts]# for i in $@;do echo $i;done
I
am
oldboy
teacher
#在循环中带“”时,2者的区别
[root@backup /server/scripts]# for i in "$*";do echo $i;done
I am oldboy teacher
[root@backup /server/scripts]# for i in "$@";do echo $i;done
I am
oldboy
teacher

第5章 特殊的位置状态变量

位置变量 作用说明
$? 获取上一个指令的执行状态并返回值(0为成功,非0为失败)
$$ 获取当前执行的shell脚本的进程号(pid),脚本名字相同时使用
$! 获取上一个后台工作的进程的进程号(pid) ,调试脚本时使用
$_ 获取在此之前执行的命令或脚本的最后一个参数 ,相当于ESE.

5.1 特殊变量$0使用

判断上一个命令是否执行成功,可用于判断服务是否正确执行或命令是否执行成功

当备份数据时,可通过$?来判断是否成功,备份数据是否完整

1
2
3
4
5
6
7
8
[root@backup /server/scripts]# pwd
/server/scripts
[root@backup /server/scripts]# echo $?
0
[root@backup /server/scripts]# lll
-bash: lll: command not found
[root@backup /server/scripts]# echo $?
127

5.2 特殊变量$$使用

获取脚本执行的进程号pid

1
2
3
4
5
6
7
8
9
10
[root@backup /server/scripts]# cat test.sh 
#!/bin/bash
echo $$ > /tmp/test.pid
sleep 300
[root@backup /server/scripts]# sh test.sh
[root@backup ~]# ps -ef |grep test.sh
root 5641 4909 0 09:51 pts/1 00:00:00 sh test.sh
root 5667 5643 0 09:51 pts/2 00:00:00 grep --color=auto test.sh
[root@backup ~]# cat /tmp/test.pid
5641

5.3 特殊变量$_使用

获取上一条命令的最后一个参数

1
2
3
[root@backup ~]# cd /server/scripts/
[root@backup /server/scripts]# echo $_
/server/scripts/

5.4 特殊变量$!使用

用于获取上一次执行脚本的pid

第6章 变量传参的三种方法

6.1 直接传参

1
2
[root@backup /server/scripts]# sh n.sh oldboy 123456
oldboy 123456

6.2 赋值传参

1
2
3
4
5
6
7
8
[root@backup /server/scripts]# cat ping.sh 
#!/bin/bash
#方法2
url=$1
ping -c 1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
[root@backup /server/scripts]# sh ping.sh www.qq.com
ping www.qq.com is ok

6.3 read传参

1
2
3
4
5
6
7
8
9
10
11
12
[root@backup /server/scripts]# cat ping.sh 
#!/bin/bash
#方法3
read -p "please input url is: " url
ping -c 1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
[root@backup /server/scripts]# sh ping.sh
please input url is: www.qq.com
ping www.qq.com is ok
[root@backup /server/scripts]# sh ping.sh
please input url is: www.qqq.com
ping www.qqq.com is error

6.4 案例 使用三种传参方式 做ping url

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@backup /server/scripts]# cat ping.sh 
#!/bin/bash
#方法1
ping -c 1 $1 &>/dev/null
[ $? -eq 0 ] && echo "ping $1 is ok" || echo "ping $1 is error"
#方法2
url=$1
ping -c 1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
#方法3
read -p "please input url is: " url
ping -c 1 $url &>/dev/null
[ $? -eq 0 ] && echo "ping $url is ok" || echo "ping $url is error"
[root@backup /server/scripts]# sh ping.sh www.qq.com
ping www.qq.com is ok
ping www.qq.com is ok
please input url is: www.qq.com
ping www.qq.com is ok

第7章 变量的子串(常用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@backup /server/scripts]# test="I am oldboy"
[root@backup /server/scripts]# echo $test
I am oldboy
[root@backup /server/scripts]# echo ${#test} #变量前加#可以打印变量的长度
11
[root@backup /server/scripts]# echo $test|wc -L
11
[root@backup /server/scripts]# expr length "$test"
11
[root@backup /server/scripts]# echo ${test}|awk '{print $2}'
am
[root@backup /server/scripts]# echo ${test}|cut -c3-4
am
[root@backup /server/scripts]# echo ${test}|grep -o am
am
[root@backup /server/scripts]# echo ${test:2:2}
am

面试题: 统计字符串长度

1
2
3
4
5
6
7
8
9
10
# echo $test
I am oldboy
# echo ${#test} #变量前加#可以打印变量的长度
11
# echo $test|wc -L
11
# expr length "$test"
11
# echo $test|awk '{print length}'
11

面试题2: 输出字符串长度小于3的单词

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@backup /server/scripts]# cat for.sh 
#!/bin/bash
for i in I am lizhenya teacher I am 18
do
[ ${#i} -lt 3 ] && echo $i
done
[root@backup /server/scripts]# sh for.sh
I
am
I
am
18

[root@backup /server/scripts]# echo "I am lizhenya teacher I am 18"|xargs -n1|awk '{if(length<3)print}'
I
am
I
am
18

[root@backup /server/scripts]# echo "I am lizhenya teacher I am 18"|xargs -n1|awk '{for(i=1;i<=NF;i++)if(length<3)print}'
I
am
I
am
18

变量子串的删除和替换

1
2
3
4
5
6
7
8
9
#截取从第二个字符之后的内容,不包含第二个字符
[root@backup /server/scripts]# echo $test
I am oldboy
[root@backup /server/scripts]#
[root@backup /server/scripts]# echo ${test:2}
am oldboy
#从第二个字符开始截取之后的二个字符
[root@backup /server/scripts]# echo ${test:2:2}
am

#从前面往后删除 ## 贪婪匹配

%从后往前删除

// 替换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

[root@backup /server/scripts]# url=www.baidu.com
[root@backup /server/scripts]# echo ${url#*.} #从.开始删除前面的内容输出
baidu.com
[root@backup /server/scripts]# echo ${url#*.*.} #从第二个.开始删除前面的内容输出
com
[root@backup /server/scripts]# echo ${url##*.} #贪婪匹配
com

[root@backup /server/scripts]# echo ${url%.*}
www.baidu
[root@backup /server/scripts]# echo ${url%.*.*}
www
[root@backup /server/scripts]# echo ${url%%.*} #贪婪匹配
www

#url// 替换
[root@backup /server/scripts]# echo $url
www.baidu.com
[root@backup /server/scripts]# echo ${url/baidu/qq}
www.qq.com
[root@backup /server/scripts]# echo ${url/w/S}
Sww.baidu.com
[root@backup /server/scripts]# echo ${url//w/S}
SSS.baidu.com

第8章 变量的数值计算

常见的Shell算术运算符

算术运算符 意义(*表示常用)
+ 、- 加(或正号)、减(或负号)*
*、/、% 乘法、除法、取余 *
** 冥运算 *
++ 、– 增加、减少,可前置也可放在变量的结尾 *
!、&&、|| 非(取反)、相当于and 、相当于or *
< 、<= 、> 、>= 比较符号(小于、小于等于、大于、大于等于)
== 、!= 、= 比较符号 (相等、不相等、对于字符串=也可表示相当于)*
<< 、>> 向左移位、向右移位
~ 、| 、& 、^ 按位取反、按位异或、按位于、按位或
= 、+=、-= 、*= 、%= 赋值运算符,例如 a+=1 相当于 a=a+1 , a-=1 相当于 a=a-1 *

常见的运算命令

运算操作符号与运算命令 意义
(()) 用于整数的运算、效率很高
let 用于证书运算,类似于(())
expr 可用于整数运算,还有其他功能
bc Linux下的计算程序、可用于整数及小数运算
$[] 用于整数运算
awk awk既可用于整数运算,也可用于小数运算
declare 定义变量值和属性,-i参数可用于定义整形变量,做运算

8.1 双小括号(())数值运算

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@backup /server/scripts]# echo $((6+2))
8
[root@backup /server/scripts]# echo $((6-2))
4
[root@backup /server/scripts]# echo $((6*2))
12
[root@backup /server/scripts]# echo $((6/2))
3
[root@backup /server/scripts]# a=3
[root@backup /server/scripts]# echo $((a=a+1)) #将a赋值给a+1,输出结果
4
[root@backup /server/scripts]# echo $((a+=1)) #相当于a=a+1
5
[root@backup /server/scripts]# echo $((a**2)) #计算a的平方
25

8.2 let数值运算

1
2
3
4
5
6
7
8
9
[root@backup /server/scripts]# sum=10
[root@backup /server/scripts]# let sum=sum+1
[root@backup /server/scripts]# echo $sum
11
[root@backup /server/scripts]# sum1=10
[root@backup /server/scripts]# sum2=20
[root@backup /server/scripts]# let sum=sum1+sum2
[root@backup /server/scripts]# echo $sum
30

8.3 expr数值运算

1
2
3
4
5
6
7
8
9
10
[root@backup /server/scripts]# expr 2 + 2
4
[root@backup /server/scripts]# expr 2 - 2
0
[root@backup /server/scripts]# expr 2 * 2
expr: syntax error
[root@backup /server/scripts]# expr 2 \* 2
4
[root@backup /server/scripts]# expr 2 / 2
1

8.4 bc数值运算

1
2
3
4
5
6
7
8
[root@backup ~]# echo 10+10|bc
20
[root@backup ~]# echo 10+10.5|bc
20.5
[root@backup ~]# echo 10*10.5|bc
105.0
[root@backup ~]# echo 10/10.5|bc
0

8.5 $[] 数值运算

1
2
3
4
5
6
7
8
[root@backup /server/scripts]# echo $[10+10]
20
[root@backup /server/scripts]# echo $[10-10]
0
[root@backup /server/scripts]# echo $[10*10]
100
[root@backup /server/scripts]# echo $[10/10]
1

8.6 awk数值运算

1
2
3
4
5
6
7
8
[root@backup /server/scripts]# echo "10 1.5"|awk '{print $1+$2}'
11.5
[root@backup /server/scripts]# echo "10 1.5"|awk '{print $1-$2}'
8.5
[root@backup /server/scripts]# echo "10 1.5"|awk '{print $1*$2}'
15
[root@backup /server/scripts]# echo "10 1.5"|awk '{print $1/$2}'
6.66667

8.7 declare命令的用法

1
2
3
4
[root@backup ~]# declare -i A=30 B=7
[root@backup ~]# A=A+B
[root@backup ~]# echo $A
37
文章作者: Wu Fei
文章链接: http://linuxwf.com/2020/04/15/1-shell%E7%BC%96%E7%A8%8B%E4%BB%8B%E7%BB%8D%E5%8F%8A%E5%8F%98%E9%87%8F/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WF's Blog
打赏
  • 微信
    微信
  • 支付宝
    支付宝

评论