Shell 编程基础 - 变量
局部变量
所谓局部变量就是指在某个 Shell 中生效的变量,对其他 Shell 来说无效,而且会随着当前 Shell 的消失而消失,局部变量的作用域被限定在声明它们的 Shell 中,可以使用 local 内建命令来“显式”的声明局部变量,但仅限于函数内使用。换言之,每个 Shell 都有自己的变量空间,彼此互不影响。而环境变量不仅仅是对于该 Shell 生效,对其子 Shell 也同样生效。
环境变量
环境变量通常又称“全局变量”,以区别于局部变量。在Shell脚本中,变量默认就是全局的,无论在脚本的任何位置声明,但是为了让子 Shell 继承当前 Shell 的变量,则可以使用 export 内建命令将其导出为环境变量。export VAR=value
bash 中有几十个预设的环境变量
变量 | 说明 |
---|---|
BASH | Bash Shell 的全路径。 |
BASH_VERSION | Bash Shell 的版本。 |
CDPATH | 用于快速进入某个目录。 |
EUID | 记录当前用户的 UID。 |
FUNCNAME | 在用户函数体内部,记录当前函数体的函数名。 |
HISTCMD | 记录下一条命令在 history 命令中的编号。 |
HISTFILE | 记录 history 命令记录文件的位置。 |
HISTFILESIZE | 设置 HISTFILE 文件记录命令的行数。 |
HISTSIZE | 缓冲区的大小。 |
HOSTNAME | 展示主机名。 |
HOSTTYPE | 展示主机的架构。 |
MACHTYPE | 主机类型的 GNU 标识,这种标识有统一的结构。 |
LANG | 设置当前系统的语言环境,其实就是 language 的意思。 |
PWD | 记录当前目录。 |
OLDPWD | 记录之前目录,这个值是什么由之前所在的那个目录决定。 |
PATH | 代表命令的搜索路径,非常重要。 |
PS1 | 命令提示符。 |
… | … |
[root@localhost shell]# bash -x echobash.sh
+ vars=(BASH BASH_VERSION CDPATH EUID FUNCNAME HISTCMD HISTFILE HISTFILESIZE HISTSIZE HOSTNAME HOSTTYPE MACHTYPE LANG PWD OLDPWD PATH PS1)
+ for var in '${vars[@]}'
+ eval echo '$BASH'
++ echo /usr/bin/bash
/usr/bin/bash
+ for var in '${vars[@]}'
+ eval echo '$BASH_VERSION'
++ echo '4.2.46(2)-release'
4.2.46(2)-release
+ for var in '${vars[@]}'
+ eval echo '$CDPATH'
++ echo
+ for var in '${vars[@]}'
+ eval echo '$EUID'
++ echo 0
0
+ for var in '${vars[@]}'
+ eval echo '$FUNCNAME'
++ echo
+ for var in '${vars[@]}'
+ eval echo '$HISTCMD'
++ echo 1
1
+ for var in '${vars[@]}'
+ eval echo '$HISTFILE'
++ echo
+ for var in '${vars[@]}'
+ eval echo '$HISTFILESIZE'
++ echo
+ for var in '${vars[@]}'
+ eval echo '$HISTSIZE'
++ echo 1000
1000
+ for var in '${vars[@]}'
+ eval echo '$HOSTNAME'
++ echo localhost
localhost
+ for var in '${vars[@]}'
+ eval echo '$HOSTTYPE'
++ echo x86_64
x86_64
+ for var in '${vars[@]}'
+ eval echo '$MACHTYPE'
++ echo x86_64-redhat-linux-gnu
x86_64-redhat-linux-gnu
+ for var in '${vars[@]}'
+ eval echo '$LANG'
++ echo zh_CN.UTF-8
zh_CN.UTF-8
+ for var in '${vars[@]}'
+ eval echo '$PWD'
++ echo /vDisk/home/shell
/vDisk/home/shell
+ for var in '${vars[@]}'
+ eval echo '$OLDPWD'
++ echo
+ for var in '${vars[@]}'
+ eval echo '$PATH'
++ echo /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
+ for var in '${vars[@]}'
+ eval echo '$PS1'
++ echo
变量命名
Shell 中的变量必须以字母或者下划线开头,后面可以跟数字、字母和下划线,变量长度没有限制。下面列举了一些变量命名,注意 Shell 的变量是区分大小写的,这也就表示 firstname 和 FIRSTNAME 是不同的两个变量。
变量赋值和取值
[root@localhost shell]# cat variate.sh
#!/bin/bash
#定义变量
name=liushu
#变量名和变量值直接用等号紧紧相连,之间没有任何空格,否则出错
#带空格的值必须加引号,单引号双引号都可以
name1="Hello World"
#取值需要在变量名前面加上 $ 即可,严谨一点的写法是 ${}
echo $name
echo ${name1}
[root@localhost shell]# bash variate.sh
liushu
Hello World
取消变量
[root@localhost shell]# cat variate.sh
#!/bin/bash
#定义变量
name=liushu
#输出
echo $name
#取消变量
unset name
#输出无值
echo $name
[root@localhost shell]# bash variate.sh
liushu
特殊变量
[root@localhost shell]# cat variate.sh
#!/bin/bash
#接收命令行传来的参数
#脚本文件名
echo $0
#第一个参数
echo $1
#第二个参数
echo ${2}
#第三个参数
echo $3
#全部参数
echo $@
#参数个数
echo $#
[root@localhost shell]# bash variate.sh 1000 Hello
variate.sh
1000
Hello
1000 Hello
2
# 脚本返回值
# $?
[root@localhost shell]# echo $?
0
[root@localhost shell]# ifonfi
-bash: ifonfi: 未找到命令
[root@localhost shell]# echo $?
127
数组
数组定义
[root@localhost shell]# cat variate.sh
#!/bin/bash
#定义数组
declare -a Array
#赋值
Array[0]=1000
Array[1]=2000
#输出
echo ${Array[0]}
echo ${Array[1]}
[root@localhost shell]# bash variate.sh
1000
2000
[root@localhost shell]# cat variate.sh
#!/bin/bash
#定义数组同时赋值
declare -a Name=('liushu' 'baililiushu')
#增加元素
Name[2]="Hello World"
echo ${Name[0]}-${Name[1]}-${Name[2]}
#不使用 declare 关键字
NewName=('ls' 'blls')
echo ${NewName[0]}-${NewName[1]}
#跳号赋值
Name1=([3]=300 [5]=500 [7]=700)
echo ${Name1[3]}-${Name1[5]}-${Name1[7]}
[root@localhost shell]# bash variate.sh
liushu-baililiushu-Hello World
ls-blls
300-500-700
数组操作
- 数组取值
${Array[0]}
取所有${Array[@]}
或${Array[*]}
- 数组长度
${#Array[@]}
或${#Array[*]}
- 数组截取
${Array[@]:1:2}
从下标 1 开始截取 2 个元素 - 连接数组
conn=(${Array[@]} ${Name[@]})
- 替换数组
Array=(${Array[@]/HelloWorld/HelloLiuShu})
- 取消数组或元素
unset Array[1]
unset Array
只读变量
只读变量又称常量,是通过 readonly 内建命令创建的变量。这种变量在声明时就要求赋值,并且之后无法修改,这和之前讲到的使用 declare -r 声明只读变量的效果是一致的。
[root@localhost shell]# readonly R0=100
[root@localhost shell]# R0=200
-bash: R0: 只读变量
变量的作用域
变量的作用域又叫“命名空间”,在 Linux 系统中,不同进程 ID 的 Shell 默认为一个不同的命名空间。
[root@localhost shell]# cat namespace1.sh
#!/bin/bash
var1=100
echo var1 in $0 is $var1
#这里调用 namespace2.sh
bash namespace2.sh
[root@localhost shell]# cat namespace2.sh
#!/bin/bash
var1=200
echo var1 in $0 is $var1
[root@localhost shell]# bash namespace1.sh
var1 in namespace1.sh is 100
var1 in namespace2.sh is 200
[root@localhost shell]# cat namespace3.sh
#!/bin/bash
var1=100
#定义函数
function change() {
var1=200
}
echo before var1 is $var1
#调用函数
change
echo now var1 is $var1
[root@localhost shell]# bash namespace3.sh
before var1 is 100
now var1 is 200