环境变量是 Bash 环境自带的变量,env
或 printenv
命令,可以显示所有变量。
env
# or
printenv
常见环境变量
BASHPID
Bash 进程IDBASHOPTS
当前 Shell 的参数,可以通过shopt
命令修改DISPLAY
图形环境的显示器名字EDITOR
默认的文本编辑器HOME
用户的主目录HOST
当前主机名称IFS
词与词之间的分隔符,默认是空格LANG
字符集以及语言编码PATH
由冒号分开的目录列表,当输入可执行程序名后,会搜索这个目录列表PS1
Shell 提示符PS2
输入多行命令时,次要的 Shell 提示符PWD
当前工作目录RANDOM
返回一个 0 到 32767 之间的随机数SHELL
Shell 的名字SHELLOPTS
启动当前 Shell 的set
命令参数TERM
终端类型名,即终端仿真器用的协议UID
当前用户的 ID 编号USER
当前用户的用户名
set
命令可以显示所有变量(包括环境变量和自定义变量),以及所有 Bash 函数。
set
用户创建变量时,变量名必须遵守下面规则:
- 字母、数字和下划线字符组成
- 第一个字符不能是数字
- 字母严格大小写
- 等号两边不能有空格
- 如果变量的值包含空格,必须放入引号中
- 赋值重复,后面会覆盖前面的值
variable=value
Bash 没有数据类型的概念,所有变量值都是字符串。 下面是一些自定义变量例子:
a=z
b="a string"
c="a string and $b"
d="\t\ta string\n"
e=$(ls -l foo.txt)
f=$((5 * 7))
读取变量的时候,直接在变量名前加 $
即可。
如果变量不存在, Bash 不会报错,而会输出空字符。
foo=bar
echo $foo
读取变量的时候,变量名可以使用花括号 {}
包围,比如 $a
可以写成 ${a}
。
这种写法可以用于变量名与其他字符连用的情况。
a=foo
echo $a_file
echo ${a}_file
如果变量的值本身也是变量,可以使用 ${!varname}
的语法,读取最终的值。
myvar=USER
echo ${!myvar}
unset
命令来删除一个变量,或者将变量复制为空。
foo=bar
unset foo
# or
foo=
用户创建的变量仅可用在当前Shell,子 Shell 默认读取不到父 Shell 定义的变量。为了把变量传递给子 Shell,需要使用 export
命令。
子 Shell 对该变量做修改,不影响父 Shell export 变量的值。
NAME=foo
export NAME
# or
export NAME=foo
# then
bash
echo $NAME
$?
为上一个命令的退出码,用来判断上一个命令是否执行成功。如果$?
结果是 1,表示上一个命令执行失败$$
输出当前 Shell 的进程 ID$_
为上一个命令的最后一个参数$!
为最后一个后台执行的异步命令的进程 ID$0
当前 Shell 的名词,或者脚本名$-
当前的 Shell 启动参数$@
和$#
表示脚本参数数量
Bash 提供四种语法与变量默认值有关。
${varname:-word}
如果 varname 不存在,返回 word,否则返回 varname 的值${varname:=word}
如果 varname 不存在,设置 varname 的值为 word,并返回 varname${varname:+word}
如果 varname 不存在,返回 word,否则返回空值${varname:?message}
如果 varname 不存在, 打印 message,并中断脚本执行
在脚本中,可以用 1 到 9 来表示脚本的参数,1 就是第一个参数。
filename=${1:?"filename missing"}
# 表示第一个参数缺失
declare
命令可以声明一些特殊类型的变量,为变量设置一些限制,比如声明只读类型的变量和整数类型的变量。
语法如下:
declare OPTION VARIABLE=true
OPTION 主要参数如下:
-a
声明数组变量-f
输出当前环境的所有函数定义-F
输出当前环境的所有函数名-i
声明整数变量-l
声明变量为小写字母,声明后,设值时都会被转为小写-u
声明变量为大写字母,声明后,设值时都会被转为大写-p
查看变量信息-r
声明只读变量-x
该变量输出位环境变量
declare
命令如果在函数中,声明的变量只在函数内部有效,等同于 local
命令。
不带任何参数时,declare
命令输出当前环境的所有变量,包含函数在内,等同于不带任何参数的 set
命令。
-i
参数声明整数变量后,可以直接进行数学运算,如果不设置 result 为整数类型,val1*val2 会被当成字面量:
declare -i val1=12 val2=5
declare -i result
result=val1*val2
echo $result
result2=val1*val2
echo $result2
-x
等同于 export
命令。
declare -x foo=bar
# equals
export foo=bar
-r
声明只读变量,无法改变变量值,也不能 unset
变量。
declare -r bar=1
bar=2
-p
打印变量信息。
declare -ir bar=100
declare -p bar
设置变量只读,等同于declare -r variable
。
# 设置 foo 只读,值为 1
readonly foo=1
# 打印当前环境下所有只读的变量
readonly -p
let
命令声明变量时,可以直接执行算术表达式。
let foo=1+2
echo $foo
如果参数表达式包含空格,需要加引号。
let "foo = 1 + 2"
let
可以同时对多个变量赋值,赋值表达式之间用空格分隔。
let "v1=1" "v2=2" "v3=++v1"
echo $v1,$v2,$v3