shell脚本

1Shell 编程基础与脚本规范
1.1编程基础
1.1.1程序组成
程序:算法+数据结构

数据:是程序的核心
算法:处理数据的方式
数据结构:数据在计算机中的类型和组织方式
1.2 shell 脚本的用途和应用场景用途:
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
应用场景:
重复性操作
交互性任务
批量事务处理
服务运行状态监控
定时任务执行
1.3常见的shell解释器
Linux系统中的Shell 是一个特殊的应用程序,它介于操作系统内核与用户之间,充当一个”命令解释器“的角色,负责接收用户输入的操作指令(命令)并进行解释,将需要执行的操作传递给内核执行,并输出结果。 它是用户使用 Linux 的桥梁。

Shell 既是一种命令语言,又是一种程序设计语言。

常见的 Shell 解释器程序有很多种,使用不同的 Shell 时,其内部指令、命令行提示符等方面会存在一些区别。通过/etc/shell 文件可以了解当前系统所支持的 Shell 脚本种类。

linux 中常见的shell
bash:基于GUN的框架下发展的shell
csh:类似C语言的shell
tcsh:整合了csh 提供了更多功能
sh:已经被bash替换
nologin:让用户无法登录
bash(/bin/bash)是目前大多数 Linux 版本采用的默认 shell。

bash特性:
支持快捷键:比如 ctrl+c 强制终止进程 、 ctrl+l 清屏 、Tab补齐 等等。
支持查看历史命令(history)
支持别名(alias)
标准输入和标准输出的重定向
管道符
文件名通配机制
支持命令hash
支持变量
这些功能都是bash特有的,其他shell环境没有这些功能,或者说没有这么全,所以bash取代sh成为了Linux的默认shell。

2    shell脚本基本结构
2.1 脚本的构成:
脚本申明(申明解释器) :第一行开头 “#!/bin/bash”,表示此行以下的代码语句是通过/bin/bash程序来执行。还有其他类型的解释器,比如 #/usr/bin/python、#!/usr/bin/expect 。
注释信息: 以“#”开头的语句表示为注释信息,被注释的语句在脚本运行时不会被执行。
可执行语句: 如echo命令,用于输出“ ”之间的字符串。
2.2 shell 脚本规范
脚本名称规范:文件名以.sh结尾,方便识别。

脚本代码开头约定:

第一行一般为调用使用的语言
程序名,避免更改文件名后无法找到正确的文件
版本号
更改后的时间
作者相关信息
该程序的作用,及注意事项
最后是各版本的更新简要说明
2.3  脚本的执行方式
1、指定路径去执行文件,文件需要有执行权限。

绝对路径。如:/root/hello.sh
相对路径。如:./hello.sh
2、指定解释器去执行(bash 脚本名),不需要执行权限。

bash 脚本名。如:bash hello.sh
“source 脚本名” 或 “ . 脚本名”。 //不会启动子shell环境
注意:

执行脚本时的shell环境:
source和 . 执行脚本时,会在当前shell环境中执行脚本。
bash、绝对路径、相对路径 执行脚本时,会创建一个子shell环境,并在这个子shell环境中执行脚本。
不建议使用source来执行脚本,可能会影响一些资源配置。
脚本中的空白行会被解释器忽略。
脚本中,除了shebang,余下所有以#开头的行,都回被视作注释行而被忽略。此即为注释行。
 脚本错误调试
脚本错误类型:

命令错误: 命令错误不会影响接下来的命令,之后的命令会继续执行。
语法错误: 会导致后续的命令不执行。造成脚本中一部分命令已执行,一部分未执行。
逻辑错误: 执行后的效果不是自己想要的。需要自己去排查。
 bash -n 脚本名称     //只检查语法错误,不真正执行脚本。定位的错误行可能不准确。  

​  bash -x 脚本名称     //显示每个命令的执行过程,方便发现逻辑错误

重定向
重定向的意思就是,不通过标准输出到默认屏幕上,而是输出到你指定的位置。

