前言
shell变量的类型:
- 自定义变量:由用户自己定义,修改和使用
- 环境变量:由系统维护,用于设置工作环境
- 只读变量:只可以读取不可以更改
- 位置变量:通过命令行给脚本传递参数
- 预定义变量:Bash中内置的一类变量,不能修改 有些规定好的变量放在那里让你使用
补充:系统内置变量:PATH,UID,HOSTNAME,USER
一、变量基础
1.1命名要求
- 区分大小写
- 不能使程序中的保留字和内置变量如:if, for,hostname 命令 a=
- 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
- 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH
- 大驼峰 StudentFirstName
- 小驼峰 studentFirstName
- 下划线 student_name
1.2定义变量
- name='value' 【变量名=变量值】
- $name(变量引用)
- ${name}(变量引用)
- 直接字串:name='root'
- 变量引用:name="$USER"
- 命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
1.3弱引用和强引用
- "$name " 弱引用:其中的变量引用会被替换为变量值
- '$name ' 强引用:其中的变量引用不会被替换为变量值,而保持原字符串
补充:
- 赋值时使用双引号(" ")可以直接调用变量
- 赋值时使用单引号(' ')$只会被认为是字符$ 不会调用变量
- 赋值时使用(``反撇在tab上面)命令替换,提取命令执行后的输出结 果$( ) 用法相同
- {}可以分隔变量值
格式:变量名+=追加值 [root@server ~]#title=CTO [root@server ~]#title+=feizirui [root@server ~]#echo $title
1.4read -p(从键盘输入的内容变成变量)
1.5变量作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。可以通过内部命令export将指定的变量为全局变量,使用户定义的变量在所子shell环境中可以继续使用。
方法:
- 格式1:export 变量名
- 格式2:export 变量名=变量值
举例:
1.6整数的运算
expr只能进行整数的运算 格式: expr 变量1 运算符 变量2 [运算符 变量3] 运算符: 加法:+ 减法:- 乘法:\ * 除法:/ 取余(取模):%
1.7环境变量
环境变量:
可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量
一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程
一般只在系统配置文件中使用,在脚本中较少使用
1. 由系统提前创建,用来设置用户的工作环境
2. 可以使用env查看环境变量
3. 需要记住的常用环境变量
- $USER 表示用户名称
- $HOME 表示用户的宿主目录
- $LANG 表示语言和字符集
- $PWD 表示当前所在工作目录
- $PATH 表示可执行用户程序的默认路径
1.8环境变量的全局配置文件
配置文件位置在
- /etc/profile:修改此文件会作用于所有用户
- ~/.bash_profile:用户独立的配置文件,修改这个文件只作用于当前用户,可以用来长期变更或设置环境变量
1.9只读变量
变量值不允许修改(重新赋值)的情况,无法使用 unset删除,最快方法重启
1.10位置变量
位置变量也称为位置参数,使用$1、$2、$3、…、$9 表示
1.11预定义变量
系统帮你定义好了 拿来用就可以了,你不需要知道为什么,记住以下:
- $*:表示所有位置参数的内容看成一个整体返回,返回所有 (45667) $1
- $@:表示所有位置参数的内容分割成n份,每份作为一个独立的个体返回,返回所有 4 5 6 6 7
- $?:表示前一条命令执行后的返回状态,返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常
- $#:表示命令行中位置参数的总个数
- $0:表示当前执行的脚本或程序的名称,当前脚本的名字
- $$:当前进程id
- $!:后台任务最后一个id
二、条件语句
2.1测试
- 格式1:test 条件表达式
- 格式2:[ 条件表达式 ],注意[]空格,否则会失败
2.2操作符
- -d:测试是否为目录(Directory)
- -e:测试目录或文件是否存在(Exist)
- -a:测试目录或文件是否存在(Exist)
- -f:测试是否为文件(File)
- -r:测试当前用户是否有权限读取(Read)
- -w:测试当前用户是否有权限写入(Write)
- -x:测试当前用户是否有权限执行(eXcute)
- -L:测试是否为软连接文件
2.3属性测试补充
- -s FILE:#是否存在且非空
- -t fd #:fd 文件描述符是否在某终端已经打开
- -N FILE:#文件自从上一次被读取之后是否被修改过
- -O FILE:#当前有效用户是否为文件属主
- -G FILE:#当前有效用户是否为文件属组
条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成
测试过程:实现评估布尔声明,以便用在条件性环境下进行执行
- 若真,则状态码变量 $? 返回0
- 若假,则状态码变量 $? 返回1
- 条件测试命令
2.4比较整数数值
[ 整数1 操作符 整数2 ] 公式
- -eq:第一个数等于(Equal)第二个数
- -ne:第一个数不等于(Not Equal)第二个数
- -gt:第一个数大于(Greater Than)第二个数
- -lt:第一个数小于(Lesser Than)第二个数
- -le:第一个数小于或等于(Lesser or Equal)第二个数
- -ge:第一个数大于或等于(Greater or Equal)第二个数
2.5字符串比较
1、常用的测试操作符
- =:字符串内容相同
- !=:字符串内容不同,! 号表示相反的意思
- -z:字符串内容为空
- -n: 字符是否存在
2、格式:
- [ 字符串1 = 字符串2 ] 是否相同
- [ 字符串1 != 字符串2 ] 是否不相同
- [ -z 字符串 ] 是否为空
- [ -n 字符串 ] 字符是否存在
2.6逻辑测试(短路运算)
- 格式1:[ 表达式1 ] 操作符 [ 表达式2 ] ...
- 格式2:命令1 操作符 命令2 ...
常见条件:
- -a或&&:逻辑与,“而且”的意思全真才为真
- -o或||:逻辑或,“或者”的意思一真即为真
- !:逻辑否
(1)短路与 &&
1 CMD1 短路与 CMD2:&&同时满足命令1和命令2 的要求,才会返回正确 2 全真才为真,一假即为假 3 第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果 4 第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2
(2)短路或 ||
1 CMD1 短路或 CMD2 2 一真即为真 3 第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2 4 第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果
1 ping 小脚本 2 -c 发送包的个数 3 -i 发送的间隔时间 4 -W 超时时间 5 -w 多少秒后停止ping操作
三、if语句分支结构
3.1if介绍
单分支结构: if 判断条件; then 条件为真的分支代码 fi
双分支结构: if 判断条件; then 条件为真的分支代码 else 条件为假的分支代码 fi
多分支结构: if 判断条件1 then 条件1为真的分支代码 elif 判断条件2 then 条件2为真的分支代码 elif 判断条件3;then 条件3为真的分支代码 ... else 以上条件都为假的分支代码 fi
例1:
例2:
例3:
3.2case
格式: case 变量引用 in PAT1) 分支1 ;; PAT2) 分支2 ;; ... *) 默认分支 ;;
case支持glob风格的通配符:
- * 任意长度任意字符
- ? 任意单个字符
- [0-9] 指定范围内的任意单个字符
- |表示:或者意思,如: a|b
例1:
例2:
3.3echo
echo -n:表示不换行输出 echo -e:表示输出转义符
data日期命令:
- date:查看当前系统时间
- -d :你描述的日期,显示指定字符串所描述的时间,而非当前时间
- %F:完整日期格式,等价于 %Y-%m-%d
- %T:时间(24小时制)(hh:mm:ss)
四、循环语句
4.1for循环
循环含义:将某代码段重复运行多次,通常有进入循环的条件和退出循环的条件
常见的循环的命令:for, while, until
执行机制: 依次将列表中的元素赋值给“变量名”; 每次赋值后即执行一次循环体; 直到列表中的元素耗尽,循环结束; 如果省略 [in WORDS ... ] ,此时使用位置参数变量 in "$@" for (( 表达式1; 表达式2; 表达式3 )); do 命令; done
例1:
方法一:
方法二:
方法三:
4.2while和until
相对于for,需要知道循环次数,我们只知道停止条件,不知道次数,就需要使用while,直到达到条件
while:当命令判断为假时停止 until:当命令判断为真时停止
双重循环及跳出循环:
- break跳出单个循环后面加数字2则代表跳出两层循环
- continue终止某次循环中的命令,但是不会完全终止命令
例1:
例2:
4.3select 菜单选择
PS1 提示符
PS2 多行重定向
PS3 菜单选择
例1: