3.1、系统预定义变量
3.1.1、常用系统变量
$HOME
、$PWD
、$SHELL
、$USER
等
3.1.2、案例实操
(1)查看系统变量的值
[root@test001 ~]# echo $HOME
/root
[root@test001 ~]# echo $USER
root
[root@test001 ~]# echo $SHELL
/bin/bash
[root@test001 ~]# echo $PWD
/root
(2)显示当前Shell中所有的变量:set
[root@test001 bash]# set
3.2、自定义变量
3.2.1、基本语法
- 定义变量:变量名称=变量值,注意:=号前后不能有空格
- 撤销变量:unset 变量
- 声明静态变量:readonly 变量,注意:这种类型的变量不能unset
- 访问变量
$变量名称
,要在变量名称前面添加一个$
符号,比如输出变量A:echo$A
${变量名称}
,如:echo${A}xxx
,在变量A后面拼接一个xxx输出,若使用echo$Axxx
,相当于输出变量Axxx的值
3.2.2、变量定义规则
- 变量名称可以有字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写
- =号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
- 变量的值如果有空格,需要使用双引号或单引号括起来
3.2.3、案例实操
(1)定义变量A
[root@test001 bash]# A=5
[root@test001 bash]# echo $A
5
(2)给变量A重新赋值
[root@test001 bash]# A=8
[root@test001 bash]# echo $A
8
(3)撤销变量A
[root@test001 bash]# unset A
[root@test001 bash]# echo $A
[root@test001 bash]#
(4)声明静态变量B=2,不能unset
[root@test001 bash]# readonly B=2
[root@test001 bash]# echo $B
2
[root@test001 bash]# unset B
-bash: unset: B: 无法反设定: 只读 variable
(5)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
[root@test001 bash]# C=1+2
[root@test001 bash]# echo $C
1+2
(6)变量的值如果有空格,需要使用双引号或单引号括起来
[root@test001 bash]# D="hello tom"
[root@test001 bash]# echo $D
hello tom
3.2.4、export将变量提升为全局环境变量
子shell无法访问父shell中定义的变量,先来一段命令,打卡一个新的窗口,执行下面命令
[root@test001 ~]# A=tom
[root@test001 ~]# echo $A
tom
[root@test001 ~]# bash
[root@test001 ~]# echo $A
[root@test001 ~]#
在定义变量的shell中,使用export 变量名
将变量提升为全局变量,这样内部的所有子shell都可以访问这个变量了,打开一个新的窗口,执行下面命令
[root@test001 ~]# A=tom
[root@test001 ~]# export A
[root@test001 ~]# bash
[root@test001 ~]# echo $A
tom
[root@test001 ~]# bash
[root@test001 ~]# echo $A
tom
[root@test001 ~]# ps -f
UID PID PPID C STIME TTY TIME CMD
root 3479 3475 0 16:43 pts/0 00:00:00 -bash
root 3531 3479 0 16:43 pts/0 00:00:00 bash
root 3571 3531 0 16:43 pts/0 00:00:00 bash
root 3831 3571 0 16:47 pts/0 00:00:00 ps -f
[root@test001 ~]# ps --forest
PID TTY TIME CMD
3479 pts/0 00:00:00 bash
3531 pts/0 00:00:00 \_ bash
3571 pts/0 00:00:00 \_ bash
3833 pts/0 00:00:00 \_ ps
3.3、特殊变量
3.3.1、$n:访问shell 的参数
(1)基本语法
执行shell脚本的时候,是可以带参数的,在shell脚本中可以通过$n来访问参数。
$n
(功能描述:n为数字,$0
代表该脚本名称,$1-$9
代表第1到到9个参数,十以上的参数需要用大括号包含,如${10}
)
(2)案例
[root@test001 shells]# touch parameter.sh
[root@test001 shells]# vi parameter.sh
#!/bin/bash
echo '========$n======='
echo $0
echo $1
echo $2
[root@test001 shells]# chmod +x parameter.sh
[root@test001 shells]# ./parameter.sh java spring
========$n=======
./parameter.sh
java
spring
[root@test001 shells]# /root/shells/parameter.sh tom jack
========$n=======
/root/shells/parameter.sh
tom
jack
3.3.2、$#:获取参数个数
(1)基本用法
$#
(功能描述: 获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性)
(2)案例
[root@test001 shells]# vi parameter.sh
#!/bin/bash
echo '========$n======='
echo $0
echo $1
echo $2
echo '========$#======='
echo $#
[root@test001 shells]# chmod +x parameter.sh
[root@test001 shells]# ./parameter.sh java spring
========$n=======
./parameter.sh
java
spring
========$#=======
2
3.3.3、$*
和$@
参数
(1)基本语法
变量 | 功能描述 |
---|---|
$* | 这个变量代表命令行中所有的参数, $*把所有的参数看成一个整体 |
$@ | 这个变量也代表命令行中所有的参数, 不过$@把每个参数区分对待 |
(2)案例
[root@test001 shells]# vi parameter.sh
#!/bin/bash
echo '========$n======='
echo $0
echo $1
echo $2
echo '========$#======='
echo $#
echo '========$*======='
echo $*
echo '========$@======='
echo $@
[root@test001 shells]# chmod +x parameter.sh
[root@test001 shells]# ./parameter.sh java spring mysql========$n=======
./parameter.sh
java
spring
========$#=======
3
========$*=======
java spring mysql
========$@=======
java spring mysql
[root@test001 shells]#
(3)$*
和$@
的区别
当 $*
和 $@
不被双引号" "
包围时,它们之间没有任何区别,都是将接收到的每个参数看做一份数据,彼此之间以空格来分隔。
但是当它们被双引号" "
包含时,就会有区别了:
"$*"
会将所有的参数从整体上看做一份数据,而不是把每个参数都看做一份数据。
"$@"
仍然将每个参数都看作一份数据,彼此之间是独立的。
比如传递了 5 个参数,那么对于"$*"
来说,这 5 个参数会合并到一起形成一份数据,它们之间是无法分割的;而对于"$@"
来说,这 5 个参数是相互独立的,它们是 5 份数据。
如果使用 echo 直接输出"$*"
和"$@"
做对比,是看不出区别的;但如果使用 for 循环来逐个输出数据,立即就能看出区别来。
编写下面的代码,并保存为 test.sh:
#!/bin/bash
echo "print each param from \"\$*\""
for var in "$*"
do
echo "$var"
done
echo "print each param from \"\$@\""
for var in "$@"
do
echo "$var"
done
运行 test.sh,并附带参数
[mozhiyan@localhost demo]$ . ./test.sh a b c d
print each param from "$*"
a b c d
print each param from "$@"
a
b
c
d
从运行结果可以发现,对于"$*"
,只循环了 1 次,因为它只有 1 分数据;对于"$@"
,循环了 5 次,因为它有 5 份数据。
3.3.4、$?
变量
1) 基本语法
$?
(功能描述: 最后一次执行的命令的返回状态, 如果这个变量的值为 0, 证明上一个命令正确执行; 如果这个变量的值为非 0(具体是哪个数, 由命令自己来决定) , 则证明上一个命令执行不正确了 )
2)案例
[root@test001 shells]# ./helloworld.sh
helloworld
[root@test001 shells]# echo $?
0
3.3.5、特殊变量总结
变量 | 含义 |
---|---|
$0 | 当前脚本的文件名。 |
$n(n≥1) | 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是 $1,第二个参数是 2 ,若 n 大于 10 ,则语法: 2,若n大于10,则语法: 2,若n大于10,则语法:{n} |
$# | 传递给脚本或函数的参数个数 |
$* | 传递给脚本或函数的所有参数。 |
$@ | 传递给脚本或函数的所有参数。当被双引号" "包含时,$@ 与 $* 稍有不同,具体见上面的3.3.3章节 |
$? | 上个命令的退出状态,或函数的返回值 |
$$ | 当前 Shell 进程 ID。对于 Shell 脚本,就是这些脚本所在的进程 ID。 |
案例:编写下面的代码,并保存为 test.sh:
#!/bin/bash
echo "Process ID: $$"
echo "File Name: $0"
echo "First Parameter : $1"
echo "Second Parameter : $2"
echo "All parameters 1: $@"
echo "All parameters 2: $*"
echo "Total: $#"
运行 test.sh,并附带参数:
[root@test001 shells]# ./test.sh shell linux
Process ID: 131045
File Name: ./test.sh
First Parameter : shell
Second Parameter : linux
All parameters 1: shell linux
All parameters 2: shell linux
Total: 2