输入重定向

符号    作用
命令 < 文件    从指定的文件读取文件,而不是从键盘输入
命令 << 分界符    从标准输入中读入,直到遇见分界符才停止
命令 < 文件1 > 文件2    将文件1 作为命令的标准输入并将标准输出到文件
输出重定向

符号    作用
命令 > 文件    将标准输出结果保存到指定的文件中(覆盖原有内容)
命令 >> 文件    将标准输出结果追加到指定的文件尾部
命令 2> 文件    将错误输出信息保存到指定文件中(覆盖原有内容)
命令 2>> 文件    将错误输出信息追加到指定文件尾部
命令 > 文件 2>&1    混合输出,将标准输出与错误输出保存到文同一个文件中
命令 2> 文件 1>&2    同上
命令 &> 文件    同上
命令 >& 文件    同上
管道符
管道符的作用是连接两个命令,将第一个命令的标准输出作为第二个命令的标准输入。 同一行命令中可以使用多个管道符。

linux下的管道符使用"竖杠"表示:| 。

格式:命令A | 命令B

Shell 脚本中的变量
变量概述
变量即在程序运行过程中它的值是允许改变的量。

变量是用一串固定的字符串去表示不固定的内容。

变量表示命令的内存空间,将数据放在内存空间中,通过变量名引用,获取数据。

变量的作用:
用来存放系统和用户需要使用的特定参数(值)。

变量名:使用固定的名称,由系统预设或用户定义。

变量值:能够根据用户设置、系统环境的变化而变化。

 变量类型
变量赋值: 变量名=变量值(name=value)

bash变量类型:

1、根据变量的生效范围可分为:

环境变量(全局变量):全局生效,在任何bash环境中都可以识别。

局部变量:生效范围为当前shell进程。对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效。

本地变量:生效范围为当前shell进程中某代码片断,通常指函数。 只能在定义它们的函数/脚本内部中使用。

2、根据是否由系统定义可分为:

内置变量:由系统维护,用于设置工作环境。如PS1,PATH,HISTSIZE, HOSTNAME,USER。
自定义变量:由用户自己定义、修改和使用。
3、特殊变量:

环境变量(全局变量):全局生效,在任何bash环境中都可以识别。:

只读变量:read only, 只可以读取不可以更改 。

位置变量: 通过命令行给脚本传递参数 。n(n是正整数),n(n是正整数),n(n是正整数),{10} 要加花括号。

预定义变量:用来保持脚本程序的执行信息。

$0 :当前脚本名称(如果是软链接,显示当前软链接文件名)。
$? :查看上一次命令的执行状态,返回0为正常,非0为错误。
$* :返回所有参数,当整体返回。
$@ :返回所有参数,当个体返回。
$# :获取当前shell命令行中参数的总个数。
$_ :在此之前执行的命令或脚本的最后一个参数。
$$ :获取当前进程的PID。
 变量的命名要求
区分大小写
不能使程序中的保留字和内置变量名称:如:if, for,hostname。
只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反。
使用英文时,尽量使用词义通俗易懂,如PATH。
大驼峰 StudentFirstName
小驼峰 studentFirstName
下划线 student_name
变量作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。

可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。

方法:
法一,设置全局变量:

export name=value
或 declare -x name=value
法二,将局部变量转变为全局变量:export name

环境变量
系统内置环境变量
1、由系统提前创建,用来设置用户的工作环境。

2、使用env命令查看所有环境变量:

需要记住的常用环境变量:

$PATH 表示可执行文件的默认路径
$USER 表示用户名称
$HOME 表示用户的宿主目录
$LANG 表示语言和字符集
$PWD 表示当前所在工作目录
环境变量的特性:
可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
一般只在系统配置文件中使用,在脚本中较少使用。
环境变量的配置文件
自定义的环境变量只是临时生效,退出系统后就会失效。需要将自定义的环境变量放入配置文件中,才会永久生效。配置文件可以用来长期变更或设置环境变量。

全局配置文件:

/etc/profile,修改此文件会作用于所有用户。
用户独立的配置文件:

~/.bash_profile,修改这个文件只作用于当前用户。
只读变量
我们在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。

只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。

定义变量:

第一步:name=value # 定义一个变量
第二步:readonly name # 使用 readonly 来修饰该变量 ,表明只读
位置变量
位置变量也称为位置参数。

使用$n表示,n为数字序列号,且必须为整数。

如:$1、$2、…、$9 、${10}、${11}。

两位数需要加花括号{},不然$10会被识别为:$1和0 。

预定义变量
预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。

可以直接使用这些变量,不能直接为这些变量赋值

变量    作用
$?    表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常。
$*    表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词)
$@    表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体)
$#    表示命令行中位置参数的总个数。
$0    表示当前脚本名称(如果是软链接,显示当前软链接文件名)。
$_    表示在此之前执行的命令或脚本的最后一个参数。
$$    获取当前进程的PID。
$* 和 $@的区别:

不加双引号的话,$* 和 $@ 都代表脚本后面跟的所有参数。
加上双引号的话,"$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待
read 从键盘输入内容为变量赋值
read可以从键盘输入变量值,即将键盘输入的内容变成变量值。

格式: read 变量名

常用选项:

-p:后面跟提示信息,即在输入前打印提示信息。
-s:安静模式,在输入字符时不再屏幕上显示,例如密码。
-t:后面跟秒数,定义输入字符的等待时间。
-n:后跟一个数字,定义输入文本的长度。
-a:后跟一个变量,该变量会被认为是个数组。
四个配置文件的作用
1、/etc/profile 文件

系统级的配置文件,开机时系统自动加载该文件中的配置。

系统每次启动都会自动执行/etc/profile 文件里的命令,这个文件是对全局有效的(所有的shell环境和用户)。

2、~/.bash_ profile 文件

不同用户登录系统时,会自动执行自己家目录中的~/ .bash_ profile 文件中的命令,之后自动执行~/ . bashrc。(因为~/ .bash_ profile文件中规定了,如果~/ . bashrc是个文件,则执行该文件)。

3、~/.bashrc 文件

当前用户每切换一个shell环境都会自动加载~/ . bashrc 文件中的配置 ,之后自动执行/etc/bashrc文件。(因为~/ . bashrc文件中规定了,如果/etc/bashrc是个文件,则执行该文件)。

4、/etc/bashrc 文件

/etc/bashrc针对所有用户,用户每切换一个shell环境都会自动执行。

5、/etc/skel/ 目录

/etc/skel/是用来存放新用户配置文件的目录,当我们添加新用户的时候,这个目录下的所有文件会自动被复制到新添加的用户的家目录下。这个目录下的所有文件都是隐藏文件(以.开头的文件)。

该目录中包括 .bash_logout 、.bash_profile 、.bashrc 这三个配置文件。

 重点总结
1、全局变量和局部变量:

环境变量(全局变量):在当前shell环境和子shell环境(包括孙子shell环境)中都生效。
局部变量:只在当前shell环境中生效,子shell环境中无效。
2、设置、查看和删除变量的命令:

变量赋值:

方法1:变量名=变量值(name=value)
方法2:read 变量名, 之后从键盘输入中获取变量名的值
设置环境变量:export name=value 或 export name

设置只读变量:readonly name 。只读变量不可删除或重新赋值。

查看变量和变量值:

env:查看所有环境变量。
set:查看所有变量,包括局部变量和环境变量。
删除变量:unset name

3、几个符号的作用:

 双引号" ":强引用,识别变量,允许通过$符号引用其他变量值。会把引号的内容当成整体来看待。
 ​
 单引号' ':弱引用,不会识别变量,禁止引用其他变量值,单引号内的内容都会被认为是普通字符。
 ​
 反撇号` ` 和 $() :调用命令执行后输出的结果。如果存在嵌套,不能使用反撇号。
 ​
 花括号{  } :定义变量范围。 
