Shell变量与使用
常用内置变量
函数或者命令接收参数时,按照位置获取参数。
工具/表达式 | 案例说明 |
---|---|
$0 | 代表命令或者脚本本身,如常用basename $0 输出脚本名称本身。 |
$1~$n | 第1个到第n个参数,从第10参数开始,引用时要加{} ,如${10} |
$# | 传入的参数个数 |
$* | 传入的全部参数 |
$@ | 传入的全部参数 |
$$ | 当前运行的进程ID |
$! | 最后一个后台进程的ID |
$? | 最后一个执行命令的返回码 |
$_ | 最后执行的命令的最后一个参数的值 |
$PPID | shell 的父进程的进程号 |
$BASH | 扩展为用来启动当前 bash 实例的文件全名 |
$BASH_VERSION | 一个只读数组变量,成员保存着当前 bash 实例的版本信息。 赋予数组元素的值是如下这些: BASH_VERSINFO[0] 主版本号 (release).BASH_VERSINFO[1] 次版本号 (version).BASH_VERSINFO[2] 补丁版本BASH_VERSINFO[3] 编译信息BASH_VERSINFO[4] 发布时的状态 (例如, beta1).BASH_VERSINFO[5] MACHTYPE 平台类型 |
$UID | UID 扩展为当前用户的 ID,在启动时初始化。 |
$GROUPS | 一个数组变量,包含当前用户所属的组的列表 |
$HOME | 前用户的个人家目录,内建命令 cd 的默认参数 |
$HOSTNAME | 自动设置为当前的主机名。 |
$IFS | 内部字段分隔符 Internal Field Separator 用来在扩展之后进行分词 |
$PATH | 索命令的路径 |
$PWD | 由 cd 命令设置的当前工作目录。 |
$OLDPWD | 上一次命令 cd 设置的工作目录。 |
$LINENO | 引用这个参数时,shell 将它替换为一个指示在脚本或函数中当前行号的十进制数字(从 1 开始) |
$FUNCNAME | 前执行的 shell 函数名。 |
$OSTYPE | 正在运行 bash 的操作系统类型。 |
$MACHTYPE | 正在运行 bash 的硬件系统类型 |
$RANDOM | 引用这个参数时,都会产生一个 0 到 32767 之间的随机整数 |
$SECONDS | 引用这个参数时,返回 shell 自运行以来的秒数 |
$TMOUT | 如果设置为大于 0 的值,TMOUT 被当作内建命令 read 的默认超时 等待时间。可以用来设置终端无操作的超时时间 |
$HISTSIZE | 令历史中保存的历史数量,默认值是 500。 |
$PS1 | 用作主提示符字符串 |
$PS2 | 个参数的值同 PS1 一起被扩展,用作次提示符字符串。 |
$PS4 | 这个参数的值同 PS1 一起被扩展,在执行跟踪中在 bash 显示每个命令之前显示 |
更多内置变量详情,可查看man bash
变量的声明
#!/bin/bash
var1= #变量赋值为空串
var2=abc #变量赋值为abc
var3='$sales' #使用单引号,避免字符串$符号被解析
var4="book." #使用双引号
var5="${var4}" #变量的结果可以赋值给另一变量
var6=4 #变量值可以为数字, 在shell变量存储是以字符串方式存储
var7=3.14159
var8=$(( ( ${var6} + 10 ) * 2 )) #表达式的结果可以赋值给变量
var9=$( echo "scale=2; ${var6}*${var7}/3" | bc ) # 命令的执行结果可以赋值给变量
var10=`expr ${var6} + ${var8}` # 另一种执行命令的方式,结果赋值给变量
var11=( 'a' 'b' 'c' 'd' ) # 变量可以为数组
- 变量名由数字、字母、下划线组成,并且必须以数字,字母开头,不能包含Shell关键字。
- 变量名称与值之间用
=
连接,=两边不能有空格。在$((...))
,$[...]
表达式内除外。 - Bash变量可以不用指定类型,默认都是字符串。
- 变量赋值使用单引确保引号内的字符串不被转义,不被解析,保持原本输出。 而使用双引号,引号内字符串包含变量,命令,转义符将先会被解析后再赋值给变量。
只读变量 的定义
用readonly
声明的变量是只读的,不能修改。
#!/bin/bash
readonly var="TEST"
var="MOD"
执行修改:
$ bash test.sh
test.sh:行4: var:只读变量
readonly
和local
不能同时使用,如果同时使用,则在最前面的生效,后面的则失效
如 readonly loacl var=123
: readonly
生效,local
失效。
如 local readonly var=123
:local
生效,readonly
失效。
声明变量类型
declare -i
: 声明整型变量
$ declare -i value=123 #声明一个整型
$ echo $value
123
$ value=abc #将字符串赋值给整型变量,结果被转换为0
$ echo $value
0
declare -r
: 声明只读变量
$ declare -r value=123 #声明只读变量,等同readonly rdval=123
$ value=456 #只读变量不能被修改
-bash: rdval:只读变量
$ echo $value
123
declare -a
: 声明数组变量
$ declare arr=('a' 'b' 1 2)
$ echo ${arr[@]}
a b 1 2
declare -f
: 声明函数
在函数定义之前可以先声明
declare -f call_script
call_script()
{
echo "[$(basename $0)] - call declare_test.sh"
}
declare -x
: 声明环境变量
声明变量为环境变量,可在当前Shell进程及其子进程中使用。
#!/bin/bash
declare -i value1=123
declare -r value2=123
declare -a arr=123
declare -f call_script
declare -x DECLARE_VAL # 声明了一个环境变量
call_script()
{
echo "[$(basename $0)] - call test.sh"
DECLARE_VAL="This_is_a_TEST_program" #主进程中赋值环境变量
bash test.sh #调用子脚本,在子进程中使用环境变量
}
call_script #调用声明的函数
子进程脚本如下:
#!/bin/bash
echo "[$(basename $0)] - DECLARE_XVAL=${DECLARE_XVAL}"
调用主脚本,执行结果如下,在子脚本中打印出了环境变量的值。
$ bash main.sh
[main.sh] - call declare_test.sh
[test.sh] - DECLARE_VAL=This_is_a_TEST_program
如果declare
声明的变量是在函数体内,则变量的作用域也仅是函数体内有效。
变量的删除
var=123
unset var
变量的作用域
1、全局变量
全局变量的作用域是从变量定义位置开始,到Shell进程结束,全局变量的作用域不包含当前进程的子进程。
全局变量的声明:
如var="abc"
或者global var="abc"
,以下示例来演示全局变量的作用域。
2、局部变量
局部变量的作用域是在函数体内定义的位置开始,到函数执行完毕。
局部变量的定义,使用local
来定义局部变量,local
只能在函数中使用。
local VariableName=Value
,如local var=123
。
变量替换
表达式 | 案例说明 |
---|---|
${var:-word} | 如果变量var已经设置且非空,结果为var的值,否则结果为word |
${var:=word} | 如果变量var已经设置且非空,结果为var的值,否则设置var为word |
${var:+word} | 如果变量var已经设置且非空,则设置var的值为word;否则不替换 |
${var:?word} | 如果变量var已经设置且非空,则替换为word,否则退出shell。 |