当前位置 : 主页 > 操作系统 > centos >

Rocky基础-Shell脚本基础知识

来源:互联网 收集:自由互联 发布时间:2022-08-10
1-1、shell 脚本的用途 将简单的命令组合完成复杂的工作,自动化执行命令,提高工作效率减少手工命令的输入,一定程度上避免人为错误将软件或应用的安装及配置实现标准化用于实现日
1-1、shell 脚本的用途

将简单的命令组合完成复杂的工作,自动化执行命令,提高工作效率 减少手工命令的输入,一定程度上避免人为错误 将软件或应用的安装及配置实现标准化 用于实现日常性的,重复性的,非交互式的运维工作,如:文件打包压缩备份,监控系统运行状态并实现告警等

1-2、 shell 脚本基本结构

shell脚本编程:是基于过程式、解释执行的语言 编程语言的基本结构: 各种系统命令的组合 数据存储:变量、数组 表达式:a + b 控制语句:if shell脚本:包含一些命令或声明,并符合一定格式的文本文件 格式要求:首行shebang机制

#!/bin/bash
#!/usr/bin/python
#!/usr/bin/perl
#!/usr/bin/ruby
#!/usr/bin/lua
1-3、shell脚本创建过程

第一步:使用文本编辑器来创建文本文件 第一行必须包括shell声明序列:#! 添加注释,注释以#开头 第二步:加执行权限 给予执行权限,在命令行上指定脚本的绝对或相对路径 第三步:运行脚本 直接运行解释器,将脚本作为解释器程序的参数运行

1-4、shell 脚本注释规范

1、第一行一般为调用使用的语言 2、程序名,避免更改文件名为无法找到正确的文件 3、版本号 4、更改后的时间 5、作者相关信息 6、该程序的作用,及注意事项 7、最后是各版本的更新简要说明

1-5、 shell 脚本调试

只检测脚本中的语法错误,但无法检查出命令错误,但不真正执行脚本

bash -n 脚本

调试并执行

bash -x 脚本

1-6、脚本错误

总结:脚本错误常见的有三种

  • 语法错误,会导致后续的命令不继续执行,可以用bash -n 检查错误,提示的出错行数不一定是准确的
  • 命令错误,默认后续的命令还会继续执行,用bash -n 无法检查出来 ,可以使用 bash -x 进观察
  • 逻辑错误:只能使用 bash -x 进行观察
1-7、变量

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

变量类型

变量类型
内置变量,如:PS1,PATH,UID,HOSTNAME,$$,BASHPID,PPID,$?,HISTSIZE
用户自定义变量
不同的变量存放的数据不同,决定了以下
数据存储方式
参与的运算
表示的数据范围
变量数据类型:
字符
数值:整型、浮点型,bash 不支持浮点数
1-8、Shell中变量命名法则
1-8.1、命名要求

区分大小写 不能使程序中的保留字和内置变量:如:if, for 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反

1-8.2、 命名习惯

见名知义,用英文单词命名,并体现出实际作用,不要用简写,如:ATM 变量名大写 局部变量小写 函数名小写 大驼峰StudentFirstName,由多个单词组成,且每个单词的首字母是大写,其它小写 小驼峰studentFirstName ,由多个单词组成,第一个单词的首字母小写,后续每个单词的字母是大写,其它小写 下划线: student_name

1-8.3、变量定义和引用

变量的生效范围等标准划分变量类型 普通变量:生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效 环境变量:生效范围为当前shell进程及其子进程 本地变量:生效范围为当前shell进程中某代码片段,通常指函数

变量赋值:name='value'

value 可以是以下多种形式
直接字串:name='root'
变量引用:name="$USER"
命令引用:name=`COMMAND` 或者 name=$(COMMAND)

注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除

变量引用:$name 或 ${name}

​ 弱引用和强引用 ​ "name' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串

显示已定义的所有变量:set

删除变量:unset

[root@rocky8 scripts]# CMD=hostname
[root@rocky8 scripts]# $CMD
rocky8.magedu.org