Shell中的算术运算
Shell允许在某些情况下对算术表达式进行求值,比如:let和declare 内置命令,(( ))复合命令和算术扩展。求值以固定宽度的整数进行,不检查溢出。

注意:默认情况下bash只支持整数运算,不支持小数运算。

运算表达式:
(1) expr 变量1 运算符 变量2 [运算符 变量3]...

 (2) let var=算术表达式  

(3) ((var=算术表达式)),和上一个等价

 (4) var=$[算术表达式]

 (5) var=$((算术表达式))

 (6) var=$(expr arg1 arg2 arg3 ...)

 (7) var= `expr arg1 arg2 arg3 ...`

 (8) echo '算术表达式' | bc

运算符:

加法 +
减法 -
乘法 \ *
除法 /
取余 (取模)%
运算法则:

加法: num1 + num2
减法:num1 - num2
乘法:num1 \ * num2
整除:num1 / num2
取余(求模):num1 % num2 (求 num1 除以 num2 的余数)
 运算演示
expr
expr命令是一个手工命令行计数器,用于在UNIX/LINUX下求表达式变量的值,一般用于整数值,也可用于字符串。

变量和运算符之间,要用空格隔开。
用反斜杠 \ 放在 shell 特定的字符前面;
对包含空格和其他特殊字符的字符串要用引号括起来
let 和 (( ))
let var=算术表达式 和 ((var=算术表达式)) 效果等同。

两者都不返回结果,需要借助echo命令。

$[ ]和$(( ))
$[ ] 和 $(( ))效果相同,且都支持对变量进行运算

小数运算(浮点数运算)
使用bc计算器
Bash内置了对整数运算的支持,但是并不支持浮点运算,而 bc 计算器可以很方便的进行浮点运算。

支持交互式和非交互式两种方式。
使用scale=n可以指定精度,即小数点后的位数。要写在算术表达式之前。
非交互式运算,使用 echo "算术表达式" | bc。 多个算术表达式之间用分号隔开,例如:echo '1+1;2+2" | bc。
 使用awk命令
使用awk进行浮点数的运算,运算结果最多显示6个有效数字。

格式:awk "BEGIN{print 算术表达式}"

变量的自增和自减
简写表达式    等同于
let i++    i=$[$i+1]
let i--    i=$[$i-1]
let i+=2    i=$[$i+2]
let i-=2    i=$[$i-2]
let i*=2    i=$[$i*2]
let i/=2    i=$[$i/2]
let i%=2    i=$[$i%2
使用分号,可以在一行执行多个命令。

Linux命令并行执行,顺序执行
1、Linux并行执行命令

在命令之间采用&进行连接

示例:

run1.sh&run2.sh&run3.sh&run4.sh&run5.sh

如果不是脚本而是一个程序块,那么可以采用如下形式来进行:

{程序块内容1}&{程序块内容2}&{程序块内容3}&{程序块内容4}&{程序块内容5}

注:&放在启动参数后面表示设置此进程为后台进程

2、Linux多命令顺序执行

当我们需要一次执行多个命令的时候,命令之间需要用连接符连接,不同的连接符有不同的效果。

(1) ; 分号,没有任何逻辑关系的连接符。当多个命令用分号连接时,各命令之间的执行成功与否彼此没有任何影响,都会一条一条执行下去。

(2) || 逻辑或,当用此连接符连接多个命令时,前面的命令执行成功,则后面的命令不会执行。前面的命令执行失败,后面的命令才会执行。

(3) && 逻辑与,当用此连接符连接多个命令时,前面的命令执行成功,才会执行后面的命令,前面的命令执行失败,后面的命令不会执行,与 || 正好相反。
 

(4) | 管道符,当用此连接符连接多个命令时,前面命令执行的正确输出,会交给后面的命令继续处理。若前面的命令执行失败,则会报错,若后面的命令无法处理前面命令的输出,也会报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值