Shell脚本中的变量
一、变量的概述
- 变量即在程序运行过程中它的值是允许改变的量。
- 变量是用一串固定的字符串去表示不固定的内容。
- 变量表示命令的内存空间,将数据放在内存空间中,通过变量名引用,获取数据。
二、变量命名的要求
- 区分大小写
- 不能使程序中的保留字和内置变量:如:if, for,hostname 命令
- 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反
- 不要使用内置的变量,使用英文尽量使用词义通俗易懂,PATH
三、常见的shell变量类型
变量赋值:变量名=变量值(name=value)
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。
四、变量作用范围
默认情况下,新定义的变量只在当前的shell环境中有效,因此称为局部变量,当进入子程序或新的shell环境中,局部变量将无法再起作用。 可以通过内部命令export将指定的变量为全局变量(即环境变量),使用户定义的变量在所有子shell环境中可以继续使用。
设置全局变量:
- export name=value
- declare -x name=value
将局部变量转变为全局变量:
- export name
五、自定义变量
- name='value'
- 变量名=变量值
- 直接字串:name='root'
- 变量引用:name="$USER"
- 命令引用:name=
COMMAND或者 name=$(COMMAND) - 注意:变量赋值是临时生效,当退出终端后,变量会自动删除,无法持久保存,脚本中的变量会随着脚本结束,也会自动删除
变量引用
- $name
- ${name}
弱引用和强引用
- "$name " 弱引用,其中的变量引用会被替换为变量值
- '$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
总结:
1.赋值时使用双引号(" ")可以直接调用变量;
2.赋值时使用单引号(' ')只会被认为是字符,不会调用变量;
3.赋值时使用(``)反撇在tab上面命令替换,提取命令执行后的输出结果,和$( )用法相同;
4.{}:确定了变量起始结束的范围,只要有变量就加。
六、环境变量
1.系统内置环境变量
由系统提前创建,用来设置用户的工作环境。
2.使用env命令查看所有环境变量
3.需要记住的常用环境变量
- $PATH:表示可执行文件的默认路径
- $USER:表示用户名称
- $HOME:表示用户的宿主目录
- $LANG:表示语言和字符集
- $PWD:表示当前所在工作目录
4.环境变量的特性
- 可以使子进程(包括孙子进程)继承父进程的变量,但是无法让父进程使用子进程的变量。
- 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程。
- 一般只在系统配置文件中使用,在脚本中较少使用。
5.环境变量的全局配置文件
/etc/profile如果修改此文件会作用于所有用户;
~/.bash_profile 用户独立的配置文件,修改这个文件只作用于当前用户 可以用来长期变更或设置环境变量。
七、只读变量
在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。
只读变量只能被赋值一次。只读变量在取得初始值之后,只能进行读取操作,不能重新赋值或删除。
八、位置变量
位置变量也称为位置参数。
使用$n表示,n为数字序列号,且必须为整数。
例如:1、1、2、…、9、9、{10}、${11}。
两位数需要加花括号{},不然10会被识别为:1和0。
九、预定义变量
预定义变量是系统定义好的变量,用来保持脚本程序的执行信息。
可以直接使用这些变量,不能直接为这些变量赋值。
| 变量 | 作用 |
|---|---|
| $? | 表示前一条命令执行后的返回状态。返回值为 0 表示执行正确,返回任何非 0值均表示执行出现异常 |
| $* | 表示所有位置参数的内容。当整体返回。(将输入的参数作为一个单词) |
| $@ | 表示所有位置参数的内容。当个体返回。可作为数组。(将参数内容分割成n份,每份作为独立个体) |
| $# | 表示命令行中位置参数的总个数 |
| $0 | 表示当前脚本名称(如果是软链接,显示当前软链接文件名) |
| $_ | 表示在此之前执行的命令或脚本的最后一个参数 |
| $$ | 获取当前bash的进程PID号 |
注意:
$* 和 $@的区别:
不加双引号的话,$* 和 $@ 都代表脚本后面跟的所有参数。
加上双引号的话,"$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待。
示例:
十、read
read可以从键盘输入变量值,即将键盘输入的内容变成变量值。
选项:
| 选项 | 作用 |
|---|---|
| -p | 后面跟提示信息,即在输入前打印提示信息 |
| -s | 安静模式,在输入字符时不再屏幕上显示,例如密码 |
| -t | 后面跟秒数,定义输入字符的等待时间 |
| -n | 后跟一个数字,定义输入文本的长度 |
| -a | 后跟一个变量,该变量会被认为是个数组 |
示例:
条件语句
一、test测试
test测试文件的表达式是否成立
命令格式1:test 条件表达式
命令格式2:[ 注意两边需要空格 ]
命令格式3:[ 操作符 文件或者目录]
操作符:
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-a:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
-L: 测试是否为软连接文件
属性测试补充:
-s FILE #是否存在且非空
-t fd #fd 文件描述符是否在某终端已经打开
-N FILE #文件自从上一次被读取之后是否被修改过
-O FILE #当前有效用户是否为文件属主
-G FILE #当前有效用户是否为文件属组
若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1
条件测试命令
示例:
二、比较整数数值
格式:[ 整数1 操作符 整数2 ] 公式
-eq:第一个数等于(Equal)第二个数
-ne:第一个数不等于(Not Equal)第二个数
-gt:第一个数大于(Greater Than)第二个数
-lt:第一个数小于(Lesser Than)第二个数
-le:第一个数小于或等于(Lesser or Equal)第二个数
-ge:第一个数大于或等于(Greater or Equal)第二个数
示例:
三、字符串比较
常见的测试操作符
- =:字符串内容相同
- !=:字符串内容不同,! 号表示相反的意思
- -z:字符串内容为空
- -n: 字符是否存在
字符串格式:
[ 字符串1 = 字符串2 ] 是否相同
[ 字符串1 != 字符串2 ] 是否不相同
[ -z 字符串 ] 是否为空
[ -n 字符串 ] 字符是否存在
示例:
四、逻辑测试
格式1:[ 表达式1 ] 操作符 [ 表达式2 ] ...
格式2:命令1 操作符 命令2 ...
常见条件
- -a或&&:逻辑与,“而且”的意思全真才为真
- -o或||:逻辑或,“或者”的意思一真即为真
- !:逻辑否
第一种形式
CMD1 && CMD2:逻辑与&&同时满足命令1和命令2的要求,才会返回正确
全真才为真 一假即为假
第一个CMD1结果为真(1),第二个CMD2必须要参与运算,才能得到最终的结果
第一个CMD1结果为假(0),总的结果必定为假,因此不需要执行CMD2
第二种形式
CMD1 || CMD2:逻辑或||满足命令1或命令2其中一个的要求,才会返回正确
一真即为真,全假才为假
第一个CMD1结果为真 (1),总的结果必定为1,因此不需要执行CMD2
第一个CMD1结果为假 (0),第二个CMD2 必须要参与运算,才能得到最终的结果
五、双中括号
[[ expression ]] 用法
- == 左侧字符串是否和右侧的PATTERN相同
注意:此表达式用于[[ ]]中,PATTERN为通配符。
- =~ 左侧字符串是否能够被右侧的正则表达式的PATTERN所匹配
注意: 此表达式用于[[ ]]中,扩展的正则表达式。
六、()和{ }
()和{ }都可以将多个命令组合在一起,批量执行。
()的格式:
(空格CMD1;CMD2;...空格)
{}的格式:
{空格CMD1;CMD2;...;空格}