显示已定义的所有变量:set

删除变量:unset 变量名 (变量名不要加$ 加$会报错)

1-8.4、环境变量

环境变量: 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程 一般只在系统配置文件中使用,在脚本中较少使用

变量声明和赋值:

#声明并赋值
export name=VALUE
declare -x name=VALUE
#或者分两步实现
name=VALUE
export name
1-8.5、显示所有环境变量
env
printenv
export
declare -x

查看shell嵌套了几层,即深度

[root@rocky8 scripts]# echo $SHLVL
3
[root@rocky8 scripts]# exit
exit
[root@rocky8 scripts]# exit
exit
[root@rocky8 scripts]# echo $SHLVL
1
1-8.6、只读变量

只读变量:只能声明定义,但后续不能修改和删除,即常量 声明只读变量:

readonly name
declare -r name

查看只读变量:

readonly [-p]
declare -r
1-8.7、位置变量

位置变量:在bash shell中内置的变量, 在脚本代码中调用通过命令行传递给脚本的参数

$1, $2, ... 对应第1个、第2个等参数,shift [n]换位置
$0 命令本身,包括路径
$* 传递给脚本的所有参数,全部参数合为一个字符串
$@ 传递给脚本的所有参数,每个参数为独立字符串
$# 传递给脚本的参数的个数
注意:$@ $* 只在被双引号包起来的时候才会有差异

清空所有位置变量 set --

1-8.8、$? 查看退出状态码变量
$?的值为0 #代表成功
$?的值是1到255 #代表失败

用户可以在脚本中使用以下命令自定义退出状态码 exit [n]

注意: 脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字

如果exit后面无数字,终止退出状态取决于exit命令前面命令执行结果

如果没有exit命令, 即未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码

1-8.9、展开命令行

展开命令执行顺序

把命令行分成单个命令词
展开别名
展开大括号的声明{}
展开波浪符声明 ~
命令替换$() 和 ``
再次把命令行分成命令词
展开文件通配符*、?、[abc]等等
准备I/0重导向 <、>
运行命令反斜线(\)会使随后的字符按原意解释
单引号(’’)防止所有扩展
双引号(”“)也可防止扩展,但是以下情况例外:$(美元符号)
`` : 反引号,命令替换
\:反斜线,禁止单个字符扩展
!:叹号,历史命令替换
1-8.10、脚本安全和 set

$- 变量 h:hashall,打开选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。通过set +h将h选项关闭 i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell,在脚本中,i选项是关闭的 m:monitor,打开监控模式,就可以通过Job control来控制进程的停止、继续,后台或者前台执行等 B:braceexpand,大括号扩展 H:history,H选项打开,可以展开历史列表中的命令,可以通过!感叹号来完成,例如“!!”返回上最近的一个历史命令,“!n”返回第 n 个历史命令

[root@rocky8 scripts]# set +B
[root@rocky8 scripts]# echo {1..10}
{1..10}
[root@rocky8 scripts]# set -B
[root@rocky8 scripts]# echo {1..10}
1 2 3 4 5 6 7 8 9 10
[root@rocky8 scripts]# echo $-
himBHs
[root@rocky8 scripts]# set +h
[root@rocky8 scripts]# hash
-bash: hash: hashing disabled
[root@rocky8 scripts]# set -h
[root@rocky8 scripts]# hash
hits command
1 /usr/bin/hostname
1 /usr/bin/bash
1-8.11、set 命令实现脚本安全

-u 在扩展一个没有设置的变量时,显示错误信息, 等同set -o nounset -e 如果一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit -o option 显示,打开或者关闭选项 显示选项:set -o 打开选项:set -o 选项 关闭选项:set +o 选项 -x 当执行命令时,打印命令及其参数,类似 bash -x

1-9、格式化输出 printf
printf "指定的格式" "文本1" ”文本2“ ......

常用格式替换符

