Bootstrap

SHELL--变量和引用

SHELL第二天
变量和引用
变量就是程序设计语言中的一个可以变化的量,当然,可以变化的是变量的值。变量几乎所有的程序设计语言中都有定义,并且其涵义也大同小异。从本质上讲,变量就是在程序中保存用户数据的一块内存空间,而变量名就是这块内存空间的地址。
在程序的执行过程中,保存数据的内存空间的内容可能会不断地发生变化,但是,代表内存地址的变量名却保持不变。
在Shell中,变量名可以由字母、数字或者下划线组成,并且只能以字母或者下划线开头。对于变量名的长度,Shell并没有做出明确的规定。因此,用户可以使用任意长度的字符串来作为变量名。但是,为了提高程序的可读性,建议用户使用相对较短的字符串作为变量名。
在一个设计良好的程序中,变量的命名有着非常大的学问。通常情况下,用户应该尽可能选择有明确意义的英文单词作为变量名,尽量避免使用拼音或者毫无意义的字符串作为变量名。这样的话,用户通过变量名就可以了解该变量的作用。
Shell中的变量是不分数据类型的,统一地按照字符串存储。

例 3-1

#!/bin/bash
x=123
let "x += 1"
echo "x = $x"
#定义一个变量,赋值123,默认字符串存储,使变量+1,输出变量值
echo "----------------------------------------------"
y=${x/1/abc}
echo "y=$y"
#替换x中的1为abc,将值赋给变量y,输出y值
echo "----------------------------------------------"
declare -i y
echo "y=$y"
#声明变量y的类型是整数型,输出y
let "y += 1"
echo "y=$y"
#y+1,输出y
echo "----------------------------------------------"
z=abc22
echo "z=$z"
m=${z/abc/11}
echo "m=$m"
#定义z为abc11,打印一下,将z中的abc改成11,赋值给m,打印一下m
echo "----------------------------------------------"
n=""
echo "n=$n"
let "n += 1"
echo "n=$n"
#将空串赋给n,输出变量n的值,让n+1,打印一下
echo "----------------------------------------------"
echo "p=$p"
let "p += 1"
echo "p=$p"
#输出空变量p的值,变量+1,打印一下

在这里插入图片描述
在这里插入图片描述

可以看到。当x=123,默认是字符串存储,但让x做算数运算时,变量的类型随之改变,此时x中没有字母,所以直接进行123+1=124运算,输出x的变量值为124.。而当y中有字母时,声明成整数型变量之后为0,使y+=1,此时y的变量值为1。

在Shell中,通常情况下用户可以直接使用变量,而毋需先进行定义,当用户第一次使用某个变量名时,实际上就同时定义了这个变量,在变量的作用域内,用户都可以使用该变量。

#!/bin/bash   
#定义变量a     
a=1            
#定义变量b     
b="hello"      
#定义变量c     
c="hello world"

二.通过declare命令声明变量
-p:显示所有变量的值。
-i:将变量定义为整数。在之后就可以直接对表达式求值,结果只能是整数。如果求值失败或者不是整数,就设置为0。
-r:将变量声明为只读变量。只读变量不允许修改,也不允许删除。
-a:变量声明为数组变量。但这没有必要。所有变量都不必显式定义就可以用作数组。事实上,在某种意义上,似乎所有变量都是数组,而且赋值给没有下标的变量与赋值给下标为0的数组元素相同.
-f:显示所有自定义函数,包括名称和函数体。
-x:将变量设置成环境变量,这样在随后的脚本和程序中可以使用。

例3-3

#!/bin/bash
#定义变量x,并将一个算术式赋给它
x=6/3
echo "$x"
#定义变量x为整数
declare -i x
echo "$x"
#将算术式赋给变量x
x=6/3
echo "$x"
#将字符串赋给变量x
x=hello
echo "$x"
#将浮点数赋给变量x
x=3.14
echo "$x"
#取消变量x的整数属性
declare +i x
#重新将算术式赋给变量x
x=6/3
echo "$x"
#求表达式的值
x=$[6/3]
echo "$x"
#求表达式的值
x=$((6/3))
echo "$x"
#声明只读变量x
declare -r x
echo "$x"
#尝试为只读变量赋值
x=5
echo "$x"

在这里插入图片描述
在这里插入图片描述

