学习笔记:CentOS7学习之二十:shell脚本的基础
本文用于记录学习体会、心得,兼做笔记使用,方便以后复习总结。内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK老师和学神教育的优质教学。希望各位因学习需求而要进行转载时,能申明出处为学神教育,谢谢各位!
20.1 shell 基本语法
20.1.1 什么是shell?
Shell是一个命令解释器,它在操作系统的最外层,负责直接与用户进行对话,把用户的输入解释给操作系统,并处理各种各样的操作系统的输出结果,输出到屏幕反馈给用户。这种对话方式可是交互也可以是非交互式的,如下图所示:
我们所输入的命令计算机是不识别的,这时就需要一种程序来帮助我们进行翻译,变成计算机能识别的二进制程序,同时又把计算机生成的结果返回给我们。
20.1.2 编程语言分类
编程语言主要用:低级语言和高级语言
- 低级语言:
机器语言:二进制语言
汇编语言:符号语言,使用助记符来代替操作码,也就是用符号代替机器语言的二进制码
它们都是面向机器的语言
- 高级语言:
它是比较接近自然语言或者说人类语言的一种编程,用人们能够容易理解的方式进行编写程序,
静态语言:编译型语言 如:c 、 c++ 、 java,
动态语言:解释型语言 如: php 、 shell 、 python 、 perl
gcc编译器:(解释器) 将人类理解的语言翻译成机器理解的语言
20.1.3 什么是shell脚本
shell脚本:就是说我们把原来linux命令或语句放在一个文件中,然后通过这个程序文件去执行时,我们就说这个程序为shell脚本或shell程序;我们可以在脚本中输入一系统的命令以及相关的语法语句组合,比如变量,流程控制语句等,把他们有机结合起来就形成了一个功能强大的shell脚本
举例:
编写一个简单的脚本程序test.sh
[root@centos-7-24 ~]# vim test.sh
#!/bin/bash
#This is shell
echo "hello world"
mkdir /tmp/test
touch /tmp/test/a.txt
注释:
1、!/bin/bash 作用:告诉脚本使用的是哪种命令解释器。如不指shell,以当前shell作为执行的shell。
2、在shell中以#表示开头,整个行就被当作一个注释。执行时被忽略。
3、shell程序一般以.sh结尾
[root@centos-7-24 ~]# chmod +x test.sh #给用户root赋予test.sh可执行权限
[root@centos-7-24 ~]# ./test.sh #执行脚本
hello world
[root@centos-7-24 ~]# ll /tmp/test/ #查看脚本运行结果
总用量 0
-rw-r--r--. 1 root root 0 6月 25 22:19 a.txt
创建shell程序的步骤:
第一步:创建一个包含命令和控制结构的文件。
第二步:修改这个文件的权限使它可以执行。使用chmod +x test.sh
第三步:检测语法错误
第四步:执行 ./example
shell脚本的执行通常有以下几种方式
- /root/test.sh 或者 ./test.sh (当前路径下执行脚本的话要有执行权限chmod +x test.sh)
- bash test.sh 或 sh test.sh (这种方式可以不对脚本文件添加执行权限)
- source test.sh (可以没有执行权限)
- sh < test.sh 或者 cat test.sh |sh(bash)
20.2 SHELL变量及运用
20.2.1 shell变量
变量是shell 传递数据的一种方法。变量是用来代表每个值的符号名。我们可以把变量当成一个容器,通过变量,可以在内存中存储数据。也可以在脚本执行中进行修改和访问存储的数据
变量的设置规则:
- 变量名称通常是大写字母,它可以由数字、字母(大小写)和下划线_组成。变量名区分大小写;但是大家要注意变量名称不能以数字开头
- 等号 = 用于为变量分配值,在使用过程中等号两边不能有空格
- 变量存储的数据类型是整数值和字符串值
- 在对变量赋于字符串值时,建议大家用引号将其括起来。因为如果字符串中存在空格隔符号。需要使用单引号或双引号
- 要对变量进行调用,可以在变量名称前加美元符号$
- 如果需要增加变量的值,那么可以进行变量值的叠加。不过变量需要用双引号包含“\(变量名”或用\){变量名}包含
变量的分类:
按照变量的作用可以分成4类:
- 用户自定义变量
- 环境变量:这种变量中主要保存的是和系统操作环境相关的数据。
- 位置参数变量:这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。
- 预定义变量:是Bash中已经定义好的变量,变量名不能自定义,变量作用也是固定的。
按照变量作用域可以分成2类:全局变量和局部变量。
- 局部变量是shell 程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量和预定义变量。
- 全局变量是环境变量,其值不随shell 脚本的执行结束而消失。
20.2.2 用户定义变量
变量名命名规则:由字母或下划线打头,不允许数字开头,后面由字母、数1字或下划线组成,并且大小写字母意义不同。在使用变量时,在变量名前加$
例1:给var1赋值:
[root@centos-7-24 ~]# var1=123
[root@centos-7-24 ~]# echo $var1
123
例2:错误的赋值方式,不允许数字开头,等号两边不能有空格
[root@centos-7-24 ~]# var2= 456
bash: 456: 未找到命令...
[root@centos-7-24 ~]# var2 =456
bash: var2: 未找到命令...
[root@centos-7-24 ~]# var2 = 456
bash: var2: 未找到命令...
[root@centos-7-24 ~]# 3var2=456
bash: 3var2=456: 未找到命令...
例3:变量值的叠加,使用${}
\(name是\){name}的简化版本,但是在某些情况下,还必须使用花括号引起的方式来消除歧义并避免意外的结果。因此建议使用${name}调用变量值,如下例所示:
[root@centos-7-24 ~]# VAR4=mysql
[root@centos-7-24 ~]# echo $VAR4
mysql
[root@centos-7-24 ~]# echo $VAR4-DB.LOG
mysql-DB.LOG
[root@centos-7-24 ~]# echo $VAR4.db.log
mysql.db.log
[root@centos-7-24 ~]# echo $VAR4db.log #输出错误,因为系统将VAR4db认为成了一个变量,但是这个变量并没有赋值
.log
[root@centos-7-24 ~]# echo ${VAR4}db.log #使用${name}消除歧义后,输出正常
mysqldb.log
20.2.3 命令的替换,使用$()或反引号
例1:在命令就调用date命令
扩展:date命令是显示或设置系统时间与日期。
-s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号;
<+时间日期格式>:指定显示时,使用特定的日期时间格式。如下所示:
[root@centos-7-24 ~]# date +"%Y-%m-%d" #显示年月日
2019-06-25
[root@centos-7-24 ~]# date +"%Y-%m" #只显示年月
2019-06
[root@centos-7-24 ~]# date +"%Y-%m-%d %H:%M.%S" #显示年月日小时分秒
2019-06-25 22:35.01
[root@centos-7-24 ~]# date +"%Y-%m-%d %H:%M:%S" #以-分割显示年月日等格式
2019-06-25 22:35:11
[root@centos-7-24 ~]# date +"%Y/%m/%d/%H/%M/%S"
2019/06/25/22/40/16
[root@centos-7-24 ~]# date +"%y-%m-%d_%H-%M-%S"
bash: date%y-%m-%d_%H-%M-%S: 未找到命令...
[root@centos-7-24 ~]# date +"%y-%m-%d_%H-%M-%S" #%y显示2位年份
19-06-25_22-42-52
[root@centos-7-24 ~]# date -d "+1 day" +"%y-%m-%d" #显示后一天的日期
19-06-26
[root@centos-7-24 ~]# date -d "+1 day" +"%y-%m-%d"
19-06-26
[root@centos-7-24 ~]# date -d "-1 day" +"%y-%m-%d" #显示前一天的日期
19-06-24
[root@centos-7-24 ~]# date -d "1 day ago" +"%y-%m-%d" #显示前一天的日期
19-06-24
[root@centos-7-24 ~]# date -d "+1 month" +"%y-%m-%d" #显示后一月的日期
19-07-25
[root@centos-7-24 ~]# date -d "+1 year" +"%y-%m-%d" #显示后一年的日期
20-06-25
设定时间:
- date -s 20180523 #设置成20120523,这样会把具体时间设置成空00:00:00
- date -s 01:01:01 #设置具体时间,不会对日期做更改
- date -s "2018-05-23 01:01:01" #这样可以设置全部时间
例1: 在命令中调用date命令输出值
[root@centos-7-24 ~]# echo `date -d "-7 day" +"%Y%m%d"`
20190618
[root@centos-7-24 ~]# echo $(date -d "-7 day" +"%Y%m%d")
20190618
20.2.4 命令的嵌套使用\((\)())
[root@centos-7-24 ~]# find /root/ -name "*.txt"
/root/j.txt
/root/k.txt
/root/m.txt
/root/n.txt
/root/p.txt
/root/q.txt
/root/s.txt
/root/t.txt
/root/v.txt
/root/w.txt
/root/y.txt
/root/z.txt
/root/a.txt
/root/b.txt
/root/c.txt
/root/d.txt
/root/e.txt
/root/f.txt
/root/g.txt
/root/h.txt
/root/i.txt
/root/l.txt
/root/o.txt
/root/r.txt
/root/u.txt
/root/x.txt
[root@centos-7-24 ~]# var6=$(tar -czvf root.tar.gz $(find /root/ -name "*.txt"))
tar: 从成员名中删除开头的“/”
[root@centos-7-24 ~]# echo $var6
/root/j.txt /root/k.txt /root/m.txt /root/n.txt /root/p.txt /root/q.txt /root/s.txt /root/t.txt /root/v.txt /root/w.txt /root/y.txt /root/z.txt /root/a.txt /root/b.txt /root/c.txt /root/d.txt /root/e.txt /root/f.txt /root/g.txt /root/h.txt /root/i.txt /root/l.txt /root/
o.txt /root/r.txt /root/u.txt /root/x.txt
20.2.5 shell中双引号和单引号的区别
‘’ 在单引号中所有的字符包括特殊字符($,'',`和\)都将解释成字符本身而成为普通字符。
“” 在双引号中,除了$, '', `和\以外所有的字符都解释成字符本身,拥有“调用变量的值”、“引用命令”和“转义符”的特殊含义
注:\转义符,跟在\之后的特殊符号将失去特殊含义,变为普通字符。如$将输出“$”符号,而不当做是变量引用
例1:使用\进行转义
[root@centos-7-24 ~]# echo $var1
123
[root@centos-7-24 ~]# echo \$var1 #使用\转义后,$变为普通字符
$var1
例2:赋值时单引号和双引号的区别
[root@centos-7-24 ~]# echo 'yg YG $var1'
yg YG $var1
[root@centos-7-24 ~]# echo "yg YG $var1"
yg YG 123
#注:单引号之间的内容原封不动赋值给变量, 双引号之间的内容如有特殊符号会保留它的特殊含义
删除变量
[root@centos-7-24 ~]# unset var1
[root@centos-7-24 ~]# echo $var1
20.2.6 环境变量
在bash shell中,环境变量分为两类:全局变量和局部变量
全局变量:对于shell会话和所有的子shell都是可见的
局部变量: 它只在自己的进程当中使用
例1:局部变量
[root@centos-7-24 ~]# var1=123
[root@centos-7-24 ~]# echo $var1
123
[root@centos-7-24 ~]# vim a.sh
#!/bin/bash
echo $var1
~
[root@centos-7-24 ~]# bash a.sh #执行a.sh 时,会使用另一个bash去执行,就访问不到var1的值
例2:env命令查看所全局变量
[root@centos-7-24 ~]# env |grep PATH
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
QT_PLUGIN_PATH=/usr/lib64/kde4/plugins:/usr/lib/kde4/plugins
例3:使用export把这个局部变量输出为全局变量
[root@centos-7-24 ~]# var1=yg
[root@centos-7-24 ~]# export var1 #设置var1为全局变量
[root@centos-7-24 ~]# bash a.sh #引用全局变量成功
yg
互动: 虽然我们设置了export全局变量,但是新开的xshell连接中,依然还是读不到变量VAR1,可以通过将全局变量写入配置文件让其生效
例3:让变量永久生效,可以把定义好的变量写入配置文件
当登录系统或新开启一个ssh连接启动bash进程时,一定会加载这4个配置文件:
- /etc/profile #系统全局环境和登录系统的一些配置
- /etc/bashrc #shell全局自义配置文件,用于自定义shell
- /root/.bashrc #用于单独自定义某个用户的bash
- /root/.bash_profile #用户单独自定义某个用户的系统环境
下面开始插入永久变量:
[root@centos-7-24 ~]# vim /etc/profile
export VAR9=yg
[root@centos-7-24 ~]# source /etc/profile
新打开的链接中,也有了,如下所示:
20.2.7 设置PATH环境变量
SHELL要执行某一个程序,它要在系统中去搜索这个程序的路径,path变量是用来定义命令和查找命令的目录,当我们安装了第三方程序后,可以把第三方程序bin目录添加到这个path路径内,就可以在全局调用这个第三方程序的
[root@centos-7-24 ~]# vim /opt/backup.sh
#!/bin/bash
echo "Backup data is OK!"
[root@centos-7-24 ~]# chmod +x /opt/backup.sh
[root@centos-7-24 ~]# /opt/backup.sh #添加全路径可以执行脚本
Backup data is OK!
[root@centos-7-24 ~]# backup.sh #不添加路径执行无效
bash: backup.sh: 未找到命令...
将backup.sh的路径添加添加PATH中
[root@centos-7-24 ~]# PATH=/opt/:$PATH
[root@centos-7-24 ~]# backup.sh #发现命令可以直接执行了,不用写全路径了
Backup data is OK!
[root@centos-7-24 ~]# vim /etc/profile # 在文件最后追加以下内容,永久生效
[root@centos-7-24 ~]# vim /etc/profile
[root@centos-7-24 ~]# source /etc/profile #重新加载配置文件,使用配置生效
[root@centos-7-24 ~]# backup.sh
Backup data is OK!
20.2.8 shell位置变量
Shell解释执行用户的命令时,将命令行的第一个字符作为命令名,而其它字符作为参数。
$0 获取当前执行shell脚本的文件文件名,包括脚本路径,命令本身
\(n 获取当前脚本的第n个参数 n=1,2.....n 当n大于9时 用\){10}表示。
举例:
[root@centos-7-24 tmp]# vim print.sh
#!/bin/bash
echo "本shell脚本的文件名:$0"
echo "\$1 是第一个参数:$1"
echo "\$2 是第二个参数:$2"
echo "\$3 是第一个参数:$3"
echo "\$4 是第一个参数:$4"
[root@centos-7-24 tmp]# chmod +x print.sh
[root@centos-7-24 tmp]# ./print.sh 111 222 a.txt 444
本shell脚本的文件名:./print.sh
$1 是第一个参数:111
$2 是第二个参数:222
$3 是第一个参数:a.txt
$4 是第一个参数:444
20.2.9 特殊变量
有些变量是一开始执行Script脚本时就会设定,且不能被修改,但我们不叫它只读的系统变量,而叫它特殊变量。这些变量当一执行程序时就有了,以下是一些特殊变量:
变量名 | 说明 |
---|---|
$* | 以一个单字符串显示所有向脚本传递的参数;如"$*"用【"】括起来的情况、以"$1 $2 … $n"的形式输出所有参数 |
$# | 传递到脚本的参数个数 |
$$ | 当前进程的进程号PID |
$? | 显示最后命令的退出状态;0表示没有错误,其他任何值表明有错误 |
$! | 后台运行的最后一个进程的进程号pid |
例子:
[root@centos-7-24 tmp]# vim special_varliable.sh
#!/bin/bash
echo "$* 表示这个程序的所有参数"
echo "$# 表示这个程序的参数个数"
echo "$$ 表示程序的进程ID"
touch /tmp/b.txt & #最后的&表示程序后台运行
echo "$! 表示执行上一个后台进程的pid"
echo "$$ 表示程序的进程ID"
echo "$? 表示上一个程序的返回结果"
[root@centos-7-24 tmp]# chmod +x special_varliable.sh
[root@centos-7-24 tmp]# ./special_varliable.sh 11 22 33 44 55
11 22 33 44 55 表示这个程序的所有参数
5 表示这个程序的参数个数
25614 表示程序的进程ID
25615 表示执行上一个后台进程的pid
25614 表示程序的进程ID
0 表示上一个程序的返回结果
例2:常用的环境变量
[root@centos-7-24 tmp]# echo $HOME
/root
[root@centos-7-24 tmp]# echo $PATH
/opt/:/opt/:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@centos-7-24 tmp]# echo $PWD
/tmp
20.3 数学运算
20.3.1 expr命令
(1)对数字的基本计算,做比较时,输出结果假为0,1为真;特殊符号用转义符
[root@centos-7-24 tmp]# expr 2\>5
2>5
[root@centos-7-24 tmp]# expr 2 \> 5
0
[root@centos-7-24 tmp]# expr 6 \> 5
1
[root@centos-7-24 tmp]# expr 3 * 5
expr: 语法错误
[root@centos-7-24 tmp]# expr 3 \* 5
15
[root@centos-7-24 tmp]# expr 3 \+ 5
8
(2)对字符串的处理
[root@centos-7-24 tmp]# expr length "ni hao"
6
[root@centos-7-24 tmp]# expr substr "ni hao" 2 4 #从第2个开始,截取4个字符出来
i ha
20.3.2 使用$(())
格式:$((表达式1,表达2))
特点:
- 在双括号结构中,所有表达式可以像c语言一样,如:a++,b--等。a++ 等价于 a=a+1
- 在双括号结构中,所有变量可以不加入:“$”符号前缀。
- 双括号可以进行逻辑运算,四则运算
- 双括号结构 扩展了for,while,if条件测试运算
- 支持多个表达式运算,各个表达式之间用“,”分开
常用的算数运算符
运算符 | 意义 |
---|---|
++ -- | 递增及递减,可前置也可以后置 |
+ - ! ~ | 一元运算的正负号 逻辑与取反 |
+ - * / % | 加减乘除与余数 |
< <= > >= | 比较大小符号 |
== != | 相等 不相等 |
>> << | 向左位移 向右位移 |
& ^ ¦ | 位的与 位的异或 位的或 |
&& ¦¦ | 逻辑与 逻辑或 |
? : | 条件判断 |
例1:
[root@centos-7-24 tmp]# b=$((1+2))
[root@centos-7-24 tmp]# echo $b
3
[root@centos-7-24 tmp]# echo $((2*3))
6
例2:递增和递减
[root@centos-7-24 tmp]# echo $((b++))
3
[root@centos-7-24 tmp]# echo $b
4
[root@centos-7-24 tmp]# echo $((++b))
5
[root@centos-7-24 tmp]# echo $b
5
说明: a++或a--为先赋值再+1或减1 ; ++a或--a为先加1或减1,然后再进行赋值
END
2019/6/26 1:21:12
学习笔记:CentOS7学习之二十:shell脚本的基础的更多相关文章
-
好记性比如烂笔头--linux学习笔记7关于linux中的shell脚本编程
之前看的各种面试,貌似都有shell脚本编程,没了解之前感觉很复杂,现在了解了些,没想象中那么难. 逻辑主要是这样的 编写.sh的脚本文件,文件里面的代码,就是在命令行输入的可执行命令的加强版,所谓加 ...
-
好记性不如烂笔头--linux学习笔记9练手写个shell脚本
#!/bin/bash #auto make install httpd #by authors baker95935 #httpd define path variable H_FILES=http ...
-
JavaSE 学习笔记之正则表达式(二十五)
正则表达式:其实是用来操作字符串的一些规则. 好处:正则的出现,对字符串的复杂操作变得更为简单. 特点:将对字符串操作的代码用一些符号来表示.只要使用了指定符号,就可以调用底层的代码对字符串进行操作. ...
-
20155234 2016-2017-2第十周《Java学习笔记》学习总结
20155234第十周<Java学习笔记>学习总结 教材学习内容总结 网络编程 在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定 ...
-
Java菜鸟学习笔记--数组篇(三):二维数组
定义 //1.二维数组的定义 //2.二维数组的内存空间 //3.不规则数组 package me.array; public class Array2Demo{ public static void ...
-
JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
-
vue2.0学习笔记之路由(二)路由嵌套+动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
-
vue2.0学习笔记之路由(二)路由嵌套
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
-
#学习笔记#e2e学习使用(二)
前言: <#学习笔记#e2e学习使用(一)>主要记录了Vue项目的创建到e2e环境的搭建,以及期间遇到的各种问题和解决方法.本文建立在基础测试环境搭建完毕能正确运行的情况下,编写测试代码, ...
随机推荐
-
js生成和下载二维码
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/stri ...
-
ajax步骤和理解
步骤: 1.利用html+css来实现页面,表达信息: 2.用XMLHttpRequest和web服务器进行数据的异步交换 3.运营js操作DOM,实现动态局部刷新: XMLHttpRequest对象 ...
-
QTP中FSO的使用
序 FSO即文件系统对象(File System Object),在测试工作中有广泛的应有,它可以帮助我们自动生成测试目录,写日志,测试报告等.FSO有对象有很多属性和方法,今天只介绍几个常用的. 创 ...
-
qmake使用实践:包含动态库的Qt4工程
文章来源:http://blog.csdn.net/dbzhang800/article/details/6317006 本文是qmake的一个使用练习,是半年前所学的 分析与学习Qt Solutio ...
-
关于css的伪类和伪元素
现在才发现自己一直没有分清楚css的伪类和伪元素啊,so,总结一下. CSS 伪类用于向某些选择器添加特殊的效果. CSS 伪元素用于将特殊的效果添加到某些选择器. 可以明确两点,第一两者都与选择器相 ...
-
用 JS 点击左右按钮 使图片切换 - 最精简版-ljx2380000-ChinaUnix博客
body { font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI ...
-
UINavigationBar统一修改导航条样式
#pragma mark -- 统一导航条样式 //统一导航条样式 UIFont *font = [UIFont systemFontOfSize:19.f]; NSDictionary *textA ...
-
Xamarin.Forms(一) Visual Studio 连接安卓模拟器(逍遥安卓)
刚开始学习Xamarin.Forms的时候总是比较困难的,连接安卓模拟器就花了我好长时间,后来在网上找到了方法: 1.打开adb.exe所在目录: 如:cd F:\Android\android-sd ...
-
【LeetCode】Anagram
Anagram 指由颠倒字母顺序而构成的单词. e.g. 给出 ["eat", "tea", "tan", "ate", ...
-
Python中__init__和__new__的区别详解
__init__ 方法是什么? 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例的时候.例如: # -*- cod ...