变量和引用
内容参考 《Shell 从入门到精通》
目录
变量
Shell 是动态型和弱类型的语言,所以在Shell 中,定义变量不用向Java C C++什么的声明变量的类型:
a=1
b="string"
echo "a = $a , b = $b"
let "a+=1"
#将b中的g变为..
c=${b/g/..}
echo "a = $a , b = $b , c = $c"
我们看一下运行结果
a = 1 , b = string
a = 2 , b = string , c = strin..
当然,有一个命令可以使用参数定义对应的变量:declare
[注] $是取值符号,定义和赋值的时候不用使用,标准使用语法 ${x} 简写为 $x,在某些情况下会产生错误
declare
基本语法 declare attribute variable
attribute 参数可选列表
序号 | 参数 | 说明 |
1 | -p | 显示所有变量的值 |
2 | -i | 将变量i定义为整数。在之后就可以直接对表达式求值,就过只能是整数。如果求值失败或者不是整数,就设置为0 |
3 | -r | 将变量声明为只读变量。只读变量不允许修改,也不允许删除 |
4 | -a | 变量声明为数组变量。但这没有必要。所有的变量都不必显示定义就可以用作数组。事实上,在某种意义上,所有的变量都是数组,而是i赋值给没有下标的变量与赋值给下标为0的数组元素相同 |
5 | -f | 显示所有的自定义函数,包括名称和函数体 |
6 | -x | 将变量设置成环境变量,这样在随后的脚本和程序中可以使用 |
下面我们看看 declare -i 的使用
x=6/3
echo "$x"
#将x声明为整数,此时还未对x操作,x的值仍然是6/3
declare -i x
echo "$x"
#对x进行运算操作,x=6/3==2
x=6/3
echo "$x"
#将字符串赋值给x,不是整数,x变为0
x=hello
echo "$x"
#将x赋值为3.14,不是整数,x为0
x=3.14
echo "$x"
输出
6/3
6/3
2
0
/home/dcpnet/桌面/Code/Java/Test/test/shell/Test.sh:行10: 3.14:语法错误: 无效的算术运算符 (错误符号是 ".14")
0
在没有对x增加整型数值限制之前,x可以是字符串。但是对x添加整型数值限制后,再对其进行赋值:如果不是整型,x就变为0
接着上面的代码继续写
#取消x为整形变量
declare +i x
x=6/3
echo "x = $x"
#对x进行赋值运算
x=$[6/3]
echo "x = $x"
#对x进行赋值运算
x=$((6/2))
echo "x = $x"
#将x设置为只读变量
declare -r x
echo "x = $x"
x=5
echo "x = $x"
输出
x = 6/3
x = 2
x = 3
x = 3
/home/dcpnet/桌面/Code/Java/Test/test/shell/Test.sh:行27: x:只读变量
x = 3
可以看到,取消x的整数限制后,他有可以变成字符串了。当然运算可以使用 $[] 和 $() 来进行计算。
然后我们将x设置为只读 -r ,我们再进行赋值操作,可以看到报错了,提示不可修改,x仍然为3
引号
在 Shell 中,有三种引号 单引号 '' 、双引号"" 、反引号``
- 单引号中内容都将作为普通字符串
- 反引号中的内容将被解释为命令
当然在双引号中: \(转移符号) ,$,`` 的特殊功能仍然保留
我们以一个示例来展示一下工作机制吧
#!/bin/bash
x=1
echo "$x"
echo '$x'
echo "Current Directory:`pwd`"
输出
1
$x
Current Directory:/home/dcpnet/桌面/Code/Java/Test/test/shell
变量作用域
因为有函数的存在,变量作用域分为 全局变量 以及 局部变量
在Shell 中函数内定义的就是并不是局部变量:
#!/bin/bash
#定义函数
function test() {
echo "[Method-test] 中 $v"
v=200
#在方法内定义全局变量x
x=6
}
#在方法外定义全局变量v
v=100
#还未执行方法,x未定义
echo "x = $x"
test
echo "x = $x"
echo "v = $v"
输出
x =
[Method-test] 中 100
x = 6
v = 200
可以看到,方法中定义的变量也是全局变量。那么局部变量是怎么定义的呢?
local 局部变量
在 Shell 中定义局部变量需要在变量前加上 local 修饰符
#!/bin/bash
#定义函数
function test() {
local v=200
echo "[Method-test] 中 v = $v"
}
#在方法外定义全局变量v
v=100
echo "v = $v"
test
echo "v = $v"
输出
v = 100
[Method-test] 中 v = 200
v = 100
可以看出,在方法中定义的局部变量只作用于方法中
系统变量
Shell 语言的系统变量主要对参数判断和命令返回值判断时使用,包括脚本和函数的参数,以及脚本和函数的返回值。Shell中的系统变量并不多,但是十分有用,特别是在做一些参数检测的时候:
序号 | 变量 | 说明 |
---|---|---|
1 | $n | n是一个整数,从1开始,表示参数的位置,例如$2表示第二个参数 |
2 | $# | 命令行参数的个数 |
3 | $0 | 当前Shell脚本的名称 |
4 | $? | 前一个命令或者函数的状态码 |
5 | $* | 以“参数1 参数2 ....”的形式将所有的参数通过一个字符串返回 |
6 | $@ | 以 "参数1" "参数2" ...... 的形式返回每个参数 |
7 | $$ | 返回本程序的进程ID |
下面我们把每个都使用一遍看看效果
#!/bin/bash
#输出参数个数
echo "脚本:$0"
#命令行参数的个数
echo $#
#输出参数
echo "args[1] = $1 ,args[2] = $2"
#以一个命令或者函数的推出状态码
echo "\$? = $?"
#以“参数1 参数2 ....”的形式将所有的参数通过一个字符串返回
echo "\$*= $*"
# shellcheck disable=SC2145
#以 "参数1" "参数2" ...... 的形式返回每个参数
echo "\$@ = $@"
#本进程ID
echo "\$$ = $$"
输出
root@kali:/home/dcpnet/桌面/Code/Java/Test/test/shell# ./Test.sh a b c d e f g
脚本:./Test.sh
7
args[1] = a ,args[2] = b
$? = 0
$*= a b c d e f g
$@ = a b c d e f g
$$ = 4399
环境变量
Shell的环境变量就是所有Shell程序都可以使用的变量。Shell程序在运行的时候,都会接受一组变量,这组变量就是环境变量。环境变量会影响到所有脚本的执行结果。下面是一些常用的Shell 变量
序号 | 变量 | 说明 |
---|---|---|
1 | PATH | 命令搜索路径,以冒号为分割符。注意与Windows下不同的是,当前目录不再系统路径里 |
2 | HOME | 用户主目录的路径名,是CD命令的默认参数 |
3 | COLUMS | 定义了命令编辑模式下可使用的命令行长度 |
4 | HISTFILE | 命令历史文件 |
5 | HISTSIZE | 命令历史文件中最多可包含的命令条数 |
6 | HISTFILESIZE | 命令历史文件中包含的最大行数 |
7 | IFS | 定义Shell 使用的分隔符 |
8 | LOGNAME | 当前的登录名 |
9 | SHELL | Shell的全路径名 |
10 | TERM | 终端类型 |
11 | TMOUT | Shell 自动推出的时间,单位为秒,若设为0则禁止Shell自动退出 |
12 | PWD | 当前工作目录 |
除了上面列出的一些常用的变量之外,还可以通过 set 命令列出所有的环境变量
下面我们通过一个Shell 文件来试试:
#!/bin/bash
echo "命令路径 [PATH]=$PATH"
echo "当前登录的用户名 [LOGNAME]=$LOGNAME"
echo "当前的用户目录 [HOME]=$HOME"
echo "当前的Shell是 [SHELL]=$SHELL"
echo "当前的工作目录 [PWD]=$PWD"
echo "当前的终端类型 [TERM]=$TERM"
输出
命令路径 [PATH]=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
当前登录的用户名 [LOGNAME]=dcpnet
当前的用户目录 [HOME]=/home/dcpnet
当前的Shell是 [SHELL]=/bin/bash
当前的工作目录 [PWD]=/home/dcpnet/桌面/Code/Java/Test/test/shell
当前的终端类型 [TERM]=xterm-256color
当然,在你的电脑上输出的内容基本不一样,因为你电脑登录的是你,工作目录也是你设定的
清除变量
当某个Shell 变量不再需要的时候,可以将其清楚。当变量被清除后,其所代表的值也会小时。清楚变量使用unset语句:
语法格式 : unset varible_name
示例
#!/bin/bash
x=100
echo "x = ${x}"
unset x
echo "x = ${x}"
输出
x = 100
x =
可以看出x被清除后,数据消失了。