大纲
一、编程语言分类
二、shell分类
三、变量相关概念
四、bash变量类型
五、变量子串与变量替换
六、逻辑运算
七、算术运算
八、bash条件测试类型及测试方法
九、命令的执行结果与执行状态返回值区别
十、信号捕捉
一、编程语言分类
距离人的远近分类:机器语言、汇编语言、高级语言
执行时是否需要预先转换:编译型语言、解释性语言
编程风格分类:面向对象、面向过程
变量使用时是否需要预先声明:强类型语言、弱类型语言
二、shell分类及bash概念
GUI:Gnome、KDE、Xfce
CLI:sh、bash、csh、ksh、tcsh、zsh
三、变量相关概念
变量定义:命名的一段内存空间
赋值过程定义:保存数据到这段内存空间的过程就叫做赋值
声明变量类型的作用:定义变量的存储格式、存储空间大小及支持的运算
变量类型:数值型、字符型、布尔型、日期时间型
四、bash变量类型
1、本地变量:只对当前shell进程有效,对其子shell以及其它shell都无效
[root@soysauce test]# A='jerry' # 定义一个本地变量A [root@soysauce test]# echo $A jerry
2、局部变量:仅对局部代码生效(且只能在函数中定义)
[root@soysauce test]# local B='tom' # 命令行不能定义局部变量,只能定义于函数中 -bash: local: can only be used in a function [root@soysauce scripts]# cat local.sh #!/bin/bash # A=1 function test { A=$[3+4] # 此时A为一个本地变量 } test # 调用此函数test for I in `seq $A 10`; do echo $I done [root@soysauce scripts]# ./local.sh 7 8 9 10 [root@soysauce scripts]# vim local.sh [root@soysauce scripts]# cat local.sh #!/bin/bash # A=1 function test { local A=$[3+4] # 定义A为局部变量 } test # 同样调用一次函数test for I in `seq $A 10`; do echo $I done [root@soysauce scripts]# ./local.sh # 可以看到定义局部变量后,影响的只是局部范围 1 2 3 4 5 6 7 8 9 10
3、环境变量:对当shell进程及其子shell有效
[root@soysauce test]# export C='natash'# 定义环境变量C [root@soysauce test]# echo $C natash [root@soysauce test]# bash # 重新打开一个子shell [root@soysauce test]# echo $C # 之前定义的环境变量在子shell中依然有效,但是重新登陆就没效了 natash
4、位置变量$[1-10]
$1 # 表示向脚本传递的第一个参数 $2 # 表示向脚本传递的第二个参数
5、特殊变量
$0:脚本名称自身 $#:传递到脚本的参数个数 $?:上一条命令的执行状态返回值,0代表成功 $$:脚本运行的当前shell进程的id号 $!:后台运行的最后一个进程的进程ID号 $*:以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选项参数可超过9个 $@: 与$*相同,但是使用时加引号,并在引号中返回每个参数
五、变量子串与变量赋值替换
1、变量字串
(1)、${parameter#*word}
从左至右,删除行首到第一次被word匹配到的位置 [root@soysauce ~]# A=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin [root@soysauce ~]# echo ${A#*/} # 从左至右,删除行首到第一次被/匹配到的位置 bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
(2)、${parameter##*word}
从左至右,删除行首到最后一次被word匹配到的位置 [root@soysauce ~]# A=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin [root@soysauce ~]# echo ${A##*/} # 从左至右,删除行首到最后一次被/匹配到的位置 sbin
(3)、${parameter%word*}
从右至左,删除行尾到第一次被word匹配到的位置 [root@soysauce ~]# A=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin [root@soysauce ~]# echo ${A%/*} # 从右至左,删除行尾到第一次被/匹配到的位置 /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local
(4)、${parameter%%word*}
从右至左,删除行尾到最后一次被word匹配到的位置 [root@soysauce ~]# A=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin [root@soysauce ~]# echo ${A%%/*} # 从右至左,删除行尾到最后一次被/匹配到的位置 [root@soysauce ~]#
2、变量替换
(1)、${parameter:-word}
如果parameter为空或未定义,则变量展开为“word”;否则,展开为parameter的值;无论何时A不会发生改变 [root@soysauce ~]# A=5 [root@soysauce ~]# echo ${A:-100} 5 # A有值时,结果就为A的值 [root@soysauce ~]# echo $A 5 # A的值未发生改变 [root@soysauce ~]# unset A [root@soysauce ~]# echo ${A:-100} 100 # A未定义时,结果为"-"后面的值 [root@soysauce ~]# echo $A # A的值未发生改变 [root@soysauce ~]# A= [root@soysauce ~]# echo ${A:-100} 100 # A为空时,结果为"-"后面的值 [root@soysauce ~]# echo $A # A的值未发生改变 [root@soysauce ~]# [root@soysauce ~]# unset A # 此时撤销变量A [root@soysauce ~]# A=${A:-100} # 如果A没有定义或为空,那么就将100赋值给A [root@soysauce ~]# echo $A 100
(2)、${parameter:+word}
如果parameter为空或未定义,不做任何操作;否则,则展开为“word”值;无论何时A不会发生改变 [root@soysauce ~]# A=5 [root@soysauce ~]# echo ${A:+100} 100 # A有值时,结果为"-"后面的值 [root@soysauce ~]# echo $A 5 # 此时A值未发生改变 [root@soysauce ~]# unset A [root@soysauce ~]# echo ${A:+100} # A未定义时,结果为空 [root@soysauce ~]# echo $A # 此时A值未发生改变 [root@soysauce ~]# A= [root@soysauce ~]# echo ${A:+100} # A为空时,结果为空 [root@soysauce ~]# echo $A # 此时A值未发生改变 [root@soysauce ~]# A= [root@soysauce ~]# echo $A [root@soysauce ~]# A=5 [root@soysauce ~]# A=${A:+100} # 如果A有值,那么就将100赋值给A [root@soysauce ~]# echo $A 100 [root@soysauce ~]#
(3)、${parameter:=word}
如果parameter为空或未定义,则变量展开为“word”,并将展开后的值赋给parameter;未定义或为空时,A的值会发生改变 [root@soysauce ~]# A=5 [root@soysauce ~]# echo ${A:=100} 5 # A有值时,结果为A的值 [root@soysauce ~]# echo $A 5 # A的值未发生改变 [root@soysauce ~]# unset A [root@soysauce ~]# echo ${A:=100} 100 # A未定义时,结果为"="后面的值 [root@soysauce ~]# echo $A 100 # 并且"="后面的值也赋值给了A [root@soysauce ~]# A= [root@soysauce ~]# echo ${A:=100} 100 # A为空时,结果为"="后的值 [root@soysauce ~]# echo $A 100 # 并且"="后面的值也赋值给了A [root@soysauce ~]# A= [root@soysauce ~]# A=${A:=100} # 如果A为空或未定义时,那么就将100赋值给A [root@soysauce ~]# echo $A 100
(4)、${parameter:?word}:
如果parameter为空或未定义,则变量展开为"world"的错误信息,否则展开为parameter的值;无论何时A不会发生改变 [root@soysauce ~]# A=5 [root@soysauce ~]# echo ${A:?Hello} 5 # A有值时,结果为A的值 [root@soysauce ~]# echo $A 5 # A的值未发生改变 [root@soysauce ~]# unset A [root@soysauce ~]# echo ${A:?Hello} -bash: A: Hello # A未定义时,结果为"?"后的错误提示信息 [root@soysauce ~]# echo $A # A的值未发生改变 [root@soysauce ~]# A= [root@soysauce ~]# echo ${A:?Hello} -bash: A: Hello # A为时,结果为"?"后的错误提示信息 [root@soysauce ~]# echo $A # A的值未发生改变 [root@soysauce ~]# A=5 [root@soysauce ~]# A=${A:?Hello} [root@soysauce ~]# echo $A 5
(5)、${parameter:offset:length}
取子串,从offset处的后一个字符开始,取lenth长的子串 [root@soysauce ~]# A=12345678 [root@soysauce ~]# echo ${A:2} # 偏移量为2,即从第三个数开始往后,显示到最后一个字符 345678 [root@soysauce ~]# A=12345678 # 偏移量为2,即从第三个数开始往后,取5个字符长度 [root@soysauce ~]# echo ${A:2:5} 34567 [root@soysauce ~]# echo ${#A} # 取A变量的长度 8
(6)、${#parameter}
取parameter的长度 [root@soysauce scripts]# A=12345678 [root@soysauce scripts]# echo ${#A} 8 [root@soysauce scripts]# A='Hello Python' [root@soysauce scripts]# echo ${#A} 12
(7)、${parameter:0-n}
取倒数第n个字符到最后一个字符 [root@soysauce ~]# A=12345678 [root@soysauce ~]# echo ${A:0-5} 45678 # 从倒数第5个数开始,显示到最后一个字符 [root@soysauce ~]# echo ${A:0-3} 678 # 从倒数第3个数开始,显示到最后一个字符
(8)、${parameter/old/new}
从左至右,替换parameter中第一次出现"old"的地方为"new" [root@soysauce ~]# A='hello everyone' [root@soysauce ~]# echo ${A/e/E} # 从左至右,将A中第一次出现e的地方替换成E hEllo everyone
(9)、${parameter//old/new}
替换parameter中所有出现"old"的地方为"new" [root@soysauce ~]# A='hello everyone' [root@soysauce ~]# echo ${A//e/E} # 从左至右,将A中所有出现e的地方替换成E hEllo EvEryonE
六、逻辑运算
1、逻辑与:&&
[root@soysauce scripts]# id user2 &> /dev/null && userdel -r user2 && echo "Delete user2 finished." Delete user2 finished. # 前面为真,后面就执行;前面为假,后面就不用执行;如果...就...
2、逻辑或:||
[root@soysauce scripts]# id user2 &> /dev/null || echo "user2 not exists." user2 not exists. # 前面为真,后面就不用执行;前面为假,后面就要执行;如果...否则...
3、逻辑非:!
[root@soysauce scripts]# ! id user2 &> /dev/null && echo "user2 not exists." user2 not exists. # 前面为真,取反之后就为假;前面为假,取反之后就为真;如果不...就...
七、算术运算
1、let算术运算表达式
[root@soysauce scripts]# A=3 [root@soysauce scripts]# B=5 [root@soysauce scripts]# let C=$A+$B;echo $C 8
2、$[算术运算表达式]
[root@soysauce scripts]# A=3 [root@soysauce scripts]# B=5 [root@soysauce scripts]# D=$[$A+$B];echo $D 8
3、$((算术运算表达式))
[root@soysauce scripts]# A=3 [root@soysauce scripts]# B=5 [root@soysauce scripts]# E=$(($A+$B));echo $E 8
4、`expr 算术运算表达式`
表达式中各操作数及运算符之间要有空格,而且要使用命令引用 [root@soysauce scripts]# A=3 [root@soysauce scripts]# B=5 [root@soysauce scripts]# F=`expr $A + $B`;echo $F 8
八、bash条件测试类型及测试方法
1、整数测试
-gt:测试是否大于,大于为真,反之为假 -lt:测试是否小于,小于为真,反之为假 -ge:测试是否大于等于,大于等于为真,反之为假 -le:测试是否是否小于等于,小于等于为真,反之为假 -eq:测试是否等于,等于为真,反之为假 -ne:测试是否不等,不等为真,反之为假
2、文件测试
-e FILE:测试文件是否存在;存在为真,否则为假 -f FILE: 测试文件是否为普通文件;是文件为真,否则为假 -d FILE: 测试指定路径是否为目录;是目录为真,否则为假 -r FILE: 测试当前用户对指定文件是否有读取权限;可读为真,否则为假 -w:测试当前用户对指定文件是否有写权限;可写为真,否则为假 -x:测试当前用户对指定文件是否有执行权限;可执行为真,否则为假 -s FILE:测试文件是否不为空,不为空则为真,空则为假
3、字符测试
==:测试是否相等,相等为真,不等为假 !=: 测试是否不等,不等为真,等为假 -n string: 测试指定字符串是否不空,不空为真,空则为假 -z string: 测试指定字符串是否为空,空为真,不空则为假
4、测试方法
(1)、[ expression ]
[root@soysauce scripts]# [ 3 -gt 2 ] && echo "3>2" 3>2
(2)、` expression `
[root@soysauce scripts]# [[ 3 -gt 2 ]] && echo "3>2" 3>2
(3)、test expression
[root@soysauce scripts]# test 3 -gt 2 && echo "3>2" 3>2
(4)、[[ =~]]
[root@soysauce scripts]# echo $LINE Sw_ip=172.100.16.20 Sw_Int=GigabitEthernet0/0/1 [root@soysauce scripts]# Sw_Ip=`echo $LINE | awk '{print $1}'`;echo $Sw_Ip Sw_ip=172.100.16.20 [root@soysauce scripts]# if [[ $Sw_Ip =~ "^192.168.*" ]];then echo "192.168";else echo "172.16";fi 172.100
5、组合测试条件
(1)、逻辑与
[root@soysauce scripts]# [ 3 -gt 2 -a 3 -lt 5 ] && echo "2<3<5" 2<3<5
(2)、逻辑或
[root@soysauce scripts]# [ 3 -gt 2 -o 3 -gt 5 ] && echo "2<3<5" 2<3<5
(3)、逻辑非
[root@soysauce scripts]# [ ! 3 -gt 5 ] && echo "3<5" 3<5
九、命令的执行结果与执行状态返回值
[root@soysauce scripts]# ls /home/ user4 user8 # 这是命令的执行结果 [root@soysauce scripts]# echo $? 0 # 这是命令的执行状态返回值,0为成功,1-255都为不成功
十、信号捕捉
进程间通信可以依靠信号来实现
[root@soysauce scripts]# kill -l # 查看所有信号 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX 常见的信号 1) SIGHUP # 让一个进程不用重启,就能重读其配置文件,并让其配置文件生效 2) SIGINT # 中止信号,Ctrl+C发出的就是此信号 9) SIGKILL # 强制杀死进程 15) SIGTERM # 终止进程,kill默认的就为此信号 18) SIGCONT # 当任务在后台终止时,使用bg命令其实就是发送此信号 19) SIGSTOP # 运行某前台命令时,使用Ctrl+z其实就是发送此信号 SYNTAX trap [-lp] [arg signal_spec ...] [root@soysauce scripts]# cat ping.sh #!/bin/bash # while :;do ping -c 1 -W 1 172.16.1.3 &> /dev/null && echo "172.16.1.3 is up." || echo "172.16.1.3 is down." done [root@soysauce scripts]# ./ping.sh 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. Killed [root@soysauce ~]# ps aux | grep "bash" root 9229 0.0 0.7 66332 1844 pts/0 Ss 10:19 0:02 -bash root 12734 0.0 0.6 66224 1688 pts/1 Ss 15:54 0:00 -bash root 12804 0.0 0.4 63884 1100 pts/0 S+ 15:55 0:00 /bin/bash ./ping.sh root 12812 0.0 0.2 61216 736 pts/1 R+ 15:55 0:00 grep bash [root@soysauce ~]# kill -9 12804 # 一直ping,按Ctrl+c并不能取消,只能切换终端kill掉 [root@soysauce scripts]# vim ping.sh [root@soysauce scripts]# cat ping.sh #!/bin/bash # trap 'echo "quit";exit 3' SIGINT # 捕捉到SIGINT信号,则立即退出脚本 while :;do ping -c 1 -W 1 172.16.1.3 &> /dev/null && echo "172.16.1.3 is up." || echo "172.16.1.3 is down." done [root@soysauce scripts]# ./ping.sh 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. 172.16.1.3 is down. quit # 当我按了Ctrl+c,也就是发送SIGINT信号,立马退出