替换符 功能
%s 字符串
%d,%i 十进制整数
%f 浮点格式
%c ASCII字符,即显示对应参数的第一个字符
%b 相对应的参数中包含转义字符时,可以使用此替换符进行替换,对应的转义字符会被转义
%o 八进制值
%u 不带正负号的十进制值
%x 十六进制值(a-f)
%X 十六进制值(A-F)
%% 表示%本身%#s 中的数字代表此替换符中的输出字符宽度,不足补空格,默认是右对齐,%-10s表示10个字符宽,- 表示左对齐
%03d 表示3位宽度,不足前面用0补全,超出位数原样输出
%.2f 中的2表示小数点后显示的小数位数转义符 功能
\a 警告字符,通常为ASCII的BEL字符
\b 后退
\f 换页
\n 换行
\r 回车
\t 水平制表符
\v 垂直制表符
\ 表示\本身

例:

[root@rocky8 scripts]# printf "%10s \n" 1 2 3 4
1
2
3
4
[root@rocky8 scripts]# printf "%10s %10s\n" 1 2 3 4
1 2
3 4
[root@rocky8 scripts]# printf "%10s %10s\n" {1..10}
1 2
3 4
5 6
7 8
9 10
[root@rocky8 scripts]# printf "%10s %10.2f\n" {1..10}
1 2.00
3 4.00
5 6.00
7 8.00
9 10.00
[root@rocky8 scripts]# printf "(%s) (%s) \n" {1..10}
(1) (2)
(3) (4)
(5) (6)
(7) (8)
(9) (10)
[root@rocky8 scripts]# Var="Welcome to magedu";printf "\033[1;32m%s\033[0m\n" $Var
Welcome
to
magedu
1-10、算术运算

Shell允许在某些情况下对算术表达式进行求值,比如:let和declare 内置命令,(( ))复合命令和算术扩展。求值以固定宽度的整数进行,不检查溢出,尽管除以0 被困并标记为错误。运算符及其优先级,关联性和值与C语言相同。以下运算符列表分组为等优先级运算符级别。级别按降序排列优先。

注意:bash 只支持整数,不支持小数。乘法符号有些场景中需要转义

+ - addition, subtraction
* / % multiplication, division, remainder, %表示取模,即取余数,示例:9%4=1,5%3=2
i++ i-- variable post-increment and post-decrement
++i --i variable pre-increment and pre-decrement
= *= /= %= += -= <<= >>= &= ^= |= assignment
- + unary minus and plus
! ~ logical and bitwise negation
** exponentiation 乘方,即指数运算
<< >> left and right bitwise shifts
<= >= < > comparison
== != equality and inequality
& bitwise AND
| bitwise OR
^ bitwise exclusive OR
&& logical AND
|| logical OR
expr?expr:expr c onditional operator
expr1 , expr2 comma算术运算
(1) let var=算术表达式
(2) ((var=算术表达式)) 和上面等价
(3) var=$[算术表达式]
(4) var=$((算术表达式))
(5) var=$(expr arg1 arg2 arg3 ...)
(6) declare -i var = 数值
(7) echo '算术表达式' | bc

内建的随机数生成器变量:$RANDOM 取值范围:0-32767

增强型赋值

+= i+=10 相当于 i=i+10
-= i-=j 相当于 i=i-j
*=
/=
%=
++ i++,++i 相当于 i=i+1
-- i--,--i 相当于 i=i-1[root@rocky8 scripts]# i=0
[root@rocky8 scripts]# echo $i
0
[root@rocky8 scripts]# echo $[++i]
1
[root@rocky8 scripts]# i=0
[root@rocky8 scripts]# let i++
[root@rocky8 scripts]# echo $i
1

[root@rocky8 scripts]# i=20
[root@rocky8 scripts]# let i+=30
[root@rocky8 scripts]# echo $i
50
[root@rocky8 scripts]# j=40
[root@rocky8 scripts]# let i*=j
[root@rocky8 scripts]# echo $i:$j
2000:40
1-11、逻辑运算
与或非
1,真 true
0,假 false

