RHCE8 资料整理(五-2)

RHCE8 资料整理

    • 第 22 章 用bash写脚本
      • 22.1 通配符
      • 22.2 变量
        • 22.2.1 本地变量
        • 22.2.2 环境变量
        • 22.2.3 位置变量和预定义变量
      • 22.3 返回值
      • 22.4 数值运算
      • 22.5 比较、对比和判断
      • 22.6 if判断语句
      • 22.7 for循环语句
      • 22.8 while循环语句

第 22 章 用bash写脚本

22.1 通配符

详细参考 https://blog.csdn.net/u010230019/article/details/132038691

通配符一般在shell语言中,常见元字符如下:

  1. []:匹配一个字符,匹配的是出现在中括号中的字符
  2. [abc]:匹配abc其中任意个字符
  3. [a-z]:匹配a到z中的任意个子符
  4. [0-9:匹配一个数字
  5. [a\-z]:这里的\表示转义,匹配a,-,z其中任意一个字符
  6. [^a-z]:除了a-z之外的字符
  7. ?:表示任意一个字符,这里是个,但不能匹配隐藏文件的点(.
  8. *:表示任意多个字符,可以是0个,也可以是1个或者多个,但不能匹配隐藏文件的点(.

例如:

[root@node-138 ~]# ll|grep no[h]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[hdf]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[a-z]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[0-9]up.out
[root@node-138 ~]# ll|grep no[0\h9]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[!h-z]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[^h-z]up.out
[root@node-138 ~]# ll|grep no[^h]up.out
[root@node-138 ~]# ll|grep no?up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no*up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[d-i]up.out
-rw-------. 1 root root      1186 Aug 15 16:01 nohup.out
[root@node-138 ~]# ll|grep no[i-d]up.out
grep: Invalid range end

这里的-必须是ascii码中的区间范围,如最后一个示例,如果倒序则不支持

22.2 变量

变量,指可以变的值

22.2.1 本地变量

格式:变量名=值,需要注意:

  1. 变量名可以包括数字、字母和_,不能以数字开头,这个同C的规则
  2. =两边不能有空格
  3. 如果包含空格,则需要由单引号或者双引号引起来
  4. 定义变量的时候,不需要加$,引用时需要
  5. 本地变量只能影响当前shell,不能影响子shell
[root@node-138 ~]# a=100
[root@node-138 ~]# bash
[root@node-138 ~]# echo $a

[root@node-138 ~]# exit
exit
[root@node-138 ~]# echo $a
100

定义变量的两种方法:

  1. 把一个值或者命令的结果赋值给一个变量,这个命令需要用$()或者反引号``括起来
  2. 通过read命令获取变量
[root@node-138 ~]# ip=`ifconfig ens37|awk '/inet /{print $2}'`
[root@node-138 ~]# echo $ip
192.168.17.138
[root@node-138 ~]# ip=`ifconfig ens37|awk 'NR==2 {print $2}'`
[root@node-138 ~]# echo $ip
192.168.17.138
[root@node-138 ~]# read -p "input" aa
input100
[root@node-138 ~]# echo $aa
100
22.2.2 环境变量

定义环境变量和本地变量类似,不过需要加export

环境变量可以影响子shell

[root@node-138 ~]# export a=110
[root@node-138 ~]# bash
[root@node-138 ~]# echo $a
110
[root@node-138 ~]# exit
exit
[root@node-138 ~]# echo $a
110
[root@node-138 ~]# env |grep a
...
a=110
...
22.2.3 位置变量和预定义变量
  1. $0:表示脚本名称
  2. $1:表示第一个参数
  3. $2:表示第二个参数
  4. ${10}:第十个参数
  5. $#:参数个数
  6. $*:代表『 “$1c$2c$3c$4” 』,其中 c 为分隔字符,默认为空格键, 所以本例中代表『 “$1 $2 $3 $4” 』之意。一个字符串
  7. $@:代表『 “$1” “$2” “$3” “$4” 』之意,每个变量是独立的(用双引号括起来);多个字符串

单引号和双引号区别:

[root@server ~]# xx=tom
[root@server ~]# echo "my name is $xx"
my name is tom
[root@server ~]# echo 'my name is $xx'
my name is $xx

单引号无法解析变量

22.3 返回值

linux中,命令正确执行,返回值为0。如果没有正确执行,则返回非0。返回值记录在$?

  • 返回值为非0,不一定是语法错误,执行结果如果有否定的意思,返回值也为非0
[root@server ~]# ping 192.168.17.138
PING 192.168.17.138 (192.168.17.138) 56(84) bytes of data.
64 bytes from 192.168.17.138: icmp_seq=1 ttl=64 time=0.311 ms
64 bytes from 192.168.17.138: icmp_seq=2 ttl=64 time=0.282 ms
^C
--- 192.168.17.138 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1042ms
rtt min/avg/max/mdev = 0.282/0.296/0.311/0.014 ms
[root@server ~]# echo $?
0
[root@server ~]# ping 121.147.143.14
PING 121.147.143.14 (121.147.143.14) 56(84) bytes of data.
^C
--- 121.147.143.14 ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3056ms

[root@server ~]# echo $?						#命令正确执行,但返回值为非0
1
[root@server ~]# grep rootxx /etc/passwd
[root@server ~]# echo $?						#命令正确执行,但返回值为非0
1
[root@server ~]# xxx
bash: xxx: command not found...

Failed to search for file: /mnt/AppStream was not found
[root@server ~]# echo $?						#命令不能正确执行,但返回值为非0
127

如果命令未能如预期成功执行,则一般都是返回值非0

22.4 数值运算

常用的数学运算符,如:

  1. +:加
  2. -:减
  3. *:乘
  4. /:除
  5. **:幂

进行数学运算的表达式有$(())、$[]、let等,命令如下:

[root@server ~]# echo 2*3
2*3
[root@server ~]# echo $((2*3))
6
[root@server ~]# echo $((2**3))
8
[root@server ~]# echo $[2*3]
6

$(())$[]用法一样,let如下

[root@server ~]# let a=2*3
[root@server ~]# echo $a
6

也可以通过declare -i把变量定义为整数,再进行运算

[root@server ~]# declare -i b
[root@server ~]# b=2*3
[root@server ~]# echo $b
6

前面的表达式无法计算浮点数,计算浮点数需要使用bc,格式

echo "[scale=N;]算法"|bc [-l]
scale 指定小数点后面保留位数
-l 定义使用的标准数学库;

例如

[root@server ~]# echo "3/2"|bc
1
[root@server ~]# echo "scale=3;3/2"|bc
1.500
[root@server ~]# echo "3/2"|bc -l
1.50000000000000000000

22.5 比较、对比和判断

详细参考
https://blog.csdn.net/u010230019/article/details/132186768
https://blog.csdn.net/u010230019/article/details/131239700

22.6 if判断语句

# 多个条件判断 (if ... elif ... elif ... else) 分多种不同情况执行
if [ 条件判断式一 ]; then
	当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
	当条件判断式二成立时,可以进行的指令工作内容;
else
	当条件判断式一与二均不成立时,可以进行的指令工作内容;
fi
[root@server ~]# if [ $UID -eq 0 ];then
> echo "root"
> fi
root

22.7 for循环语句

参考 https://blog.csdn.net/u010230019/article/details/132193766

shell支持两种形式的for语句,一种是shell形式,另一种是C形式

for var in con1 con2 con3 ...
do
	程序段
done
for (( 初始值; 限制值; 执行步阶 )) 
do
	程序段
done
[root@server ~]# for ((i=1;i<10;i++));do
> echo $i
> done
1
2
3
4
5
6
7
8
9

22.8 while循环语句

while [ condition ] <==中括号内的状态就是判断式 
do <==do 是循环的开始!
	程序段落
done <==done 是循环的结束
[root@server ~]# cat cc.sh
#!/bin/bash

declare -i n=1

while [ $n -lt 10 ];do
        echo $n
        let n=$n+1
done
[root@server ~]# ./cc.sh
1
2
3
4
5
6
7
8
9

从文件输入内容进行循环:

while read aa;do
	echo $aa
done < file
[root@server ~]# while read aa;do echo $aa; done < 123
1
2
3
[root@server ~]# cat 123
1
2
3

循环:

while ((1));dowhile true;dowhile :;do
	命令
done
while true;do
	systemctl is-active vsftpd &> /dev/null
	if [ $? -ne 0 ];then
		systemctl start vsftpd
	fi
	sleep 1
done	

你可能感兴趣的:(#,bash,shell整理,服务器,运维)