使用不同的方法了声明变量,导致变量在不同的环境下表现出不同的行为
三.变量和引号
Shell语言中一共有3种引号,分别为
单引号(’ ‘)单引号括起来的字符都作为普通字符出现
双引号(" ")双引号括起来的字符,除“$”、“\”、“’”和“"”这几个字符仍是特殊字符并保留其特殊功能外,其余字符仍作为普通字符对待,
反引号()。反引号括起来的字串被Shell解释为命令,在执行时,Shell首先执行该命令,并以它的标准输出结果取代整个反引号(包括两个反引号)部分

例3-4

#!/bin/bash
a= demo
b='b- $a'
c="b- $a"
echo $a
echo $b
echo $c

在这里插入图片描述
在这里插入图片描述

1、单引号
所见即所得
例如:

var=123 
var2='${var}123'
echo var2 var2
结果为${var}123

2、双引号
输出引号中的内容,若存在命令、变量等,会先执行命令解析出结果再输出
例如:

var=123 
var2="${var}123"
echo var2 var2
结果为123123

3、反引号(键盘tab键上面一个键)
命令替换
例如:

root用户登录系统
var=`whoami`
echo $var var结果为执行whoami命令的
结果 显示root

备注:反引号和$()作用相同

对三种引号的建议:
1、简单变量,简单赋值可以不用""
2、脚本中声明变量最好用""
3、原样子输出用’’
4、执行命令赋值最好用$()或者``

四.变量的作用域
1.全局变量
全局变量可以在脚本中定义,也可以在某个函数中定义。在脚本中定义的变量都是全局变量,其作用域为从被定义的地方开始,一直到Shell脚本结束或者被显式地删除
例3-5 全局变量的使用方法

#!/bin/bash
#定义函数
func()
{
   #输出变量x的值
   echo "$v1"
   #修改变量x的值
   v1=200
}
#在脚本中定义变量x
v1=100
#调用函数
func
#输出变量x的值
echo "$v1"

在这里插入图片描述
在这里插入图片描述

如果在定义之前调用函数,就会发生错误
其实和c语言中的一样,全局变量就是全局都可以使用,有过定义的变量。
而局部变量一般在函数中声明,不能在全局进行引用。

例 3-6 :演示在函数内部定义全局变量的方法

#!/bin/bash
#定义函数
func()
{
   #在函数内部定义变量
   v2=200
}
#调用函数
func
#输出变量的值
echo "$v2"

在这里插入图片描述
在这里插入图片描述
全局变量在函数中的声明方法和在其余部分一样,直接声明,不加关键字。
2.局部变量
与全局变量相比,局部变量的使用范围较小,通常仅限于某个程序段访问,例如函数内部。在Shell语言中,可以在函数内部通过local关键字定义局部变量,另外,函数的参数也是局部变量。
例3-7 演示使用local关键字定义局部变量

#!/bin/bash
#定义函数
func()
{
   #使用local关键字定义局部变量
   local v2=200
}
#调用函数
func
#输出变量的值
echo "$v2"

在这里插入图片描述
在这里插入图片描述
局部变量声明使用关键字 local
例3-8

#!/bin/bash
#定义函数
func()
{
   #输出全局变量v1的值
   echo "global variable v1 is $v1"
   #定义局部变量v1
   local v1=2
   #输出局部变量v1的值
   echo "local variable v1 is $v1"
}
#定义全局变量v1
v1=1
#调用函数
func
#输出全局变量v1的值
echo "global variable v1 is $v1"

在这里插入图片描述
在这里插入图片描述

先定义再调用。

环境变量即为全局变量,可以在定义它们的shell及其派生出来的任意子进程的shell中使用。局部变量只能在定义它们的函数/脚本中使用。还有一些变量是用户创建的,其他的则是专用的shell变量。环境变量可用于定义shell的运行环境,环境变量可以在配置文件中定义与修改,也可以在命令行中设置,但是命令行中的修改操作在终端重启时就会丢失,因此最好在配置文件中修改(用户家目录的“.bash_profile“文件或者全局配置“/etc/profile”、“/etc/bashrc”文件或者“/etc/profile.d”文件中定义。)将环境变量放在profile文件中,每次用户登录时这些变量值将被初始化。比如HOME、USER、SHELL、UID等再用户登录之前就已经被/bin/login程序设置好了。

常见的系统变量有:
TMOUT:设置自动退出的误操作等待时间
HOSTTYPE:系统文件系统类型
HISTSIZE:历史命令记录条数
HOME:用户登录时进入的目录,家目录
UID:当前用户的id
SHELL:当前shell解释器
PWD:当前所在路径(每改变一次目录,该值就会改变)
PATH:可执行文件默认路径