与:& 和0相与结果为0,和1相与结果保留原值, 一假则假,全真才真

0 与 0 = 0
0 与 1 = 0
1 与 0 = 0
1 与 1 = 1

或:| 和1相或结果为1,和0相或结果保留原值,一真则真,全假才假

0 或 0 = 0
0 或 1 = 1
1 或 0 = 1
1 或 1 = 1

非:!

! 1 = 0 ! true
! 0 = 1 ! false

异或:^ 异或的两个值,相同为假,不同为真。两个数字X,Y异或得到结果Z,Z再和任意两者之一X异或,将得出另一个值Y

0 ^ 0 = 0
0 ^ 1 = 1
1 ^ 0 = 1
1 ^ 1 = 0
1-12、短路运算

短路与 &&

CMD1 && CMD2
第一个CMD1结果为真(1),第二个CMD2必须要参与运算,才能得到最终的结果
第一个CMD1结果为假(0),总的结果必定为0,因此不需要执行CMD2

短路或 ||

CMD1 || CMD2
第一个CMD1结果为真(1),总的结果必定为1,因此不需要执行CMD2
第一个CMD1结果为假(0),第二个CMD2 必须要参与运算,才能得到最终的结果

短路与和或组合

CMD1 && CMD2 || CMD3 (类似双分支if语句:如果第一个命令执行成功,则执行第二个命令,否则执行第三个命令)
当CMD1执行成功时,会执行CMD2
当CMD1执行失败时,会执行CMD3
注意: CMD1 || CMD2 && CMD3 逻辑不通,不使用
1-13、条件测试命令

条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成 测试过程,实现评估布尔声明,以便用在条件性环境下进行执行 若真,则状态码变量 $? 返回0 若假,则状态码变量 $? 返回1 条件测试命令 test EXPRESSION [ EXPRESSION ] #和test 等价,建议使用 [ ]
[[ EXPRESSION ]] 相关于增强版的 [ ], 支持[]的用法,且支持扩展正则表达式和通配符 注意:EXPRESSION前后必须有空白字符

1-14、变量测试

\#判断 NAME 变量是否定义 [ -v NAME ] \#注意 [ ] 中需要空格,否则会报错

1-15、数值测试
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-ge 是否大于等于
-lt 是否小于
-le 是否小于等于[root@rocky8 scripts]# i=10;j=20
[root@rocky8 scripts]# [ $i -gt $j ]
[root@rocky8 scripts]# echo $?
1
1-16、算术表达式
== 相等
!= 不相等
<=
>=
<
>[root@rocky8 scripts]# (( i == j ))
[root@rocky8 scripts]# echo $?
1
[root@rocky8 scripts]# (( i <= j ))
[root@rocky8 scripts]# echo $?
0
1-17、字符串测试
## test和 [ ] 字符串测试用法
-z STRING 字符串是否为空,没定义或空为真,不空为假,
-n STRING 字符串是否不空,不空为真,空为假
STRING 同上
STRING1 = STRING2 是否等于,注意 = 前后有空格
STRING1 != STRING2 是否不等于
> ascii码是否大于ascii码
< 是否小于
## [[]] 字符串测试用法
[[ expression ]] 用法
== 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符
=~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[ ]]中为扩展的正则表达式
# 建议:当使用正则表达式或通配符使用[[ ]],其它情况一般使用 [ ]
1-18、文件测试
1-18.1、存在性测试
-a FILE:同 -e
-e FILE: 文件存在性测试,存在为真,否则为假
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或 -L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
1-18.2、文件权限测试
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限

注意:最终结果由用户对文件的实际权限决定,而非文件属性决定

1-18.3、文件属性测试
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主
-G FILE #当前有效用户是否为文件属组
FILE1 -ef FILE2 #FILE1是否是FILE2的硬链接
FILE1 -nt FILE2 #FILE1是否新于FILE2(mtime)
FILE1 -ot FILE2 #FILE1是否旧于FILE2
1-19、关于 () 和 {}

