bash新手入门指南-变量的声明
默认类型
由于 bash shell 是解释型语言,所以它在执行脚本时不会进行编译,同样地,也不会执行强类型检查。默认情况下,所有变量都是字符串类型。例如:
a=1
c=12345
如上脚本使用了变量a和变量c分别赋予不同的值,从表面上来看,a和c应当是整数类型才是,其实不然,都是字符串,可以通过下面这个例子来说明:
#!/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/bash
declare -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 | 声明环境变量 |
declare或typeset除了-以外,还支持+,除了只读类型以外,它的含义是解除变量类型。
声明和解除声明
声明和解除声明类型,案例如下:
#!/bin/bash
a=3
b=5
declare -i c
declare -p c
c="a + b"
echo $c
declare +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/bash
declare -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/bash
declare -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/bash
declare -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/bash
declare -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,但是其底层计算逻辑是不一样的。