可以用echo来显示查看全局变量(eg:echo $HOME)。env(或printenv)、set也可以用来查看系统的环境变量,但不是单独查看。而用unset临时取消环境变量(eg:unset USER),要永久生效还是要写到配置文件中

自定义环境变量(采用export):
export 变量名=value
变量名=value;export 变量名
declare -x 变量名=value

这里依旧是临时生效,在shell终端关闭后就消失了,写到配置文件中则永久生效(注意:写到配置文件中后需要运行一遍配置文件的脚本才可生效,否则等重启时生效)

局部变量即为本地变量,本地变量在用户当前的shell生存期的脚本中使用。在一个函数中将某个变量声明为local,则该变量就是一个局部变量,只在本函数中有效。
①用反引号将命令的结果作为变量名是常用的方法,eg:cmd=date +%F
②用 符 号 将 命 令 的 结 果 作 为 变 量 名 也 比 较 常 用 , e g : c m d = 符号将命令的结果作为变量名也比较常用,eg:cmd= egcmd=(date +%F)
③变量在大括号上的使用:在以时间、主机名等为包名一部分来打包的时候常用

$?常用来判断上一步是否成功(压缩失败打印ERROR压缩成功打印OK)

五.系统变量
Shell语言的系统变量主要在对参数判断和命令返回值判断时使用,包括脚本和函数的参数以及脚本和函数的返回值
在这里插入图片描述
例3-9

#!/bin/bash
#输出脚本的参数个数
echo "the number of parameters is $#"
#输出上一个命令的退出状态码
echo "the return code of last command is $?"
#输出当前脚本名称
echo "the script name is $0"
#输出所有的参数
echo "the parameters are $*"
#输出其中的几个参数
echo "\$1=$1;\$2=$2;\$11=$11"

在这里插入图片描述
在这里插入图片描述
此时查看上一步的返回码时,就可以使用$?
Shell的环境变量是所有的Shell程序都可以使用的变量。Shell程序在运行时,都会接收一组变量,这组变量就是环境变量。环境变量会影响到所有的脚本的执行结果。

在这里插入图片描述
变量赋值和清空
当Shell变量不再需要时,使用unset语句可以将其清除。当变量被清除后,其所代表的值也会消失。
基本语法如下:
**

unset variable_name

**
其中,参数varibale_name表示要清除的变量的名称。
引用和替换
引用,是指将字符串用引用符号包括起来,以防止其中的特殊字符被Shell解释为其他涵义。特殊字符是指除了字面意思之外还可以解释为其他意思的字符。例如在Shell中,“ $ ”符号的本身涵义是美元符号,其ASCII码值为十进制36。除了这个涵义之外,前面已经讲过,“$”符号还可以用了获取某个变量的值,即变量替换。星号“*”也是一个特殊的字符,星号可以用来作为通配符使用。
在这里插入图片描述
在Shell语句中,当一个字符串被单引号引用起来之后,其中所有的字符,除单引号本身之外,都将被解释为字面意义,即字符本身的涵义。这意味着被单引号引用起来的所有的字符都将被解释为普通的字符,这称为全引用

对于单引号来说, 被其引用起来的所有的字符都将被解释为字面意义。而对于双引号来说,情况会有所不同。如果用户使用双引号将字符串引用起来,则其中所包含的字符除美元符号( $ )、反引号以及反斜线(\)之外的所有的其他的字符,都将被解释为字面意义,这称为部分引用。也就是说,在部分引用中,“$”、“`”和“\”仍然拥有特殊的涵义。

所谓命令替换,是指在Shell程序中,将某个Shell命令的执行结果赋给某个变量。在bash中,有2种语法可以进行命令替换,分别使用反引号和圆括号,如下:

`command`

$(command)
以上2种语法时等价的,用户可以根据自己的习惯来选择使用。

例3-16 打印当前路径

#!/bin/bash
#变量替换
v1=`pwd`
#输出变量的值
echo "current working directory is $v1"

反引号看不清的可以看下图:
在这里插入图片描述

转义的作用是转换某些特殊字符的意义。转义使用反斜线表示,当反斜线后面的一个字符具有特殊的意义时,反斜线将屏蔽该字符的特殊意义,使得Shell按照该字符的字面意义来解释。(防止转义)

;