Shell 变量
Shell 中可使用的变量大致分为四种: 环境变量, 预定义变量, 脚本变量, 用户自定义变量.
1. 基础知识
1.1 变量分类
- 环境变量: 主要保存的是和系统操作环境相关的变量, 可以新增和修改
- 预定义变量: 系统预设的一些变量
- 脚本变量: 调用脚本时, 传入的参数, 又称位置参数变量
- 用户自定义变量: 脚本中设置的变量
1.2 变量名命名
- 变量名和=号直接不能有空格
- 变量名不能以数字开头, 首个字符只能为字母(A-Z, a-z)
- 变量名直接不能有空格, 可以使用下划线
- 变量名不能使用标点符号
- 环境变量名建议全部大写
1.2 变量赋值
- 变量值与=号直接不能有空格
- 变量类型默认都是字符串类型
- 变量值可以使用特殊符号,转义符号, 如: name="zhang\nsan"
- 变量值可以是命令执行的结果, 用反引号, 如:dt=
date
- 变量值可以是包含其他变量的表达式, 如:result="hello,$name"
2. 环境变量
环境变量通常用于存储一些与系统操作相关的命令, 比如如JAVA_HOME. 在脚本中设置的环境变量, 只在当前脚本中生效, 不会修改系统的环境变量. 通常用于为某些程序的运行准备环境. 比如说, 系统默认安装的是jdk1.7, 而你的程序想要使用jdk 1.8运行 ,那么就可以创建一个脚本, 脚本中先设置JAVA_HOme 的值, 然后再执行你的程序就好了.
1. 变量定义
- 语法1: export NAME=value, 定义新的环境变量
- 语法2: export NAME, 将已有用户自定义变量转换为环境变量
2. 变量引用
对环境变量的引用有两种语法,语法1比较简单常用, 语法2在特殊场景下使用.如:${NAME}script, 如果用用语法1, 那么会找变量名为 NAMEscript 的值, 而不是NAME值了
- 语法1: $NAME
- 语法2: ${NAME}
3. 变量删除:
- 格式: unset NAME
4. 查看所有环境变量:
- 命令: env
5. 测试脚本:
#!/bin/bash
#查看系统环境变量
echo "JAV_HOME:$JAVA_HOME"
# 设置环境变量
export JAVA_HOME=/opt/app/jdk/jdk1.8.0_121
echo "JAVA_HOME:$JAVA_HOME"
# 删除环境变量
unset JAVA_HOME
echo "JAVA_HOME:$JAVA_HOME"
输出结果:
脚本中将环境变量JAVA_HOME 删除了, 脚本中便获取不到JAVA_HOME 环境变量了, 但是脚本执行完之后, 直接输出环境变量JAVA_HOME, 会发现依然存在.
[admin@localhost shell]$ ./var03.sh
JAV_HOME:/opt/app/jdk/jdk1.6.0_31
JAVA_HOME:/opt/app/jdk/jdk1.8.0_121
JAVA_HOME:
[admin@localhost shell]$ echo $JAVA_HOME
/opt/app/jdk/jdk1.6.0_31
[admin@localhost shell]$
3. 预定义变量
预定义变量是系统内置的, 用于表示特殊含义的一些变量. 常用的预定义变量有:
变量名 | 变量含义 |
---|---|
$? | 记录上次执行的命令的返回状态, 返回0 表示执行成功, 否则表示执行错误 |
$$ | 记录当前脚本运行时的进程id |
$! | 记录上次后台运行的进程的PID |
测试脚本
#!/bin/bash
# &> 表示将输出结果重定向, $> /dev/null 表示不输出脚本运行结果
# 系统有此目录, 执行结果成功
ls / &> /dev/null
echo "ls / 执行结果: $?"
# 系统无此目录, 执行结果为失败
ls /hhhh &> /dev/null
echo "ls /hhhh 执行结果: $?"
# 输出当前脚本进程id
echo "当前进程PID: $$"
# 输出上次后台运行进程id
ls / &> /dev/null &
echo "上次后台运行进程id: $!"
输出结果:
[admin@localhost shell]$ ./var01.sh
ls / 执行结果: 0
ls /hhhh 执行结果: 2
当前进程PID: 22798
上次后台运行进程id: 22853
[admin@localhost shell]$
4. 脚本变量
1. 变量引用
变量名 | 变量含义 |
---|---|
$# | 代表传入的参数格式 |
$* | 代表传入的所有参数, 把所有传入的参数当做是一个字符串变量 |
$@ | 代表传入的所有参数, 把所有传入的参数当做一个数组 |
$n | n为数字,从1开始,表示传入的第几个参数,当超过9个参数时,需要用${n} |
$0 | 命令本身 |
2. 示例脚本:
#!/bin/bash
echo '参数数量 $#:' $#
echo '参数列表 $*:' $*
echo '参数数组 $@:' $@
echo '调用命令 $0:' $0
echo '第1 个参数 $1:' $1
echo '第2 个参数 $2:' $2
echo '第10个参数 $10:' ${10}
echo '============== 遍历输出: $* ========================'
# 只有一个元素
for i in "$*"
do
echo "arg:" $i
done
echo '============== 遍历输出: $@ ========================'
# 有多个元素
for y in "$@"
do
echo "arg:" $y
done
测试结果:
[admin@localhost shell]$ ./var01.sh 1 2 3 4 5 6 7 8 9 10
参数数量 $#: 10
参数列表 $*: 1 2 3 4 5 6 7 8 9 10
参数数组 $@: 1 2 3 4 5 6 7 8 9 10
调用命令 $0: ./var01.sh
第1 个参数 $1: 1
第2 个参数 $2: 2
第10个参数 $10: 10
============== 遍历输出: $* ========================
arg: 1 2 3 4 5 6 7 8 9 10
============== 遍历输出: $@ ========================
arg: 1
arg: 2
arg: 3
arg: 4
arg: 5
arg: 6
arg: 7
arg: 8
arg: 9
arg: 10
[admin@localhost shell]$
5. 用户之定义变量
用户自定义的变量,作用域为当前脚本, 也就是说只能在脚本内使用.
1. 变量定义:
- 格式:[readonly] name=value
- 格式:[readonly] name=
命令
- 注意: =号两边不能有空格
- readonly 表示为只读变量, 如果修改会报错
2. 变量引用:
对环境变量的引用有两种语法,语法1比较简单常用, 语法2在特殊场景下使用如: ${name}script, 如果用用语法1, 那么会找变量名为 namescript 的值, 而不是name 值了
- 语法1: $name
- 语法2: ${name}
3. 变量删除:
- 格式: unset name
4. 变量特殊处理
4.1 数字变量运算
- 由于shell 中所有变量都是字符串, 当需要对变量进行数字进行运算时, 使用普通的方式是不能行的, 需要用到$(( a + b))
4.2 字符串拼接
shell 中字符串的拼接符为 .
5. 测试脚本:
#!/bin/bash
#定义变量
name="java"
#变量引用
echo "name:$name"
echo "book:${name}Script"
#删除变量
unset name
echo "name:$name"
#数值运算
a=10
b=5
echo "$a+$b=$(( $a + $b ))"
echo "$a*$b=$(( $a * $b ))"
echo "$a/$b=$(( $a / $b ))"
#获取当前服务器时间
date=`date`
echo "date:$date"
#只读变量
readonly sum=0
sum=1
测试输出:
\[admin@localhost shell\]$ ./var02.sh
name:java
book:javaScript
name:
10+5=15
10*5=50
10/5=2
date:Thu Jun 22 16:40:29 CST 2017
./var02.sh: line 27: sum: readonly variable
\[admin@localhost shell\]$