Bash 变量
1月13日,打卡额外学习,嘻嘻
内容来自实验楼
shell 变量
- 没有众多的存储类及类型限制,都是字符串
- 不需要预先定义,可以直接赋值
变量的定义
变量定义的格式如下:
变量名=字符串
变量名
shell
中的变量名可以由字母,数字,下划线组成。
- 但是只能由字母或下划线开头。
- 建议不使用命令关键字,如定义的变量名不可以为
echo
或rm
等命令。(可用help
命令查看保留关键字)
如下示例:
# 正确的定义
user2=shiyanlou002
_user3=shiyanlou003
# 错误的定义
4user=shiyanlou004
变量赋值
直接赋值:
在 shell
中,变量是无类型的,即所有变量的值都是一串字符,即字符串,当然,也可以为空字符串。
对于变量的赋值需要注意的是:
- 在等号
=
的两边不能有空格 - 如果在变量的值中包含空格,需要使用单引号
''
或者双引号""
- 如果赋值的是一个已存在的变量名,则会覆盖掉原有的内容
命令结果进行赋值:
除了使用上述的方式对变量进行赋值之外,我们还可以使用命令执行的结果进行赋值。一般有两种方式:
反引号 ( ` )
使用反引号我们可以在字符串中执行命令,也可以直接引用命令执行的结果进行赋值,如下示例:
# 直接使用反引号进行赋值 user1=`echo shiyanlou` # 也可以在字符串中执行命令 user2="shiyanlou `echo MM`"
而对于在字符串中使用反引号执行命令,如果需要使用引号的话,则只能使用双引号。
$(command)
直接将命令写在括号中即可,如下:
# 使用 $() 进行赋值 user1=$(echo syl001) # 查看 user1 echo $user1
对于使用反引号或者使用 $(command)
的方式又被称为命令替换,即使用命令的输出来替换命令本身
使用read定义
除了使用上述的方式定义变量之外,我们还可以使用 read
。
read
命令可以读取标准输入的内容,然后将其赋值给一个变量或数组,多用于接收用户输入。这里我们仅仅介绍使用 read
定义变量,关于数组的内容在后面我们会学习到。
常用的用法如下:
read: 用法: read [-s 关闭回显] [-a 数组] [-n 读取字符数] [-p 提示符] [-t 超时] [名称 ...]
如下,我们通过示例来学习相关的参数的使用:
# 读取用户输入赋值给变量 user1,输入完成后使用回车即可
$ read user1
# 读取用户输入赋值给多个变量,user2,user3,输入的时候需要使用空格分隔
$ read user2 user3
# 使用命令提示符,提示输入
$ read -p "please enter your username:" user4
# -t 指定超时时间,即等待用户输入的时间,不会一直等待用户的输入,设置的时间单位为秒
$ read -p "username:" -t 5 user6 user7
# -s 不会显示输入的内容,
$ read -s user8
使用 declare 定义
declare
属于 bash 的内建命令,可以声明变量并赋值给声明的变量属性值。
常用的选项如下:
-r
设置只读,-l
使值中所有的大写字母转换为小写-u
小写转换为大写
$ declare user1=shiyanlou001
$ echo $user1
shiyanlou001
$ declare -r user2=shiyanlou2
$ echo $user2
shiyanlou2
$ user2=test
-bash: user2: readonly variable
引用变量$
之前使用 echo
输出变量时需要在变量名前面加 $
符号,这是因为在 shell
中变量是无类型的。
而为了区分到底引用的是变量的值还是字符串,需要在变量名前面使用美元符号 $
。
引号的使用
在使用变量时,如果变量存在于引号内,则必须使用双引号。
如下示例:
# 首先定义 user1 变量
user1=syl001
# 正确的引用,在 user2 中使用,不使用引号
user2=hello$user1
# 正确的引用,在 user2 中使用,使用双引号
user2="hello $user1"
# 正确的引用,
user2="hello"$user1"hello"
user2='hello'$user1'hello'
# 错误的引用,在 user2 中引用,使用单引号
user2='hello $user1'
扩展变量${}
引用变量除了使用 $var
格式直接引用变量之外,还可以使用 ${var}
的方式对变量进行扩展。常见的形式如下表:
表达式 | 说明 |
---|---|
${var} | 等同于 $var |
${var:-word} | 如果 $var 的变量值为空或未赋值,则返回 word 字符串,防止变量为空值或因未定义而导致异常 。 |
${var:=word} | 如果 $var 的变量值为空或未赋值,则设置这个变量值为 word ,并返回其值。位置变量和特殊变量不适用。基本同上一个,但该变量又额外给 $var 变量赋值了。 |
${var:?word} | 如果 $var 变量值为空或未赋值,那么 word 字符串将被作为标准错误输出,否则输出变量的值。用于捕捉由于变量未定义而导致的错误,并退出程序。 |
${var:+word} | 如果 $var 变量值为空或未赋值,则什么都不做,否则返回 word 字符串的值,也就是整个表达式的值为 word 。 |
同上述内容一样,使用 ${var}
及其扩展方式不适用于单引号。
如下示例,编写 test1.sh
脚本:
#!/bin/bash
# 定义 $user1 变量
user1=syl001
# 打印 $user1 变量
echo $user1 ${user1}
syl001 syl001
# 打印 $user1 $user2。而 $user2 不存在,打印 syl002
echo $user1 ${user2:-syl002}
syl001 syl002
# 上一步并未设置 $user2 的值,所以这里只能打印出 $user1
echo $user1 $user2
syl001
# 打印 $user1 并设置 $user2 的值
echo $user1 ${user2:=syl002}
syl001 syl002
# 此时,能够打印出 $user1 $user2
echo $user1 $user2
syl001 syl002
特殊变量
位置参数
位置参数代表的是 bash
脚本执行时的命令行参数,也代表 bash
脚本中定义的函数参数,而关于函数的内容在后面的章节中我们会学习到。
如下表中的位置参数:
变量 | 含义 |
---|---|
$n | 传递给脚本或函数的参数。n 是一个非负的整数,表示第几个参数。例如,第一个参数是 $1 ,第二个参数是 $2 。在 n 大于等于 10 的时候,需要使用 ${n} |
如下示例,我们编辑 test2.sh
脚本文件:
#!/bin/bash
echo $1 $2 $3
echo ${12} $12
使用如下语句运行:
$ bash test2.sh 1 2 3 4 5 6 7 8 9 0 a b c
1 2 3
b 12
其它特殊参数
除此之外,还有一些特殊的参数,这些变量仅仅可以被引用,而不可以被修改,说明如下:
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
$# | 传递给脚本或函数的参数数量 |
$* | 传递给脚本或函数的所有参数 |
$? | 获取执行上一个指令的执行状态返回值(0 为成功,非零为失败),我们之前已经用到了 |
$$ | 获取当前执行的 shell 脚本的进程号(PID) |
$! | 获取上一个在后台工作的进程的进程号 |
$_ | 获取在此之前执行的命令或脚本的最后一个参数 |
我们通过示例来学习这一部分内容,编写 test.sh
脚本文件:
#!/bin/bash
# 打印所有的参数个数
echo $#
# 打印所有的位置参数
echo ${*:-"no parameter"}
# 打印当前执行的进程号
echo $$
# 打印之前命令的最后一个参数,也就是进程号
echo $_
ubuntu@VM-0-5-ubuntu:~$ bash test.sh
0
no parameter
8927
8927
ubuntu@VM-0-5-ubuntu:~$ bash test.sh 1 2 3 a b c
6
1 2 3 a b c
9068
9068
ubuntu@VM-0-5-ubuntu:~$ echo $_
c
删除变量
对于定义的变量我们可以使用 unset
命令进行删除操作,两个常用的选项如下:
-f
仅删除函数-v
仅删除变量
如下示例,我们定义变量,然后将其删除:
# 定义
user1=shiyanlou001
user2=shiyanlou002
# 查看值
echo $user1 $user2
# 删除
unset user1 user2
# 删除后再次查看
echo $user1 $user2