@TOC
变量使用
说明
- 变量的定义与使用规则:
1)变量名首字符必须为字母,名字只能用字母、数字、下滑线,不要用bash关键字。非法的名字:8var、var-8
2)变量定义或赋值时,变量名与值之间用等号连接:变量名=值,等号两边不能有空格,值中有空格或特殊字符需要用双引号或单引号引起来。
3)使用 $变量名 或 ${变量名} 形式获取变量值 - sh -x sh2.sh
选项参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 script 前,先将 scripts 的内容输出到屏幕上;
-x:实现shell脚本逐条语句的跟踪。这样我们可以分步骤进行查看每步的输出结果
- 变量定义中符号的使用
1)单引号 ' ' :单引号里面的所有字符都是普通字符。
2)双引号 " ":双引号会保留变量特性,用值替换。
3)反引号:位于Esc 键下方,用倒引号括起一个命令时,这个命令将会被执行,执行后的结果作为这个表达式的值。
单引号和双引号用于变量值出现空格时,比如 name=zhang san,这样执行就会出现问题,而必须用引号括起来,比如 name="zhang san"。
不过,引号有单引号和双引号之分,二者的主要区别在于,被单引号括起来的字符都是普通字符,就算特殊字符也不再有特殊含义;而被双引号括起来的字符中,"$"、"\"和反引号是拥有特殊含义的,"$"代表引用变量的值,而反引号代表引用命令。
如果需要调用命令的输出,或把命令的输出赋予变量,则命令必须使用反引号包含,这条命令才会执行,反引号的作用和 $(命令) 是一样的,但是反引号非常容易和单引号搞混,所以推荐大家使用 $(命令) 的方式引用命令的输出。
测试变量:
[root@linux01 sh]# vim sh2.sh
1 #!/bin/bash
2 now=$(date)
3 echo ${now}
4 msg1="当前时间,${now}"
5 echo ${msg1}
6 msg2='当前时间,${now}'
7 echo $msg2
[root@linux01 sh]# sh sh2.sh
2020年 05月 10日 星期日 19:48:17 CST
当前时间,2020年 05月 10日 星期日 19:48:17 CST
当前时间,${now}
4.转义符的使用
[root@linux01 sh]# msg='hello'
[root@linux01 sh]# echo ${msg}
hello
[root@linux01 sh]# echo \$msg
$msg
[root@linux01 sh]# echo \${msg}
${msg}
位置变量使用
shell语法中,当调用shell脚本的时候,可以通过脚本后面的位置进行参数传递,然后通过各种不同的位置变量接收
|语法 |说明 |
|--|--|
| $0 | 脚本名 |
| $n | n为从1开始的数字,表示脚本的第几个参数 |
|$# | 位置参数的个数 |
| $* | 所有位置参数作为单个字符串表示:"$1 $2 $3 $4",默认分隔符为空格 |
| $@ | 所有的位置参数,每个都作为独立的字符串表示:"$1" "$2" "$3" "$4"|
| $? | 上一个命令的返回值,一般情况下成功执行则$?的值为0,否则为其他非零值 |
| $$ | 脚本的进程ID(PID) |
[root@linux01 sh]# vim sh3.sh
1 #!/bin/bash
2 echo "脚本的进程ID:$$"
3 echo "脚本名称:$0"
4 echo "本次一共传递了$#个参数"
5 echo "第一个参数是:$1"
6 echo "第二个参数是:$2"
7 echo "所有参数作为一个字符串接收:$*"
8 echo "所有参数作为一个数组接收:$@"
9 echo "验证:"
10 echo '$* 的演示'
11 for i in "$*";
12 do
13 echo $i
14 done;
15 echo '$@ 的演示'
16 for i in "$@";
17 do
18 echo $i
19 done;
20 echo "脚本执行状态:$?"
[root@linux01 sh]# sh sh3.sh 1 2 3
脚本的进程ID:4530
脚本名称:sh3.sh
本次一共传递了3个参数
第一个参数是:1
第二个参数是:2
所有参数作为一个字符串接收:1 2 3
所有参数作为一个数组接收:1 2 3
验证:
$* 的演示
1 2 3
$@ 的演示
1
2
3
脚本执行状态:0
数组的使用
数组的定义
常量列表的方式:
#用空格分隔
arr1=("a" "ab" "bc")
直接下标引用
arr2[0]=1
arr2[1]=3
arr2[2]=4
declare 命令定义数组
declare用于声明变量的属性,-a 表示声明数组
#定义数据arr3,并初始化元素
declare -a arr3=('a' 'b')
#先定义,后给元素赋值
declare -a arr3
arr3[0]="a"
arr3[1]="b"
数组的使用
**获取数组长度:**用$可以得到数组长度
${#arr[*]} 或 ${#arr[@]}
读取数组元素:
读取下标为1的元素:${arr[i]}
读取整个数组:${arr[*]}
给数组元素赋值:
arr[1]=1
删除数组元素:
删除后,数组长度改变:unset arr[1]
数组切片:
${数组名[@或*]:起始位置:长度
切片原先数组,返回是字符串,中间用“空格”分开。
如果加上”()”,将得到切片数组
[root@linux01 sh]# vim sh4.sh
1 #!/bin/bash
2 # 定义一个数组
3 arr1=("张三" "李四" "王五");
4 # 打印数组长度
5 echo "数组长度是:${#arr1[*]}";
6 # 遍历数组
7 for i in ${arr1[*]};
8 do
9 echo $i
10 done;
11 # 添加新元素
12 arr1[3]='赵六'
13 # 打印新元素
14 echo ${arr1[3]}
15 # 删除元素
16 unset arr1[0]
17
18 # 打印一下
19 echo "删除元素后:${arr1[*]}"
20 echo "数组长度:${#arr1[*]}"
21 # 数组切片
22 echo ${arr1[*]:2:1}
23 str=${arr1[*]:2:1}
24 # 输出切片
25 echo "切片数组:${str[*]}"
26
"sh4.sh" 27L, 469C 已写入
[root@linux01 sh]# sh sh4.sh
数组长度是:3
张三
李四
王五
赵六
删除元素后:李四 王五 赵六
数组长度:3
王五
切片数组:王五
运算符的使用
算数运算符
其中:
expr 方式:expr 的表达式要用反引号括起来,并且要用空格分隔
示例:
加法:
[root@linux01 sh]# a=6;b=3
[root@linux01 sh]# echo $a;echo $b
6
3
[root@linux01 sh]# echo $((a+b))
9
[root@linux01 sh]# echo $((a + b))
9
[root@linux01 sh]# echo $[a+b]
9
[root@linux01 sh]# echo $[a-b]
3
[root@linux01 sh]# echo $[$a + $b]
9
[root@linux01 sh]# echo $[$a+$b]
9
[root@linux01 sh]# echo `expr $a + $b`
9
[root@linux01 sh]# expr $a + $b
9
[root@linux01 sh]# `expr $a + $b`
-bash: 9: 未找到命令
[root@linux01 sh]# expr $a +$b
expr: 语法错误
[root@linux01 sh]# expr $a+$b
6+3
乘法:
[root@linux01 sh]# echo $((a*b))
18
[root@linux01 sh]# echo $[a*b]
18
[root@linux01 sh]# echo $[a * b]
18
[root@linux01 sh]# expr $a * $b
expr: 语法错误
[root@linux01 sh]# expr $a \* $b
18
自增:
[root@linux01 sh]# a=10
[root@linux01 sh]# echo $((a++))
10
[root@linux01 sh]# echo $a
11
[root@linux01 sh]# $((a++))
-bash: 11: 未找到命令
[root@linux01 sh]# ((a++))
[root@linux01 sh]# echo $a
13
幂运算:
[root@linux01 sh]# x=2;y=3
[root@linux01 sh]# echo $((x**y))
8
[root@linux01 sh]# echo $((2**3))
8
比较运算符
数字比较:
一般-eq
这种,用[]
== > <
这种, 用[[]]
示例:
[root@linux01 sh]# a=3
[root@linux01 sh]# test $a -eq 3 && echo 'ok'
ok
[root@linux01 sh]# test $a == 3 && echo 'ok'
ok
[root@linux01 sh]# [ $a -eq 3 ] && echo 'ok'
ok
[root@linux01 sh]# [ $a -eq 3] && echo 'ok'
-bash: [: 缺少 `]
[root@linux01 sh]# [ $a == 3 ] && echo 'ok'
ok
[root@linux01 sh]# [ $a < 4 ] && echo 'ok'
-bash: 4: 没有那个文件或目录
[root@linux01 sh]# [ $a -lt 4 ] && echo 'ok'
ok
[root@linux01 sh]# [[ $a < 4 ]] && echo 'ok'
ok
字符串比较:
示例:
[root@linux01 sh]# str=xxx
[root@linux01 sh]# test $str == xxx && echo 'ok'
ok
[root@linux01 sh]# [ $str == 'xxx' ] && echo 'ok'
ok
[root@linux01 sh]# [[ $str == 'xxx' ]] && echo 'ok'
ok
[root@linux01 sh]# test $str == 'xxx' && echo 'ok'
ok
[root@linux01 sh]# test $str != 'xxx' && echo 'ok'
[root@linux01 sh]# test $str != 'xxux' && echo 'ok'
ok
[root@linux01 sh]# str=""
[root@linux01 sh]# [ -z $str ] && echo 'ok'
ok
[root@linux01 sh]# [ "${str}x" == x ] && echo 'ok' #判空的另一种方案
ok
[root@linux01 sh]# [ ! "${str}x" == x ] && echo 'ok' #判空的另一种方案
[root@linux01 sh]# [ -n $str ] && echo 'ok'
ok
[root@linux01 sh]# # -n不怎么靠谱
[root@linux01 sh]# # 用[ ! ${str}x == x ] 判断非空
[root@linux01 sh]# [ -n "" ] && echo 'ok
Q.E.D.