在命令行提示符直接执行env、set查看系统或环境变量。env显示用户环境变量,set显示Shell预先定义好的变量以及用户变量。可以通过export导出成用户变量。
一些写Shell脚本时常用的系统变量:
$SHELL | 默认Shell |
---|---|
$HOME | 当前用户家目录 |
$IFS | 内部字段分隔符 |
$LANG | 默认语言 |
$PATH | 默认可执行程序路径 |
$PWD | 当前目录 |
$UID | 当前用户ID |
$USER | 当前用户 |
$HISTSIZE | 历史命令大小,可通过HISTTIMEFORMAT变量设置命令执行时间 |
$RANDOM | 随机生成一个0至32767的整数 |
$HOSTNAME | 主机名 |
普通变量定义:VAR=value
临时环境变量定义:export VAR=value
变量引用:$VAR
下面看下他们之间区别:
Shell进程的环境变量作用域是Shell进程,当export导入到系统变量时,则作用域是Shell进程及其Shell子进程。
ps axjf输出的第一列是PPID(父进程ID),第二列是PID(子进程ID)
当SSH连接Shell时,当前终端PPID(-bash)是sshd守护程序的PID(root@pts/0),因此在当前终端下的所有进程的PPID都是-bash的PID,比如执行命令、运行脚本。
所以当在-bash下设置的变量,只在-bash进程下有效,而-bash下的子进程bash是无效的,当export后才有效。
进一步说明:再重新连接SSH,去除上面定义的变量测试下
所以在当前shell定义的变量一定要export,否则在写脚本时,会引用不到。
还需要注意的是退出终端后,所有用户定义的变量都会清除。
在/etc/profile下定义的变量就是这个原理,后面有章节会讲解Linux常用变量文件。
位置变量指的是函数或脚本后跟的第n个参数。从$ 1 到 $ n,需要注意的是从第10个开始要用花括号调用,例如${10}
shift可对位置变量控制,例如:
#!/bin/bash
echo "1: $1"
shift
echo "2: $2"
shift
echo "3: $3"
# bash test.sh a b c
1: a
2: c
3:
每执行一次shift命令,位置变量个数就会减一,而变量值则提前一位。shift n,可设置向前移动n位。
$0 | 脚本自身名字 |
---|---|
$? | 返回上一条命令是否执行成功,0为执行成功,非0则为执行失败 |
$# | 位置参数总数 |
$* | 所有的位置参数被看做一个字符串 |
$@ | 每个位置参数被看做独立的字符串 |
$$ | 当前进程PID |
$! | 上一条运行后台进程的PID |
赋值运算符 | 示例 |
---|---|
= | 变量赋值 |
+= | 两个变量相加 |
# VAR=123
# echo $VAR
123
# VAR+=456
# echo $VAR
123456
Shell中所有变量引用使用 符,后跟变量名。有时个别特殊字符会影响正常引用,那么需要使用 符,后跟变量名。 有时个别特殊字符会影响正常引用,那么需要使用 符,后跟变量名。有时个别特殊字符会影响正常引用,那么需要使用{VAR},例如:
# VAR=123
# echo $VAR
123
# echo $VAR_ # Shell允许VAR_为变量名,所以此引用认为这是一个有效的变量名,故此返回空
# echo ${VAR}
123
还有时候变量名与其他字符串紧碍着,也会误认为是整个变量:
# echo $VAR456
# echo ${VAR}456
123456
# VAR=`echo 123`
# echo $VAR
123
# VAR=$(echo 123)
# echo $VAR
123
这里的反撇号等效于$(),都是用于执行Shell命令。
在变量赋值时,如果值有空格,Shell会把空格后面的字符串解释为命令:
# VAR=1 2 3
-bash: 2: command not found
# VAR="1 2 3"
# echo $VAR
1 2 3
# VAR='1 2 3'
# echo $VAR
1 2 3
看不出什么区别,再举个说明:
# N=3
# VAR="1 2 $N"
# echo $VAR
1 2 3
# VAR='1 2 $N'
# echo $VAR
1 2 $N
单引号是告诉Shell忽略特殊字符,而双引号则解释特殊符号原有的意义,比如$、!。
Shell注释也很简单,只要在每行前面加个#号,即表示Shell忽略解释。