-
SHELL脚本
-
- 编程语言的分类
-
解释型语言:shell,Python,需要解析器
-
编译型语言:C语言,C++,需要编译器
-
-
shell脚本
-
操作系统的结构
-
shell(贝壳)
-
应用层
-
app,代码
-
应用层需要通过shell完成和内核的交互
-
-
-
内核层
-
设备管理
-
文件管理
-
网络管理
-
进程管理
-
内存管理
-
-
硬件层
-
外部设备
-
-
-
-
第一个shell脚本
-
shell脚本的本质: 指令的集合
-
C语言文件 .c
-
shell文件 .sh
-
C++文件 .cpp
-
-
-
#!/bin/bash
-
#!用于指明该脚本默认使用shell解析器
-
说明使用的是shell解析器
-
-
echo hello
-
输出hello
-
echo 打印指令将hello输出
-
-
-
#
-
在shell中表示注释
-
-
-
执行脚本的三种方式
-
bash 文件名
-
通过解析器,直接解析脚本
-
bash 1.sh
-
执行过程:在后台打开一个终端
-
-
-
直接运行脚本
-
需要给脚本添加可执行权限
-
chmod 777 1.sh
-
直接在终端输入1.sh
-
-
-
source 脚本名
-
前台打开一个终端,执行脚本和返回脚本都在当前终端
-
-
-
-
修改环境变量
-
查看已有的特殊系统变量
-
env
-
-
查看环境变量
-
echo $PATH
-
环境变量的作用:当在终端直接运行指令时,去默认环境变量保存的路径中查找指令,如果没找到该指令不能执行
-
-
修改环境变量
-
只对当前终端有效
-
export PATH = ${PATH}:/home/ubunutu
-
export : 给系统变量赋值
-
PATH:被赋值的变量
-
=:赋值
-
${PATH} : 拿到之前PATH的值
-
::分隔
-
/home/ubuntu:添加的路径
-
-
代码运行的作用:在当前终端给PATH添加了一个/home/ubuntu路径
-
-
只对当前用户有效
-
修改家目录下的~/.bashrc文件
-
由于是当前用户下的家目录,所以不需要加sudo
-
-
vim ~/.bashrc
-
然后将export表达式添加到文件的尾部
-
-
修改文件后需要运行文件才能生效
-
source ~/.bashrc
-
重启虚拟机
-
-
-
对所有用户生效
-
修改/etc/enviroment
-
sudo vim /etc/enviroment
-
只有一行PATH的信息,想要添加的路径
-
-
-
修改/etc/bash.bashrc文件
-
sudo vim /etc/bash.bashrc
-
使用export表达式,添加路径
-
-
-
-
-
-
shell中的变量
-
shell中的变量没有数据类型的区别,shell是一种弱数据类型语言,都当字符串处理
-
格式:
-
变量名 = ‘变量的值’
-
用于变量值内有空格时,无$获取变量的值
-
-
变量名 = “变量的值”
-
可以$变量的展开
-
-
变量名 = 变量的值
-
= 号两侧不能有空格
-
-
-
获取变量
-
$变量名
-
${变量名}
-
为了更好的区分变量名的范围
-
-
-
修饰变量的关键字
-
readonly
-
只读变量,值不能更改
-
-
unset
-
清空变量的值,不能清空readonly修饰的值
-
-
local
-
定义局部变量(只能在函数中使用)
-
-
-
外部传参/位置变量
-
和C语言相同,脚本也可以在执行时进行外部传参,shell中通过位置变量获取参数
-
$0
-
获取脚本名
-
-
$n
-
获取第n个外部参数
-
n>10时需在n外加上大括号,否则只能读取一位
-
-
-
$#
-
获取所有外部参数的个数
-
-
$*/$@
-
获取所有的外部参数
-
-
-
输出
-
echo
-
echo 输出内容(将内容回显到终端,并自动换行)
-
echo默认不解析转义字符
-
echo -n 输出内容
-
取消echo输出时的换行
-
-
echo -e "hello\n"
-
解析转义字符
-
-
-
-
指令的格式:指令 参数 操作数
-
有些指令也支持:指令 操作数 参数
-
echo 不支持
-
-
指令的标准格式
-
-
输入
-
复习:C中使用scanf、gets、getchar需要变量的地址
-
shell中使用read指令完成输出
-
read
-
read 变量名
-
直接加变量名即可,可以读入带空格的数据
-
-
read -p "提示信息" 变量名
-
在终端给用户输出提示信息
-
-
read -s 变量名
-
输入的信息不回显
-
-
read -t 秒数 变量名
-
如果n秒用户不输入,就结束输入向后执行语句
-
-
read -n 个数 变量名
-
如果输入n个字符,自动停止
-
-
-
-
命令置换符
-
作用:获取指令的执行结果
-
`命令` (反引号)
-
$(命令)
-
-
-
shell中的数组
-
shell中支持稀疏数组
-
定义
-
数组名=(初始值1 初始值2 初始值3 ····)
-
#shell中的数组,不需要写出数组长度
-
#shell中数组初始化时,直接使用()
-
#shell中的数组每个元素之间是空格不是逗号
-
#访问仍然通过下标访问,并且下标仍然从0开始
-
数组名=([下标]=初始值 [下标]=初始值 ····)
-
下标可以不连续
-
-
-
访问数组中的元素
-
${数组名[下标]}
-
获取数组中指定下标的元素的值
-
-
要在shell中需要使用变量的值,都要用$进行访问
-
-
获取数组中元素的个数
-
${#数组名[*/@]}
-
获取数组中已经赋值的元素的个数
-
-
${#数组名[下标]}
-
获取数组中指定下标元素的长度(字符个数)
-
-
-
稀疏数组
-
下标不连续的数组
-
稀疏数组中元素的个数,由不为空的数据的个数决定
-
数组名=([下标]=初始值 [下标]=初始值 ····)
-
下标可以不连续 初始值可以是任意字符/串
-
-
-
使用已有的数组给新的数组赋值
-
arr=(1 2 3 4 5) arr1=(a b c d) #定义一个arr2数组使用已有的arr和arr1数组赋值 arr2=(${arr1[*]} ${arr[*]}) #拼接加空格 echo ${arr2[*]} echo ${#arr2[*]}
-
拼接时两个数组中间没有加空格, 第一个数组中的对后一个元素和第二个数组中的第一个元素会被拼接到一起
-
拼接时两个数组中间加空格,两个数组独立起来拼接
-
-
-
-
shell中的运算
-
shell本身不擅长运算,需要借助运算符和其他指令
-
(())
-
常用于shell中的整数算术运算
-
(())几乎支持所有的C语言语法
-
((表达式1,表达式2,表达式3,·······)) 每一个表达式都会执行,获取最右侧一个表达式的结果
-
想要获取运算的结果,需要使用$(()),还可以((变量名=表达式))
-
在(())中,使用变量的值,可以加$也可以不加$ (建议在(())直接使用变量的值,不加$)
-
在(())中,运算符两侧可以有空格
-
-
$[]
-
变量名=$[表达式1,表达式2,表达式3,·······]只获取最右侧表达式的结果
-
使用变量时,可以加$也可以不加$
-
运算符两侧可以加空格,也可以不加空格
-
$[]的结果,建议直接按照"变量名=$[]"格式接收,因为$[]本质上,会遗留一个运算结果在表达式的位置,如果不接受继续向后运行指令会报错
-
-
let
-
let 变量名=表达式
-
let和变量名中间一定要有空格
-
-
let中使用变量,可以加$也可以不加$
-
let运算时,运算符两侧一定不能有空格
-
如果直接写成 let 表达式,表达式会运行,但是没有返回值
-
-
expr
-
格式:expr 表达式
-
是一个终端指令
-
故而expr中使用变量,必须加$
-
-
如果想要接收expr的结果,必须使用命令置换符
-
expr中运算符两侧必须有空格,不支持自增、自减和shell中的幂运算
-
expr中使用某些运算符时,需要转义|、>、<、.、······ (不需要记转义字符,简单的指令在运行前,去终端里运行一下指令,没结果就加上转义字符)
-
expr指令的结果,可以直接回显到终端上,故使用命令置换符接收回显值
-
expr操作数的值不能为空
-
如果expr的操作数为空会报语法错误
-
-
expr进行整数算术运算
-
expr(字符串运算)
-
match 字符串 表达式
-
返回表达式,在字符串中第一个位置起完全匹配成功的字符个数,如果能够匹配成功,返回值就是表达式中字符的个数
-
expr match "$str1" $str2
-
由于str1中有空格,需用双引号引起来
-
-
str2不能在str1中的第一个位置开始完全匹配返回0
-
-
substr 字符串 偏移量 长度
-
从字符串中偏移量的位置开始 截取指定长度的字串,偏移量从1开始
-
expr substr "$str1" 7 5
-
截取出字符串的子串world
-
substr : 字符串的子串
-
-
-
index 字符串 字符
-
返回字符在字符串中第一次被查找到时的下标,下标从1开始
-
expr index "$str1" el
-
返回下标2
-
index:指标
-
-
如果查找多个字符在字符串中的位置 返回最先出现的字符的位置
-
-
length 字符串
-
返回字符串的长度
-
expr length "$str1"
-
-
-
-
-
if 分支结构
-
shell中的if语句格式
-
单分支结构
-
if [ test语句 ] then 语句块 fi
-
-
双分支结构
-
if [ test语句 ] then 语句块 else 不满足条件执行的语句 fi
-
-
多分支结构
-
if [ test语句1 ] then 满足语句1执行的语句块 elif [ test语句2 ] ------> elif test 表达式 then 不满足语句1满足语句2执行的语句 else 两个都不满足语句块 fi
-
-
-
if对整数进行判断
-
ARG1 -eq ARG2: ARG1和ARG2相等
-
-eq : INTEGER1 is equal to INTEGER2
-
-
ARG1 -ge ARG2: ARG1>=ARG2
-
-ge : INTEGER1 is greater than or equal to INTEGER2
-
-
ARG1 -gt ARG2: ARG1>ARG2
-
-gt : INTEGER1 is greater than INTEGER2
-
-
ARG1 -le ARG2: ARG1<=ARG2
-
-le : INTEGER1 is less than or equal to INTEGER2
-
-
ARG1 -lt ARG2: ARG1<ARG2
-
-lt : INTEGER1 is less than INTEGER2
-
-
ARG1 -ne ARG2: ARG!=ARG2
-
-ne : INTEGER1 is not equal to INTEGER2
-
-
-
if对字符串进行判断
-
-n string
-
字符串长度不为零
-
-
-z string
-
字符串长度为零
-
-
str1 = str2
-
str1 != str2
-
-
if对文件进行判断
-
FILE1 -ef FILE2
-
FILE1 and FILE2 have the same device and inode numbers
-
-
FILE1 -nt FILE2
-
FILE1 is newer (modification date) than FILE2
-
-
FILE1 -ot FILE2
-
-ot :FILE1 is older than FILE2
-
-
-b FILE:文件存在且是一个块设备文件
-
-c FILE:文件存在且是一个字符设备文件
-
-d FILE:文件存在且是一个目录设备文件
-
-f FILE:文件存在且是一个普通文件
-
-h\-L FILE:文件存在且为软链接文件
-
lin
-
-
-S FILE:文件存在且是一个套接字文件
-
-e FILE:文件存在
-
equal
-
-
-s FILE:文件存在且大小不为0
-
-p FILE:文件存在且是一个管道文件
-
-w FILE:文件存在且有可写权限
-
-r FILE:文件存在且有可读权限
-
-x FILE:文件存在且有可执行权限
-
-
-
case in分支结构
-
格式
-
case $变量名 in 常量1) 语句 ;; 常量2) 语句 ;; ······ 常量n) 语句 ;; *) 语句 esac
-
$变量名
-
通过输入的变量,进入不同的 “常量)”分支
-
-
;;
-
和C中break的作用相同,shell中必须写;; (除非是最后一个分支)
-
-
*)
-
起到通配符的作用,可以通配所有情况 shell中*)分支必须是最后一条分支
-
-
-
-
1):如果变量的值为1
-
1|2|3|4): 值为1或2或3或4都走该分支
-
[0-9]):0-9中的值都走该分支 不能写两位数,都是对单字符的判断
-
1?):1开头两个字符一个确定一个不确定的情况
-
-
循环结构
-
while循环结构
-
格式
-
while [ test语句 ] do 语句块 done
-
while [ test语句 ] == while test 表达式
-
[] 中输入的语句需要用空格与中括号隔开
-
-
-
-
for循环结构
-
shell格式1(类似C语言)
-
类似于C语言的格式 for ((表达式1;表达式2;表达式3)) do 循环体 done
-
执行逻辑和C语言一致
-
-
-
shell格式2(自己的格式)
-
for 变量名 in 字符串列表 do 循环体 done
-
执行逻辑
-
循环变量i从in后面提供的字符串列表中,按顺序取值
-
循环次数和字符串列表中字符串的个数有关
-
直到i把字符串列表中每一个字符串的值都获取结束后,循环结束,(i为获取的值)
-
-
-
-
使用连续列表的情况
-
seq 起始值 间隔值 终止值
-
终端回显起始值到终止值之间的数
-
故使用时需用指令置换符
-
-
{1..3}
-
在bash编译器中遍历1-3中的每一个数 可以用在for中,单独使用不能回显在终端
-
{起始值..终止值}
-
间隔值默认为1
-
中间只能写两个点
-
-
-
-
-
select···in循环结构
-
格式
-
select 变量名 in 选项列表 do 语句块 done
-
-
执行逻辑
-
会在终端打印选项列表 用户需要根据选项前面的序号做出选择 选择后变量会获取到相应的值 如果用户不做选择,会再次打印选项列表 如果用户选错,获取到空值
-
-
常和case语句使用
-
在select···in语句中,嵌套case···in语句, 可以根据用户的不同选择,使用case···in完成不同的处理
-
-
-
辅助控制关键字
-
break n
-
跳出n层循环
-
-
continu n
-
退出第n层本次循环
-
退出n层本次循环,跳出n层循环时,只需要看第n层循环是否有下一次即可
-
-
-
-
-
shell中的函数
-
格式:(function)函数名() { 函数体 return 返回值 }
-
function 可加可不加
-
shell中的函数仍然满足先定义后调用
-
shell函数中是否还有返回值,根据实际的实现来决定
-
返回值只能是(0~255)
-
-
调用函数
-
()内必须为空,不能写任何内容
-
直接通过函数名调用函数
-
函数名
-
fun
-
-
函数调用后其内部的定义变量才能被调用
-
-
如何获取函数的外部参数
-
如果函数需要外部传参
-
函数名 参数1 参数2 参数3 ·····
-
fun 12 34
-
调用函数fun
-
-
-
通过外部传参获取两个数,计算两数和
-
先调用函数,并输入外部参数
-
-
函数内部仍然通过$获取外部参数
-
n大于等于10时需用${10}
-
-
函数内部使用$1 $2
-
获取12和23 两个外部参数
-
-
在函数外可以访问函数内的变量(全局变量),但需要函数被调用后访问
-
函数内和脚本内的外部参数获取互不影响
-
在函数内使用位置变量,获取的是函数的外部参数
-
在脚本中使用位置变量,获取的是脚本的外部参数
-
-
如果想要在函数中,使用脚本的外部参数,只能通过函数调用将该参数传给函数
-
-
如何获取函数的输出
-
函数有返回值
-
$?
-
只能获取0-255范围内的值
-
获取的是上一条指令的运行结果
-
-
-
函数没有返回值
-
但是函数有echo输出,可以使用命令置换符获取
-
·· $()
-
-
-
local
-
修饰局部变量
-
local sum
-
全局变量sum被修饰为局部变量
-
-
-
- 编程语言的分类