(CMD1;CMD2;...)和 { CMD1;CMD2;...; } 都可以将多个命令组合在一起,批量执行

( list ) 会开启子shell,并且list中变量赋值及内部命令执行后,将不再影响后续的环境帮助参看:man bash 搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境帮助参看:man bash 搜索{ list; }
1-20、组合测试条件
[ EXPRESSION1 -a EXPRESSION2 ] #并且,EXPRESSION1和EXPRESSION2都是真,结果才为真
[ EXPRESSION1 -o EXPRESSION2 ] #或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为真
[ ! EXPRESSION ] #取反COMMAND1 && COMMAND2 #并且,短路与,代表条件性的AND THEN 如果COMMAND1 成功,将执行COMMAND2,否则,将不执行COMMAND2
COMMAND1 || COMMAND2 #或者,短路或,代表条件性的OR ELSE 如果COMMAND1 成功,将不执行COMMAND2,否则,将执行COMMAND2
! COMMAND #非,取反[ $[RANDOM%6] -eq 0 ] && echo "rm -rf /*" || echo "hahahahahah"
1-21、使用read命令来接受输入

使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每个单词分配一个变量,所有剩余单词都被分配给最后一个变量,如果变量名没有指定,默认标准输入的值赋值给系统内置变量REPLY

格式:read [options] [name ...]

-p 指定要显示的提示
-s 静默输入,一般用于密码
-n N 指定输入的字符长度N
-d '字符' 输入结束符
-t N TIMEOUT为N秒
1-22、bash shell 的配置文件

按生效范围划分两类

全局配置:针对所有用户皆有效

