咱们在上一章当中示例了检测ip地址是否在线的脚本,可是有一个问题,运行的过程当中,不管使用Ctrl+c
怎么制止,并无什么卵用,仍是继续运行,直到将最后一个IP地址ping
完,没法制止,只是将当前的ping操做结束,下一个ping
操做就要运行,可是若是连续的按下快捷键,总有一个信号捕捉到,但只有被当前进程的脚本捕捉到才可以中止,而不是ping进程,这就是信号。shell
咱们也能够手动定制信号捕捉的功能,那么如何自定义信号捕捉的处理,那么在ping
操做时,因为信号捕捉不到,那么能不能在捕捉信号以后作出相应的处理操做,对于bash
而言这是能够的,在系统当中有一个trap
命令,经过部署一个陷阱捕捉到信号,或者激发其某个事件进行捕捉处理。数组
咱们可以使用-l
选项来列出可捕捉的全部信号。bash
# trap -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
不过,使用kill -l
也是得到相同的结果,不过要想了解其信号意义,咱们可经过man
手册来进行查看。ide
信号捕捉: 列出信号: trap -l kill -l man 7 signal
信号是进程间通讯间的一种机制,而trap
命令可让bash
脚本自定义如何捕捉信号,但须要注意的是,不能捕捉TERM
和KILL
的信号,由于捕捉信号的意义在于一旦捕捉到以后可以做出什么操做,所以通常捕捉到信号为HUP
以及INT
等,固然其它的信号也能够捕捉,可是没有以上这两个用的那么频繁。函数
经常使用的信号: HUP, INT
示例:字体
#!/bin/bash trap 'echo "Dou ni wan"' INT for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up." else echo "192.168.$i.1 is down." fi done
# bash trap.sh 192.168.1.1 is down. 192.168.2.1 is down. ^CDou ni wan 192.168.3.1 is down. ^CDou ni wan 192.168.4.1 is down. ^CDou ni wan 192.168.5.1 is down. ^CDou ni wan 192.168.6.1 is down.
从以上的运行结果看出,一旦发出Ctrl+c
就是INT
信号后,会显示出Dou ni wan
,可是其实并无中止其ping
进程,只是中止了当前的ping
,而下一个循环的ping
开始运行,若是完全退出的当前bash进程的话,要用另外一种方式。ui
#!/bin/bash trap 'echo "quit"; exit 1' INT for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up." else echo "192.168.$i.1 is down." fi done
那么这就是trap命令的意义,可以其捕捉信号,且捕捉到信号后,使用所定义好的命令来进行处理如何进行,那么以上的信号处理就是显示quit并退出shell进程。code
那么trap命令的方法很简单,后面跟上其参数,并跟上信号声明,而一旦捕捉到其信号以后,咱们做出什么样的处理操做,而它的命令用法为:教程
trap 'COMMAND' SIGNALS
咱们可使用以函数中所定义好的命令的形式来对trap
进行定义然后对其进行捕捉。进程
#!/bin/bash # trap 'mytrap' INT mytrap() { echo "Quit" exit 1 } for i in {1..254}; do if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up" else echo "192.168.$i.1 is down" fi done
而在每次ping
操做完成以后,可建立其临时文件保存其相关的信息。放在循环内部,每一次建立完成可保证将其能够删除,也须要保证三叉输出。
可是这样的话会建立无数个临时文件,咱们须要建立其数组用来其追加到最后一个元素中,遇到终止信号时将其文件进行删除。
#!/bin/bash # declare -a hosttmpfiles trap 'mytrap' INT mytrap() { echo "Quit" rm -f ${hosttmpfiles[@]} exit 1 } for i in {1..254}; do tmpfile=$(mktemp /tmp/ping.XXXXXX) if ping -W1 -c1 192.168.$i.1 &> /dev/null; then echo "192.168.$i.1 is up" | tee $tmpfiles else echo "192.168.$i.1 is down" | tee $tmpfiles fi hosttmpfiles[${#hosttmpfiles[*]}]=$tmpfile done echo ${hosttmpfiles[@]}
在信号捕捉中的函数内部能够写出一些复杂的处理逻辑,包括退出及删除未处理的文件等。
在echo
命令中如何进行着色是一件很简单的事情,关于相关的教程网上也是一抓一大把,那么其着色定义格式为:
\033[31m hello \033[0m
以上这种格式表示随后控制的字体显示为何颜色,以及在那里进行关闭,若是没有关闭的话随后都是以这个颜色进行显示,除非到下一个命令有本身的输出流时才能结束,为了不这种影响,因此要在后面需加上\033[0m
,表示不要影响其后面的着色,就在这个范围内进行着色。
而那两个数字也有个不一样的意义。
##m: 左侧#: 3: 前景色; 4: 背景色; 右侧#: 颜色种类 1, 2, 3, 4, 5, 6, 7
若是使用的是单个数字的话,会改变文本的格式,例如加粗或闪烁等。
#m: 加粗、闪烁等功能; 多种控制符,可组合使用,彼此间用分号隔开;
echo -e "\033[42;35;5,hello world\033[0m"