一.Shell的变量
1.什么是变量
shell变量的名称以一个字母或下划线符号开始,后面可以接任意长度的字母,下划线或数字。和许多其他程序设计语言不同的是,shell变量名称字符并没有长度的限制。
变量赋值的方式为:变量名称=值
其中=号两边不要有任何空格。当你想使用变量名称来获取值时,在变量名称前面加上$符号。当赋值的内容包含空格时,请加引号。
例如:
[root@server scripts]# with_space="this contains space"
[root@server scripts]# echo $with_space #注意$with_space事实上只是${with_space}的简写形式。在某些上下文中,$with_space可能会引起错误,这时候就需要用${with_space}了。
this contains space
变量赋值可以使用=(比如var=27),也可以在read命令后面或利用特殊变量在循环头进行赋值,例如:for var2 in 1 2 3。
2.变量的分类
shell的变量类型有两种:局部变量(普通变量)和全局变量(环境变量是全局变量)
局部变量:对于函数而言,顾名思义,局部变量的可见范围是代码块或函数中。这一点与大部分编程语言是相同的。但是,局部变量必须明确以local声明,否则即使在代码块中,它也是全局可见的。对于shell而言,局部变量也可称为普通变量,只能在创建他们的Shell函数或Shell脚本中使用。普通变量一般是由开发者用户开发脚本程序时创建的。
全局变量:对于函数而言,全局变量在全局范围内可见,在声明全局变量时,不需要加任何修饰词。环境变量是全局变量的一种。对于shell而言,全局变量也可称为环境变量,可以在创建他们的Shell及其派生出来的任意子进程shell中使用,环境变量又可分为自定义环境变量和Bash内置的环境变量
特殊变量
3.局部变量
普通变量在用户当前的Shell生存期的脚本中使用。例如,普通变量a取值为1,这个值在用户当前Shell生存期中有意义。如果在Shell中启动另一个进程或退出,普通变量值将无效。
定义普通变量实践
[root@server scripts]# a=hello #定义变量时,不用引号
[root@server scripts]# b='hello' #定义变量时,使用单引号
[root@server scripts]# c="hello" #定义变量时,使用双引号
[root@server scripts]# echo $a #使用$a输出变量
hello
[root@server scripts]# echo ${a} #使用${a}输出变量
hello
[root@server scripts]# echo $b
hello
[root@server scripts]# echo ${b}
hello
[root@server scripts]# echo $c
hello
[root@server scripts]# echo ${c}
hello
提示:$变量名表示输出变量,可以用$c和${c}两种用法。
小结:连续普通字符串内容赋值给变量,不管用什么引号或者不用引号,它的内容是什么,打印变量就输出什么。
4.全局变量
例如这样的一个例子
[root@server scripts]# vim variable.sh
#!/bin/bash
#测试全局变量和局部变量的使用范围
num=123
func1()
{
num=321 #在代码块中声明的变量,全局变量
echo $num
}
func2()
{
local num=456 #声明局部变量
echo $num
}
echo $num #显示初始时的num变量
func1 #调用func1,在函数体中声明变量
echo $num #测试num变量是否改变
func2 #调用func2,显示声明局部变量
echo $num #测试num变量是否被改变
查看该例子的运行结果
[root@server scripts]# sh variable.sh
123 #初始值
321 #fun1内被改变
321 #func1内的赋值影响到函数体外
456 #func2内声明局部变量
321 #函数体外的num未改变
5.特殊变量
特殊变量 | 作用说明 |
$0 | 如果是:利用bash和sh执行脚本。则输入什么就输出什么; 如果是:利用./或者是绝对路径执行脚本。则输入什么就输出什么; 如果是:利用source或. 执行脚本。则输出-bash。 |
$n(n>0) | 获取当前执行的shell脚本的第n个参数值,n=1..9,如果n大于9用大括号括起来{10},参数以空格隔开。 |
$# | 获取当前执行的shell脚本后面接的参数的总个数 |
$? | 上一个命令的执行结果(返回值)。0表示执行正确,1表示执行失败。2表示没有找到文件。这个变量最常用 |
$$ | 获取当前shell的进程号 |
$* | 获取当前shell的所有传参的参数,不加引号同$@;如果给$*加上双引号,例如: “$*”,则表示将所有的参数视为单个字符串,相当于“12$3”。 |
$@ | 获取当前shell的所有传参的参数,不加引号同$*;如果给$@加上双引号,例如: “$@”,则表示将所有参数视为不同的独立字符串,相当于“$1” “$2” “$3” “……”,这是将参数传递给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。 |
当“$*”和“$@”都加双引号时,两者有区别,都不加双引号时,两者无区别。
$0参数实践
$n(n>0)参数实践
$#参数实践
$?参数实践
$$参数实践
$*参数实践
$@参数实践
6.变量中引号的使用
只有在变量的值中有空格的时候,会使用引号。
单引号与双引号的区别在于,是否能够解析特殊符号。
[root@server scripts]# a=hello
[root@server scripts]# a=$a-world #定义变量时,不用引号
[root@server scripts]# b='$a-world' #定义变量时,使用单引号
[root@server scripts]# c="$a-world" #定义变量时,使用双引号
[root@server scripts]# echo $a
hello-world
[root@server scripts]# echo $b
$a-world
[root@server scripts]# echo $c
hello-world-world
小结:对于不是连续普通字符串内容赋值给变量。不使用引号,使用单引号,使用双引号的输出结果有所差异。
- 被一对双引号(" ")括起来的变量替换是不会被阻止的。所以双引号被称为部分引用,有时候又被称为“弱引用”。
- 但是如果使用单引号的话,变量替换就会被禁止了,变量名只会被解释成字面的意思,不会发生变量替换。所以单引号被称为“全引用”,有时候页被称为“强引用”。
- 不加引号与加双引号的效果相同。
注意:建议没有特别要求时,字符串都加双引号,需要原样输出就加单引号
7.普通变量的要求
1) 内容是纯数字、简单的连续字符(内容中不带任何空格)时,定义时可以不加任何引号,例如:
a. age=22
b. name=dog
2) 没有特殊情况时,字符串一律用双引号定义赋值,特别是多个字符串中间有空格时,例如:
a. with_space="This contains space"
3) 当变量里的内容需要原样输出时,要用单引号(M),这样的需求极少,例如:
a. name='cat'
变量使用反引号赋值
[root@server scripts]# time=`date`
[root@server scripts]# echo $time
Wed Dec 26 04:41:31 EST 2018
变量使用$()赋值(同变量使用反引号赋值)
[root@server scripts]# time=$(date)
[root@server scripts]# echo $time
Wed Dec 26 04:54:12 EST 2018
使用${}
打印变量的时候防止出现“金庸新著”的问题
[root@server scripts]# time=`date`
[root@server scripts]# echo $time_day #因为下划线是变量的组成成分,所以,这里写的time_day是一个新的变量,而之前没有定义过time_day这个变量,所以没有输出结果。[root@server scripts]# echo ${time}_day
Wed Dec 26 04:45:48 EST 2018_day
[root@server scripts]# echo $time-day
Wed Dec 26 04:45:48 EST 2018-day
二.用echo命令输出变量
1.echo命令的作用
echo命令的任务就是输出一行文本,多用于提示用户或产生数据。
2.echo命令的语法
echo命令的语法:echo [options] [CONTENT]...
echo命令的主要选项:-n不输出行尾的换行符
echo命令的行为模式:echo将各个参数打印到标准输出。参数间以一个空格隔开,在输出结束后,换行。它会解释每个字符串里的转义序列。转义序列可以用来表示特殊字符,以及控制其行为模式。
echo命令的警告:echo命令的-n选项并不被所有Linux版本支持。
3.echo参数说明
参数 | 参数说明 |
-n | 不要追加换行 |
-e | 启用下列反斜杠的转义 |
-E | 显式地抑制对于反斜杠转义的解释 |
4.echo转义字符说明
转义字符可以表示程序中难以看得见或者难以输入的特殊字符。当echo遇到转义序列时,就会打印相应的字符。echo支持的转义字符如下表。
序列 | 描述 |
\a | 报警符,ASCII的BEL字符 |
\b | 退格符(Backspace) |
\c | 禁止尾随,这个字符后面的所有字符(包括换行符,都会被忽略掉,不打印) |
\f | 换页符(清除屏幕) |
\n | 换行符(Newline) |
\r | 回车符(Carriage return) |
\t | 水平制表符(Horiziontal tab):默认空三个空格 |
\v | 垂直制表符(Vertical tab) |
\\ | 反斜线 |
三.定义变量的方式
1.定义变量的三种方式
1.直接赋值
2.传参 (传递参数)
3.交互式设置变量,使用read命令
2.read命令的说明
<1>交互式:只能命令行中使用
[root@server scripts]# read
hello,world
[root@server scripts]# echo $REPLY #打印没有给定变量名称的变量
hello,world
[root@server scripts]# read num
123
[root@server scripts]# echo $num
123
[root@server scripts]# echo $REPLY
hello,world
<2>非交互式:既可以在命令行中使用,也可以在脚本中使用
在命令行中的使用
###让执行命令后出现提示信息###
-p 为显示提示信息。p作为输出,一般写在其他参数的最后面
[root@server scripts]# read -p "请输入一个整数:" a
请输入一个整数:2
[root@server scripts]# echo $a
2###限制读取字符的个数###
使用-n选项给出限制字符的个数,读取n个字符就会自动结束读取,如果没有读满n个字符就按回车或遇到换行符,也会结束读取
-n 5限制字符个数最多为5个
[root@server scripts]# read -n 5 -p "请输入密码:" a
请输入密码:12345[root@server scripts]# echo $a
12345###设置等待时间###
-t 5 等待5秒
[root@server scripts]# read -t 5 -p "请输入密码:" a
请输入密码:123
[root@server scripts]# echo $a
123###不显示输入的内容###
-s 输入的时候不显示输入内容。
[root@server scripts]# read -s -t 5 -p "请输入密码:" a
请输入密码:[root@server scripts]#
[root@server scripts]# echo $a
123###read 可以同时读入多个字符###
注意 : 同时传入两个参数的时候,参数之间要使用空格分割。
[root@server scripts]# read -p "请输入两个整数:" a b
请输入两个整数:2 3
[root@server scripts]# echo $a $b
2 3
在脚本中的使用(同在命令行中的使用,这里只拿其中一部分举例)
四.变量的数值计算
1.仅支持整数的运算的命令
<1>expr命令(没有幂次方的运算)
[root@server scripts]# a=25
[root@server scripts]# b=10
[root@server scripts]# expr $a+$b #这种表达方法是错误的
25+10
[root@server scripts]# expr $a + $b #表达式的数字和表达式的符号之间必须有空格
35
[root@server scripts]# expr $a - $b
15
[root@server scripts]# expr $a * $b
expr: syntax error
[root@server scripts]# expr $a \* $b #乘法需要转义
250
[root@server scripts]# expr $a / $b
2
[root@server scripts]# expr $a % $b
5[root@server scripts]# expr $a ** $b #expr命令不支持幂次方的运算
expr: syntax error
[root@server scripts]# expr $a \** $b
expr: syntax error
[root@server scripts]# expr $a \*\* $b
expr: syntax error
<2>echo命令:echo $((数学运算表达式))或者echo $[数学运算表达式]
###使用echo $((数学表达式))###
[root@server scripts]# a=25
[root@server scripts]# b=10
[root@server scripts]# echo $((a+b))
35
[root@server scripts]# echo $((a-b))
15
[root@server scripts]# echo $((a*b))
250
[root@server scripts]# echo $((a/b))
2
[root@server scripts]# echo $((a%b))
5[root@server scripts]# echo $((a**b)) #echo命令支持幂次方的运算
95367431640625
###使用echo $[数学表达式]###
[root@server scripts]# a=25
[root@server scripts]# b=10
[root@server scripts]# echo $[a+b]
35
[root@server scripts]# echo $[a-b]
15
[root@server scripts]# echo $[a*b]
250
[root@server scripts]# echo $[a/b]
2
[root@server scripts]# echo $[a%b]
5[root@server scripts]# echo $[a**b] #echo命令支持幂次方的运算
95367431640625
<3>let命令
###let命令的加,减,乘,除,取余运算###
[root@server scripts]# a=25
[root@server scripts]# b=10
[root@server scripts]# let c=a+b
[root@server scripts]# echo $c
35
[root@server scripts]# let c=a-b
[root@server scripts]# echo $c
15
[root@server scripts]# let c=a*b
[root@server scripts]# echo $c
250
[root@server scripts]# let c=a/b
[root@server scripts]# echo $c
2
[root@server scripts]# let c=a%b
[root@server scripts]# echo $c
5[root@server scripts]# let c=a**b #let命令支持幂次方运算
[root@server scripts]# echo $c
95367431640625###let命令的“+=”,“-=”,“*=”,“/=”,“%=”运算###
[root@server scripts]# a=25
[root@server scripts]# let a+=10
[root@server scripts]# echo $a
35
[root@server scripts]# let a-=10
[root@server scripts]# echo $a
25
[root@server scripts]# let a*=10
[root@server scripts]# echo $a
250
[root@server scripts]# let a/=10
[root@server scripts]# echo $a
25
[root@server scripts]# let a%=10
[root@server scripts]# echo $a
5[root@server scripts]# let a**=b #let命令这种运算规则是不支持幂次方运算的
-bash: let: a**=b: syntax error: operand expected (error token is "=b")
[root@server scripts]# let a\**=b
-bash: let: a**=b: syntax error: operand expected (error token is "=b")
[root@server scripts]# let a\*\*=b
-bash: let: a**=b: syntax error: operand expected (error token is "=b")
2.可以进行小数运算的命令
bc命令
安装bc,依赖于yum源
###交互模式下使用bc命令###
<1>
[root@server scripts]# bc
bc 1.06.95 #首先输出bc的版本信息,可以使用-q选项不输出头部信息
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
6.66+8.8889
15.5489quit #使用quit命令退出
<2>使用-q选项
[root@server scripts]# bc -q #利用-q选项不输出头部信息
2**3
(standard_in) 1: syntax error #bc命令支持的幂次方符号为^,而不是**。
2^3
8
quit #使用quit命令退出
###非交互模式下使用bc命令###
<1>
[root@server scripts]# echo 6.66+8.8889 | bc
15.5489<2>使用sacle来限制位数:
比如:
[root@server scripts]# echo 'scale=6;1/3' | bc
.333333[root@server scripts]# echo 'scale=2;5.55*4.466' | bc
24.786
五.运算相关练习题
实现一个两个整数的加减乘除,取余,幂此方等功能的计算器
方法一:echo命令
实现脚本
脚本执行结果
方法二:expr命令
实现脚本:这里注意到:expr命令不支持幂次方的运算
脚本运行结果
方法三:bc命令
实现脚本:这里注意到:bc命令的幂次方运算符为"^",而不是"**"
脚本运行结果