bash新手入门指南-变量的声明

156 阅读4分钟

bash新手入门指南-变量的声明

默认类型

由于 bash shell 是解释型语言,所以它在执行脚本时不会进行编译,同样地,也不会执行强类型检查。默认情况下,所有变量都是字符串类型。例如:

a=1
c=12345

如上脚本使用了变量a和变量c分别赋予不同的值,从表面上来看,ac应当是整数类型才是,其实不然,都是字符串,可以通过下面这个例子来说明:

#!/bin/bash
​
a=1
c=12345
​
d="${a} + ${c}"
echo ${d}

如上脚本执行后结果为1 + 12345,当然是被当城字符串拼接了。

[root@localhost bash]# bash var_declaration.sh
1 + 12345
[root@localhost bash]#

bash中,可以使用declare或者typeset来声明变量类型,例如修改如上脚本,将d声明为整数类型。

#!/bin/bash
​
a=1
c=12345
​
declare -i d # 等同于 typeset -i d
d="${a} + ${c}"
echo ${d}

只需要添加上declare -i即可声明后面的变量类型为整数型,其运行结果为:

[root@localhost bash]# bash var_declaration.sh
12346
[root@localhost bash]#

获取变量的类型

bash中,可以使用declare -p来获取其变量的类型(这个只是查看其被declare定义过的变量),例子如下:

#!/bin/bashdeclare -i a
a=3
​
b=5
​
declare -p a
declare -p b

如上脚本先定义了一个整数类型变量a,再定义了一个变量b,使用declare -p查看定义过的类型,其结果如下:

[root@localhost bash]# bash var_declaration.sh
declare -i a="3"
declare -- b="5"
[root@localhost bash]#

其中-i表示整数类型、而--表示为定义其类型。

其他类型声明说明

bash中,除了声明整型类型外,还有以下类型:

选项含义
-a声明为索引数组
-A声明为关联数组
-f声明为仅使用函数名称
-i声明为整数类型
-l为变量赋值的时,所有大写都将转换为小写
-n声明引用变量
-r声明为只读类型
-u为变量赋值的时,所有小写都将转换为大写
-x声明环境变量

declaretypeset除了-以外,还支持+,除了只读类型以外,它的含义是解除变量类型。

声明和解除声明

声明和解除声明类型,案例如下:

#!/bin/bash
​
a=3
b=5
​
declare -i c
declare -p c
c="a + b"
echo $cdeclare +i c
declare -p c
c="a + b"
echo $c

上述代码有2段,主要区别是第一段将变量c声明为整数类型,而第二段将变量c的整数类型取消掉。都分别赋值a + b,其运行结果如下:

[root@localhost bash]# bash var_declaration.sh
declare -i c
8
declare -- c="8"
a + b
[root@localhost bash]#

声明为只读类型

bash中,declare -r可以声明为只读类型,顾名思义,其定义后,后面不能再修改该变量的值,这也是最特殊的,该变量类型不能被解除掉。

例子如下:

#!/bin/bashdeclare -r a=3
​
echo ${a}
​
a=5
​
declare +r a

上述该代码先申请了变量a,并且将其定义为只读类型,而后输出该值,后续将该值进行修改,最后取消该变量类型。

执行结果如下:

[root@localhost bash]# bash var_declaration.sh
3
var_declaration.sh: line 7: a: readonly variable
var_declaration.sh: line 9: declare: a: readonly variable
[root@localhost bash]#

修改只读变量和取消该变量类型,都报错了。

声明类型且修改大小写

大家或多或少都遇到过这样的场景,需要收集用户输入的指令,但是往往用户输入的指令大小写不确定,程序往往第一步就需要进行转换,而在bash中,在定义变量的时候就可以指定。

将变量中所有的大写都转换为小写,只需要定义declare -l即可,这样存储的数据,会自动将大写转为小写;而将变量中所有的小写都转为大写,需要定义declare -u,这样存储的数据,会自动将小写转换为大写。

案例如下:

#!/bin/bashdeclare -l a
a='123ABCder'
echo ${a}declare -u b
b='123ABCder'
echo ${b}

这样执行的结果为:

[root@localhost bash]# bash var_declaration.sh
123abcder
123ABCDER
[root@localhost bash]#

在实际案例中,比如想要从用户输入获取新息,比如:yes|YES等,直接可以将其转为一致的写法,如都转换为小写,再进行比对,就非常方便了,案例如下:

#!/bin/bashdeclare -l userInput
read -p "please input words: " userInput
​
echo your inputs: ${userInput}

在上述代码中,首先定义了一个变量userInput,存储的时候,将其中的大写字符转换为小写字符,而后使用read读取用户输入,并且将其存储到userInput变量中,最后再输出输入的字符。

执行的结果如下:

[root@localhost bash]# bash var_declaration.sh
please input words: AbcdEf123aA
your inputs: abcdef123aa
[root@localhost bash]#

引用变量的声明

bash中,引用变量类似于c的指针,指向的是一个变量的地址,即同该变量本身,案例代码如下:

#!/bin/bashdeclare -n b
​
b='a'echo b: ${b}
​
a=10
​
echo a: ${a}
echo b: ${b}
​
a=12
echo b: ${b}

上述代码中,定义了一个引用类型的变量b,这里特地将其用单引号括起来,但是其不影响结果,当执行的时候,bash会检测当前是否有a这个变量,如果没有该变量,那么b的值也会为空;而后续定义了a变量的值后,通过b可以访问到a的值,当a修改后,b的值也会相应的修改,因为b不是一个正常的变量,而是指向a的地址,同样的,当a被销毁的时候,b所引用的地址即a也会相应的被销毁,所以b的值也会为空。具体代码结果如下:

[root@localhost bash]# bash var_declaration.sh
b:
a: 10
b: 10
b: 12
b:
[root@localhost bash]#

总结

首先,bash shell 是解释型语言,所以不会存在强类型检查和预先声明,同样的对于shell而言,也同样的灵活,可以动态的声明类型,也可以解除声明类型,除了只读类型以外。

bash中,可以使用declare -p来尝试获取变量定义的类型,当为--则表示没有使用declare定义过该变量,即为默认的字符型类型。

后续介绍了只读类型、声明类型且修改大小写,最后的引用变量等等。还有一些并未说明,这是因为这些需要linux相关基础才行。

啰嗦几句,在上一篇文章中,介绍了变量替换,即:

a=3
echo ${a} + 1

bash在执行之前,会将${a}进行变量替换,替换为3,而后再输出3 + 1字符串。

那么,有下面这段代码:

#!/bin/bash
​
a=3
declare -i b='a + 1'declare -i c="${a} + 1"echo ${b}
echo ${c}

最后输出的结果都是4,但是需要注意不同的点,b是计算变量a+1的值,而c是计算变量a当时的值再+1的值。

运行程序:

[root@localhost bash]# bash var_declaration.sh
4
4
[root@localhost bash]#

输出的结果都为4,但是其底层计算逻辑是不一样的。