Shell脚本中的变量与条件语句

95 阅读6分钟

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命令查看所有环境变量

image.png

3.需要记住的常用环境变量

  • $PATH:表示可执行文件的默认路径
  • $USER:表示用户名称
  • $HOME:表示用户的宿主目录
  • $LANG:表示语言和字符集
  • $PWD:表示当前所在工作目录

4.环境变量的特性

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

5.环境变量的全局配置文件

/etc/profile如果修改此文件会作用于所有用户;

~/.bash_profile 用户独立的配置文件,修改这个文件只作用于当前用户 可以用来长期变更或设置环境变量。

七、只读变量

在定义shell变量时,默认定义的变量是可以被修改的,但有一种变量是不能修改的,就是只读变量。

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

image.png

八、位置变量

位置变量也称为位置参数。

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

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

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

image.png

image.png

九、预定义变量

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

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

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

注意

$* 和 $@的区别: 
不加双引号的话,$* 和 $@ 都代表脚本后面跟的所有参数。 
加上双引号的话,"$*"会把所有参数当作一个整体去看待(此时参数数量为1),"$@"会把脚本后面跟的每一个参数当作一个个体去看待。

示例

image.png

image.png

image.png

十、read

read可以从键盘输入变量值,即将键盘输入的内容变成变量值。

选项

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

示例

image.png

条件语句

一、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

条件测试命令

示例:

image.png

二、比较整数数值

格式:[ 整数1 操作符 整数2 ] 公式

-eq:第一个数等于(Equal)第二个数 
-ne:第一个数不等于(Not Equal)第二个数 
-gt:第一个数大于(Greater Than)第二个数 
-lt:第一个数小于(Lesser Than)第二个数 
-le:第一个数小于或等于(Lesser or Equal)第二个数 
-ge:第一个数大于或等于(Greater or Equal)第二个数

示例

image.png

三、字符串比较

常见的测试操作符

  • =:字符串内容相同
  • !=:字符串内容不同,! 号表示相反的意思
  • -z:字符串内容为空
  • -n: 字符是否存在

字符串格式

[ 字符串1 = 字符串2 ] 是否相同

[ 字符串1 != 字符串2 ] 是否不相同

[ -z 字符串 ] 是否为空

[ -n 字符串 ] 字符是否存在

示例

image.png

四、逻辑测试

格式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;...;空格}