什么是变量?
变量最初来源于数学,指的是非固定的值可变化的数通常用拉丁字母表示。在计算机中变量它依旧指的是可变化的数,只不过表现形式有些变化。它指的是变量名+所指向的内存空间。
变量的特点
变量分强类型变量,与弱类型变量
强类型变量:变量需事先声明且需提前定义其变量存储格式
弱类型变量:不需事先声明,不需定义变量存储格式。
bash把所有变量统统视作字符型;bash中的变量无需事先声明,相当于,把声明和赋值过程同时实现。
变量名的命名规范:
变量名只能包含数字,字母和下划线,而且不能以数字开头。
其命名要求见名知义,命名机制遵循某种法则(驼峰法则);不能使用程序的保留字:if,else,then,while,for...
bash的变量类型及其使用格式
本地变量,环境变量,局部变量,位置参数变量,特殊变量
变量引用格式:$VAR、${VAR}
………………………………………………………………………………………………………………………
本地变量:作用域仅为当前shell进程
变量赋值:name=‘value’
value有如下引用类型
1、直接字符串引用,格式:name="CHARS"
1 2 3 |
|
2、变量引用,格式:name=“$VAR”
1 2 3 |
|
3、命令引用,格式:name=`COMMAND` | name=$(COMMAND)
1 2 3 4 5 6 |
|
“”:弱引用,其中的变量引用会被替换为变量值;
1 2 3 |
|
‘’:强引用,其中的变量引用不会被替换为变量值,而保持原字符串;
1 2 3 |
|
命令set用于显示已定义的所有变量
撤销已定义的变量,格式:unset 变量名
1 2 3 4 5 |
|
注:在刚接触bash变量时特别容易搞错的就是变量的使用格式,有时候该命令引用却忘记加``或$(),还有就是强引用与弱引用的使用时机。
下面以例子说明本地变量的作用范围,使用命令bash进入子shell
1 2 3 4 5 6 7 |
|
由实验可知,作用域仅为当前shell进程。当然上面实验做的不够完善,因为并没有演示在符父shell中其变量是否有效,大家可以在下面补充实验去验证。
………………………………………………………………………………………………………………………
环境变量:作用域为当前shell进程及子进程
变量赋值:
有四种赋值格式:
1、export name=value
2、name=value
export name
3、declare -x name=value
4、name=value
declare -x name
注:bash内嵌了许多环境变量(通常全为大写字符),用于定义bash的工作环境
查看/显示环境变量 命令
export
1 2 3 4 5 6 |
|
declare -x
1 2 3 4 5 6 |
|
printenv
1 2 3 4 5 6 |
|
env
1 2 3 4 5 6 |
|
上面四个命令虽然显示顺序略有不同但是所包含的内容都是一样的
1 2 3 4 5 6 7 8 |
|
撤销环境变量
格式:unset VAR
下面通过例子验证环境变量的作用范围
1 2 3 4 5 6 |
|
………………………………………………………………………………………………………………………
局部变量:作用域仅为某代码片段(通常用在函数)
因为函数还没学到,这里不举例子
………………………………………………………………………………………………………………………
位置变量:当执行脚本的shell进程传递的参数
$1,$2,...$(10)...:对应调用第1,第2...第10个参数
………………………………………………………………………………………………………………………
特殊变量:shell内置的特殊功用的变量
$#:传递给脚本参数的个数
$*:传递给脚本的所有参数;各参数读成多个独立字符串
$@:传递给脚本的所有参数;各参数读成一个完整的字符串形式
$?:程序执行状态返回值,0表示正确,1-255表示失败
$0:表示命令本身
算术运算
Linux中的运算符主要有单目运算符和双目运算符,运算符也有优先级的高低之分。
运算符主要有以下这些:
优先级 | 运算符 | 类型 | 说明 |
---|---|---|---|
13 | +、- | 单目 | 单目正、单目负。它们是单目运算符的正、负,而不是加、减。 |
12 | !、~ | 单目 | 逻辑非、按位取反或补码。 |
11 | *、/、% | 双目 | 乘、除、取模。 |
10 | +、- | 双目 | 加、减。 |
9 | <<、>> | 双目 | 按位左移、按位右移。 |
8 | <、<=、>、>= | 双目 | 小于、小于等于、大于、大于等于。 |
7 | ==、!= | 双目 | 等于、不等于。 |
6 | & | 双目 | 按位与。 |
5 | ^ | 双目 | 按位异或。 |
4 | | | 双目 | 按位或。 |
3 | && | 双目 | 逻辑与。 |
2 | || | 双目 | 逻辑或。 |
1 | =、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>= | 双目 | 赋值、运算且赋值。 |
说明:对于该表,数值越大,优先级越高。故赋值运算符的优先级最低。
注意: 小括号内的表达式的优先级最高,会优先运算。因此,可以用小括号改变运算符的优先级。
优先级越高,会先进行运算;相同优先级的运算符,按照先后顺序顺序运算。
--------------------- 本文来自 lamp_yang_3533 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/lamp_yang_3533/article/details/70041211?utm_source=copy
在未学习bash中的算术运算之前如果要计算从1+...+10需要使用管道将其送入bc计算器来解决,
echo {1..10} | tr ' ' '+'| bc很麻烦。而使用bash中的算术运算则可以简化代码。
bash中的算术运算格式:有很多种,本文只介绍常用的4种
1)let VAR=算术运算表达式
1 2 3 |
|
2)VAR=$[算术表达式]
1 2 3 |
|
3)VAR=$((算术表达式))
1 2 3 |
|
4)VAR=$(expr $ARG $OP $ARG2)
1 2 3 4 5 6 |
|
这种是调用expr命令计算后面运算表达式,它要求数值与运算符之间有空格,没有空格则不进行计算,保持运算表达式原本模样赋值给变量。
注:它与上述三种不同之处还有如果有乘法运算,乘法符号*在第四种里面需要加\进行转义。
以下为四种算术运算在乘法中的表现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
第四种需要转义,其他三种不需要。
逻辑运算符
逻辑卷标 | 表示意思 |
1. | 关于档案与目录的侦测逻辑卷标! |
-f | 常用!侦测『档案』是否存在 eg: if [ -f filename ] |
-d | 常用!侦测『目录』是否存在 |
-b | 侦测是否为一个『 block 档案』 |
-c | 侦测是否为一个『 character 档案』 |
-S | 侦测是否为一个『 socket 标签档案』 |
-L | 侦测是否为一个『 symbolic link 的档案』 |
-e | 侦测『某个东西』是否存在! |
2. | 关于程序的逻辑卷标! |
-G | 侦测是否由 GID 所执行的程序所拥有 |
-O | 侦测是否由 UID 所执行的程序所拥有 |
-p | 侦测是否为程序间传送信息的 name pipe 或是 FIFO (老实说,这个不太懂!) |
3. | 关于档案的属性侦测! |
-r | 侦测是否为可读的属性 |
-w | 侦测是否为可以写入的属性 |
-x | 侦测是否为可执行的属性 |
-s | 侦测是否为『非空白档案』 |
-u | 侦测是否具有『 SUID 』的属性 |
-g | 侦测是否具有『 SGID 』的属性 |
-k | 侦测是否具有『 sticky bit 』的属性 |
4. | 两个档案之间的判断与比较 ;例如[ test file1 -nt file2 ] |
-nt | 第一个档案比第二个档案新 |
-ot | 第一个档案比第二个档案旧 |
-ef | 第一个档案与第二个档案为同一个档案( link 之类的档案) |
5. | 逻辑的『和(and)』『或(or)』 |
&& | 逻辑的 AND 的意思 |
|| | 逻辑的 OR 的意思 |
逻辑表达式
- test 命令
使用方法:test EXPRESSION
如:
[root@localhost ~]# test 1 = 1 && echo 'ok'
ok[root@localhost ~]# test -d /etc/ && echo 'ok'
ok[root@localhost ~]# test 1 -eq 1 && echo 'ok'
ok
[root@localhost ~]# if test 1 = 1 ; then echo 'ok'; fi
ok
注意:所有字符 与逻辑运算符直接用“空格”分开,不能连到一起。
- 精简表达式
- [] 表达式
[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok'
ok[root@localhost ~]# [ 2 < 1 ] && echo 'ok'
-bash: 2: No such file or directory
[root@localhost ~]# [ 2 \< 1 ] && echo 'ok'
[root@localhost ~]# [ 2 -gt 1 -a 3 -lt 4 ] && echo 'ok'
ok
[root@localhost ~]# [ 2 -gt 1 && 3 -lt 4 ] && echo 'ok'
-bash: [: missing `]'注意:在[] 表达式中,常见的>,<需要加转义字符,表示字符串大小比较,以acill码 位置作为比较。 不直接支持<>运算符,还有逻辑运算符|| && 它需要用-a[and] –o[or]表示
[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok'
- [[]] 表达式
ok[root@localhost ~]$ [[ 2 < 3 ]] && echo 'ok'
[root@localhost ~]$ [[ 2 < 3 && 4 > 5 ]] && echo 'ok'
ok
ok
注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符:|| &&
三、性能比较
bash的条件表达式中有三个几乎等效的符号和命令:test,[]和[[]]。通常,大家习惯用if [];then这样的形式。而[[]]的出现,根据ABS所说,是为了兼容><之类的运算符。以下是比较它们性能,发现[[]]是最快的。
$ time (for m in {1..100000}; do test -d .;done;)
real 0m0.658s
user 0m0.558s
sys 0m0.100s
$ time (for m in {1..100000}; do [ -d . ];done;)
real 0m0.609s
user 0m0.524s
sys 0m0.085s
$ time (for m in {1..100000}; do [[ -d . ]];done;)
real 0m0.311s
user 0m0.275s
sys 0m0.036s
不考虑对低版本bash和对sh的兼容的情况下,用[[]]是兼容性强,而且性能比较快,在做条件运算时候,可以使用该运算符。