变量
创建变量
变量名=变量值
hw=HelloWorld
引用变量
${变量名}
echo ${hw}
HelloWorld
{}可以省略
echo $hw
HelloWorld
某些情况不能省略,如在变量前后直接追加字符
echo $hws
echo ${hw}s
HelloWorlds
撤销变量
unset 变量名
unset hw
echo ${hw}
本地变量
作用域
只在当前bash进程中有效,对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效
分类
全局变量
变量名=变量值
局部变量
local 变量名=变量值
作用域:局部变量只对当前函数或代码段有效
如果脚本中存在全局变量var,同时某个函数中也有相同变量var被赋值,那么函数中的var值将会覆盖全局变量var的值
cat test.sh
hw=HelloWorld
echo ${hw}
testLocal(){
hw=HiWorld;
echo ${hw};
}
testLocal
echo ${hw}
运行test.sh,结果如下,可见全局变量的值已被覆盖
sh test.sh
HelloWorld
HiWorld
HiWorld
对函数中的变量加上local
cat test.sh
hw=HelloWorld
echo ${hw}
testLocal(){
local hw=HiWorld;
echo ${hw};
}
testLocal
echo ${hw}
运行test.sh,结果如下,可见全局变量的值未被覆盖
sh test.sh
HelloWorld
HiWorld
HelloWorld
环境变量
export 变量=变量值 或
先声明本地变量 变量=变量值 再 export 变量
作用域
当前shell进程及其子进程
与本地变量区别
在当前bash先定义一个本地变量
hw=HelloWorld
test.sh如下
cat test.sh
echo ${hw}
运行test.sh,结果如下,可见并没有输出变量的值
sh test.sh
因为test.sh实际上是在当前bash的子进程中运行,而hw是定义在当前bash中的本地变量
而环境变量可以使test.sh使用当前bash中的变量
定义环境变量
export hw=HelloWorld
运行test.sh,结果如下,可见输出了变量的值
sh test.sh
HelloWorld
source关键字
除了定义环境变量的方式让test.sh可以使用到当前bash中定义的变量之外,还可以使用source关键字
不加source关键字的时候,执行脚本,相当于创建了一个子进程,然后在子进程中运行脚本;如果加了source关键字,相当于没有创建子进程,而是直接在当前bash中运行了脚本
在当前bash先定义一个本地变量
hw=HelloWorld
echo ${hw}
HelloWorld
直接运行test.sh,结果如下,可见并没有输出变量的值
sh test.sh
用source关键字运行test.sh,结果如下,可见输出了变量的值
source test.sh
HelloWorld
注意事项
声明一个环境变量,然后重新对这个环境变量赋值,并不能表示它从一个环境变量变成了本地变量,如果想把它从本地变量变成环境变量,需要先unset,然后再重新声明为本地变量并赋值
export hw=HelloWorld
hw=HiWorld
echo${hw}
HiWorld
sh test.sh
HiWorld
只读变量
readonly 变量=变量值
只读变量设置后不可修改,不可unset(撤销),如果想要只读变量失效需要退出当前shell
readonly hw=HelloWorld
unset hw
-bash: unset: hw: cannot unset: readonly variable
特殊变量
$0
表示脚本名称
test.sh如下
cat test.sh
echo $0
运行test.sh
sh test.sh
test.sh
$1-9
表示传入脚本的第1-9个参数
test.sh如下
cat test.sh
echo $1,$2,$3
运行test.sh,并传入参数
sh test.sh a b c
a,b,c
$?
保存上一个命令的执行状态返回值
命令执行后,可能有两类状态返回值(0 – 255)
如果返回值为0:表示上一条命令正确执行
如果返回值为1-255中的任意一个:表示上一条命令执行错误
1到255中,1、2、127 为系统预留的错误状态码,其他状态码可自定义
$#
表示传入脚本的参数个数,参数数量
test.sh如下
cat test.sh
echo $#
运行test.sh,并传入参数
sh test.sh a
1
sh test.sh a b
2
sh test.sh a b c
3
$@
表示传入脚本的参数
test.sh如下
cat test.sh
echo $@
运行test.sh,并传入参数
sh test.sh a
a
sh test.sh a b
a b
sh test.sh a b c
a b c
${@:起点} 表示由起点开始(包括起点),取得后面的所有的位置参数
test.sh如下
cat test.sh
echo ${@:2}
运行test.sh,并传入参数,可以看出从第2个参数开始输出
sh test.sh a b c
b c
${@:起点:个数} 表示由起点开始(包括起点),取得指定个数的位置参数
test.sh如下
cat test.sh
echo ${@:2:2}
运行test.sh,并传入参数,可以看出从第2个参数开始输出,输出2个参数为止
sh test.sh a b c d
b c
$*
@ 与 @与 @与*都可以使用一个变量来来表示所有的参数内容,但这两个变量之间有一些不同之处。
只在被双引号包起来的时候
$@:将输入的每个参数作为一个字符串
$*:将输入的所有参数作为一个字符串
test.sh如下
#-----$@-----
echo $@
for i in "$@"
do
echo $i
done
#-----$*-----
echo $*
for i in "$*"
do
echo $i
done
运行test.sh,并传入参数
sh test.sh a b c
#-----$@-----
a b c
a
b
c
#-----$*-----
a b c
a b c
declare声明变量
declare 变量=变量值
选项 | 表达式 | 含义 |
---|---|---|
-i | declare -i hw=HelloWorld | 表示为声明的变量为整型 |
-x | declare -x hw=HelloWorld | 表示为声明的变量为环境变量,相当于export |
-r | declare -r hw=HelloWorld | 表示为声明一个只读变量 |
这些选项可以混合使用,比如声明一个可以被继承的”环境只读变量”
declare -rx hw=HelloWorld
算术运算
shell中,无法直接进行算术运算
a=1+2
echo a
a
a=1
b=2
echo a+b
a+b
echo ${a}+${b}
1+2
默认情况下,shell不会直接进行算术运算,而是把”算术符号”当做”字符串”与两个变量的值连接在了一起,形成了一个新的字符串
let
shell内建命令,只支持整数运算,不支持包含小数的运算
a=1
b=2
let c=a+b
echo ${c}
3
let a=1+2
echo ${a}
3
let a=5/2
echo ${a}
2
expr
与let命令相似,也只能进行整数运算,而且,使用expr命令进行算术运算时,需要注意以下两点
1、数值与运算符号之间需要用空格隔开,否则无法进行算术运算。
2、使用expr命令进行乘法运算时,需要将”乘号”转义,否则会报错。
expr 1+2
1+2
expr 1 + 2
3
expr 1 * 2
expr: syntax error
expr 1 \* 2
2
如果想要使用经过计算过的值,可以使用‘命令引用’
a=1
b=2
expr ${a} + ${b}
3
c=`expr ${a} + ${b}`
echo ${c}
3
bc
是linux下最常用的”计算器”,支持小数运算
bc支持运算有以下几种:
- **+ - * / % 😗*加,减,乘,除,取余
- a^b : 取a的b方
- **&& || < <= > >= == != 😗*条件判断,为真返回1,否则返回0
bc支持的函数有以下几种:
- **sqrt(num)😗*获取num的平方根
- **length(num)😗*获取num数值的长度,比如length(10)=2
- **read:**获取输入的数据
- **scale:**设置小数有效位
- **ibase:**设置输入进制格式
- **obase:**设置输出进制格式
运算语法 $[算术表达式]
echo $[1+2]
3
a=1
b=2
echo $[a+b]
3
echo $[a-b]
-1
运算语法 $((算术表达式))
echo $((1+2))
3
a=1
b=2
echo $((a+b))
3
echo $((a-b))
-1
将变量声明为整形
declare -i s
s=1+2
echo ${s}
3
逻辑运算
与
-a或&&
当使用”&&”或者”-a”作为条件判断的运算符时,”-a”只能用”单大括号”括起,”&&”只能用”双大括号”括起
a=1
b=2
if [ ${a} -eq 1 -a ${b} -eq 2 ];then echo "true";fi
true
if [[ ${a} -eq 1 && ${b} -eq 2 ]];then echo "true";fi
true
”&&”具有短路功能:当”&&”之前的命令执行成功时,则执行”&&”之后的命令,当”&&”之前的命令执行失败时,”&&”之后的命令则不会被执行
a=1
[ ${a} -eq 1 ] && echo "true"
true
[ ${a} -eq 2 ] && echo "true"
或
-o或||
当使用”||”或者”-o”作为条件判断的运算符时,”-o”只能用”单大括号”括起,”||”只能用”双大括号”括起
a=1
b=2
if [ ${a} -eq 1 -o ${b} -eq 1 ];then echo "true";fi
true
if [[ ${a} -eq 1 || ${b} -eq 1 ]];then echo "true";fi
true
”||”具有短路功能:当”||”之前的命令执行失败时,则执行”||”之后的命令,当”||”之前的命令执行成功时,”||”之后的命令则不会被执行
a=1
[ ${a} -eq 1 ] || echo "true"
[ ${a} -eq 2 ] || echo "true"
true
非
!
a=1
if [ ! ${a} -eq 1 ];then echo "true";fi
if [ ! ${a} -eq 2 ];then echo "true";fi
true
与或结合
cmd1 && cmd2 || cmd3
上述语法表示,表示如果cmd1执行成功,则执行cmd2,如果cmd1执行失败,则不执行cmd2,而是执行cmd3
分析如下:
- cmd1执行成功时,则cmd2必须执行,如果cmd2执行成功,(cmd1 && cmd2)整体结果为真,则不用执行cmd3
- cmd1执行失败时,则cmd2不用执行,(cmd1 && cmd2)整体结果为假,则cmd3必须执行
组合命令
使用小括号”( )” 或大括号”{ }”将命令组合在一起
ls dir1 | wc -l
1
ls dir2 | wc -l
2
(ls dir1;ls dir2) | wc -l
3
{ ls dir1; ls dir2; } | wc -l
3
二者区别如下:
- 大括号内的所有命令都用空格隔开
- 大括号内的每个命令都必须以分号”;”结尾,即使是大括号内的最后一个命令,也需要以分号结尾,而且需要用空格与大括号隔开