/etc/profile /etc/profile.d/*.sh /etc/bashrc

个人配置:只针对特定用户有效

~/.bash_profile ~/.bashrc

shell登录两种方式分类

交互式登录

直接通过终端输入账号密码登录 使用 su - UserName 切换的用户

配置文件生效和执行顺序:

#放在每个文件最前
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
~/ .bash_ profile
~/ .bashrc
/etc/bashrc
#放在每个文件最后
/etc/profile.d/*.sh
/etc/bashrc
/etc/profile
/etc/bashrc #此文件执行两次
~/.bashrc
~/.bash_profile
注意:文件之间的调用关系,写在同一个文件的不同位置,将影响文件的执行顺序

非交互式登录

su UserName 图形界面下打开的终端 执行脚本 任何其它的bash实例

执行顺序:

/etc/profile.d/*.sh
/etc/bashrc
~/.bashrc

按功能划分分类

Profile类

profile类为交互式登录的shell提供配置

全局:/etc/profile, /etc/profile.d/*.sh

个人:~/.bash_profile

功用: (1) 用于定义环境变量 (2) 运行命令或脚本

Bashrc类

bashrc类:为非交互式和交互式登录的shell提供配置

全局:/etc/bashrc 个人:~/.bashrc

功用: (1) 定义命令别名和函数 (2) 定义本地变量

编辑配置文件生效

修改profile和bashrc文件后需生效两种方法:

重新启动shell进程

source|. 配置文件

注意:source 会在当前shell中执行脚本,所有一般只用于执行置文件,或在脚本中调用另一个脚本的场景

Bash 退出任务

保存在~/.bash_logout文件中(用户),在退出登录shell时运行

功能: 创建自动备份 清除临时文件

2、IF语句

格式:

if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else
COMMANDS; ] fi 单分支if 判断条件;then
条件为真的分支代码
fi

双分支

if 判断条件; then
条件为真的分支代码
else
条件为假的分支代码
fi

多分支

if 判断条件1; then
条件1为真的分支代码
elif 判断条件2; then
条件2为真的分支代码
elif 判断条件3; then
条件3为真的分支代码
...
else
以上条件都为假的分支代码
fi

说明: 多个条件时,逐个条件进行判断,第一次遇为“真”条件时,执行其分支,而后结束整个if语句 if 语句可嵌套

3、 case 语句

格式:

case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esaccase 变量引用 in
PAT1)
分支1
;;
PAT2)
分支2
;;
...
*)
默认分支
;;
esac

case支持glob风格的通配符:

* 任意长度任意字符
? 任意单个字符
[] 指定范围内的任意单个字符
| 或者,如: a|b
4、for循环

将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件重复运行次数 循环次数事先已知 循环次数事先未知 常见的循环的命令:for, while, until

格式:

for NAME [in WORDS ... ] ; do COMMANDS; done
#方式1
for 变量名 in 列表;do
循环体
done
#方式2
for 变量名 in 列表
do
循环体
done

执行机制

依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束 如果省略 [in WORDS ... ] ,此时使用位置参数变量 in "$@"

for 循环列表生成方式

直接给出列表 整数列表:

{start..end}
$(seq [start [step]] end)

返回列表的命令:

$(COMMAND)

使用glob,如:*.sh
变量引用,如:$@,$*,$#
5、while循环

格式:

while COMMANDS; do COMMANDS; done
while CONDITION; do
循环体
done

说明: CONDITION:循环控制条件;进入循环之前,先做一次判断;每一次循环之后会再次做判断;条件为“true”,则执行一次循环;直到条件测试状态为“false”终止循环,因此:CONDTION一般应该有循环 控制变量;而此变量的值会在循环体不断地被修正 进入条件:CONDITION为 true 退出条件:CONDITION为 false

无限循环

while true; do
循环体
done
while : ; do
循环体
done
5.1 while 特殊用法 while read

while 循环的特殊用法,遍历文件或文本的每一行

while read line; do
循环体
done < /PATH/FROM/SOMEFILE
说明:依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line
6、 until循环
until COMMANDS; do COMMANDS; done
until CONDITION; do
循环体
done

说明: 进入条件: CONDITION 为false 退出条件: CONDITION 为true

无限循环

until false; do
循环体
Done
7、循环控制语句 continue

continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

8、循环控制语句 break

break [N]:提前结束第N层整个循环,最内层为第1层

9、循环控制 shift 命令

shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。 参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,常用到 shift

10、select
select NAME [in WORDS ... ;] do COMMANDS; done
select NAME in list ;do
循环体命令
done

select 循环主要用于创建菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示符,等待用户输入
用户输入菜单列表中的某个数字,执行相应的命令
用户输入菜单列表中的某个数字,会将对应的WORD值赋值给NAME变量
用户输入被保存在内置变量 REPLY 中
select 是个无限循环,因此要用 break 命令退出循环,或用 exit 命令终止脚本。也可以按 ctrl+c退出循环
select 经常和 case 联合使用与 for 循环类似,可以省略 in list,此时使用位置参量
11、函数 function

函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程 它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运行,而是shell程序的一部分

函数和shell程序区别 Shell程序在子Shell中运行 函数在当前Shell中运行。因此在当前Shell中,函数可对shell中变量进行修改

#查看当前已定义的函数名
declare -F
#查看当前已定义的函数定义
declare -f
#查看指定当前已定义的函数名
declare -f func_name
#查看当前已定义的函数名定义
declare -F func_name
#删除函数
unset func_name

调用:函数只有被调用才会执行,通过给定函数名调用函数,函数名出现的地方,会被自动替换为函数代码 函数的生命周期:被调用时创建,返回时终止

可在交互式环境下定义函数 可将函数放在脚本文件中作为它的一部分 可放在只包含函数的单独文件中

在脚本中定义及使用函数

函数在使用前必须定义,因此应将函数定义放在脚本开始部分,直至shell首次发现它后才能使用,调用函数仅使用其函数名即可

使用函数文件

可以将经常使用的函数存入一个单独的函数文件,然后将函数文件载入shell,再进行调用函数 函数文件名可任意选取,但最好与相关任务有某种联系,例如:functions 一旦函数文件载入shell,就可以在命令行或脚本中调用函数。可以使用delcare -f 或set 命令查看所有定义的函数,其输出列表包括已经载入shell的所有函数 若要改动函数,首先用unset命令从shell中删除函数。改动完毕后,再重新载入此文件 实现函数文件的过程:

  • 创建函数文件,只存放函数的定义
  • 在shell脚本或交互式shell中调用函数文件,格式如下
  • . filename
    source filenam

    函数返回值

    函数的执行结果返回值: 使用echo等命令进行输出 函数体中调用命令的输出结果 函数的退出状态码: 默认取决于函数中执行的最后一条命令的退出状态码 自定义退出状态码,其格式为: return 从函数中返回,用最后状态命令决定返回值 return 0 无错误返回 return 1-255 有错误返回

    环境函数

    类拟于环境变量,也可以定义环境函数,使子进程也可使用父进程定义的函数

    export -f function_name
    declare -xf function_name

    export -f
    declare -xf

    函数参数

    函数可以接受参数: 传递参数给函数:在函数名后面以空白分隔给定参数列表即可,如:testfunc arg1 arg2 ... 在函数体中当中,可使用$1, @, $*, $#等特殊变量

    函数变量

    变量作用域: 普通变量:只在当前shell进程有效,为执行脚本会启动专用子shell进程;因此,本地变量的作用范围是当前shell脚本程序文件,包括脚本中的函数 环境变量:当前shell和子shell有效 本地变量:函数的生命周期;函数结束时变量被自动销毁

    注意: 如果函数中定义了普通变量,且名称和局部变量相同,则使用本地变量 由于普通变量和局部变量会冲突,建议在函数中只使用本地变量

    在函数中定义本地变量的方法

    local NAME=VALUE

    函数递归

    函数递归:函数直接或间接调用自身,注意递归层数,可能会陷入死循环

    #递归特点:
    函数内部自已调用自已
    必须有结束函数的出口语句,防止死循环
    12、信号捕捉 trap

    trap 命令可以捕捉信号,修改信号原来的功能,实现自定义功能

    #进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操作
    trap '触发指令' 信号
    #忽略信号的操作
    trap '' 信号
    #恢复原信号的操作
    trap '-' 信号
    #列出自定义信号操作
    trap -p
    #当脚本退出时,执行finish函数
    trap finish EXIT
    13、创建临时文件 mktemp

    mktemp 命令用于创建并显示临时文件,可避免冲突

    mktemp [OPTION]... [TEMPLATE]
    说明:TEMPLATE: filenameXXX,X至少要出现三个
    -d #创建临时目录
    -p DIR或--tmpdir=DIR #指明临时文件所存放目录位置
    14、安装复制文件 install

    install 功能相当于cp,chmod,chown,chgrp ,mkdir 等相关工具的集合 install命令格式:

    install [OPTION]... [-T] SOURCE DEST 单文件
    install [OPTION]... SOURCE... DIRECTORY
    install [OPTION]... -t DIRECTORY SOURCE...
    install [OPTION]... -d DIRECTORY... #创建空目录
    -m MODE,默认755
    -o OWNER
    -g GROUP
    -d DIRNAME 目录
    15、交互式转化批处理工具 expect

    expect 是由Don Libes基于 Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式操作的场景,借助 expect 处理交互的命令,可以将交互过程如:ssh登录,ftp登录等写在一个脚本上,使之自动化完成。尤其适用于需要对多台服务器执行相同操作的环境中,可以大大提高系统管理人员的工作效率

    安装expect 及mkpasswd 工具

    yum -y install expectexpect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]

    -c:从命令行执行expect脚本,默认expect是交互地执行的
    -d:可以调试信息

    expect -c 'expect "\n" {send "pressed enter\n"}'
    expect -d ssh.exp

    expect中相关命令 spawn 启动新的进程 expect 从进程接收字符串 send 用于向进程发送字符串 interact 允许用户交互 exp_continue 匹配多个字符串在执行动作后加此命令 expect最常用的语法(tcl语言:模式-动作)

    上一篇:mysql函数汇总之日期和时间函数
    下一篇:没有了
    网友评论