在日常運維中,經常需要監控某個進程,並打印某個進程的監控結果,通常需要打印匹配某個結果的行以及其前后各N行。
這里注意下:echo使用-e參數,對打印的結果中進行\n換行
[root@mq-master02 ~]# echo "abcd" abcd [root@mq-master02 ~]# echo "ab\ncd" ab\ncd [root@mq-master02 ~]# echo "ab \n cd" ab \n cd [root@mq-master02 ~]# echo -e "ab\ncd" ab cd [root@mq-master02 ~]# echo -e "ab \n cd" ab cd [root@mq-master02 ~]# echo -e "ab \n cd \n \n df" ab cd df [root@mq-master02 ~]# echo -e "ab\ncd \n \ndf" ab cd df
echo的-n、-e參數:
1)echo -n 表示:不換行輸出 [root@mq-master02 ~]# echo "123" 123 [root@mq-master02 ~]# echo -n "123" 123[root@mq-master02 ~]# 2)echo -e 表示:處理特殊字符。若字符串中出現以下字符,則特別加以處理,而不會將它當成一般文字輸出: \a 發出警告聲; \b 刪除前一個字符; \c 最后不加上換行符號; \f 換行但光標仍舊停留在原來的位置; \n 換行且光標移至行首; \r 光標移至行首,但不換行; \t 插入tab; \v 與\f相同; \\ 插入\字符; \nnn 插入nnn(八進制)所代表的ASCII字符; [root@mq-master02 ~]# echo "123\n456" 123\n456 [root@mq-master02 ~]# echo -e "123\n456" 123 456 [root@mq-master02 ~]# echo -e "wang\bkevin" wankevin
echo后面跟雙引號或單引號問題:
使用echo輸出字符串時候,無論單引號還是雙引號都是一樣的。 如果字符串中有變量,單引號會忽略,而雙引號會把變量解析以后帶入字符串。 也就是說,echo后面的單引號就是一般輸出,對引號里面的變量和特殊操作符號都不識別。 echo后面跟雙引號,雙引號里能識別變量和特殊操作符號; echo后面跟單引號,單引號里不會識別變量和特殊操作符號; 示例: [root@localhost ~]# aa=123 [root@localhost ~]# echo "${aa}" 123 [root@localhost ~]# echo '${aa}' ${aa} 如下,將kill -9 `ps -ef|grep web_server|awk '{print $2}'`這條命令追加到web_script.sh腳本中,正確寫法如下: 由於要保留kill命令后面``操作語句中的單引號和$2,所以單引號和$2前面都要加轉義符\。 下面示例中echo后面加不加-e參數,效果都一樣! [root@localhost ~]# echo -e "kill -9 \`ps -ef|grep web_server|awk '{print \$2}'\`" >> 123.sh [root@localhost ~]# cat 123.sh kill -9 `ps -ef|grep web_server|awk '{print $2}'` 如果不加轉移符號,則echo后面的雙引號就會直接識別出``執行之后的結果,就將web_server的pid打印出來了 [root@localhost ~]# echo -e "kill -9 `ps -ef|grep web_server|awk '{print $2}'`" >> 123.sh [root@localhost ~]# cat 123.sh kill -9 9850 如果echo不使用雙引號,使用單引號,則結果中會把$2內容給抹掉。 [root@localhost ~]# echo -e 'kill -9 `ps -ef|grep web_server|awk '{print $2}'`' >> 123.sh [root@localhost ~]# cat 123.sh kill -9 `ps -ef|grep web_server|awk {print }` 如果echo使用單引號,在單引號里面使用雙引號,如下,在echo的單引號里將awk后面的內容用雙引號,則$2會保留。 但是awk后面必須是單引號才能正確print,awk后面跟單引號就沒有意義了! [root@localhost ~]# echo -e 'kill -9 `ps -ef|grep web_server|awk "{print $2}"`' >> 123.sh [root@localhost ~]# cat 123.sh kill -9 `ps -ef|grep web_server|awk "{print $2}"`
示例1
[root@mq-master02 ~]# cat /opt/test 192.168.10.11 Don't worry! main is running! 192.168.10.12 Don't worry! main is running! 192.168.10.13 It's so bad! main is failed! 192.168.10.14 Don't worry! main is running! 192.168.10.15 Don't worry! main is running! 192.168.10.16 It's so bad! main is failed! 192.168.10.17 Don't worry! main is running! 192.168.10.18 Don't worry! main is running! 192.168.10.19 Don't worry! main is running! 192.168.10.20 Don't worry! main is running! 192.168.10.21 Don't worry! main is running! 192.168.10.12 Don't worry! main is running! 1)打印/opt/test中所有匹配"main is failed"的行 [root@mq-master02 ~]# cat /opt/test |grep "main is failed" It's so bad! main is failed! It's so bad! main is failed! [root@mq-master02 ~]# sed -n '/main is failed/p' /opt/test It's so bad! main is failed! It's so bad! main is failed! 2)打印/opt/test中所有匹配"main is failed"的行及其前1行 [root@mq-master02 ~]# cat /opt/test |grep "main is failed" -B1 192.168.10.13 It's so bad! main is failed! -- 192.168.10.16 It's so bad! main is failed! 3)打印/opt/test中所有匹配"main is failed"的行及其后1行 [root@mq-master02 ~]# cat /opt/test |grep "main is failed" -A1 It's so bad! main is failed! 192.168.10.14 -- It's so bad! main is failed! 192.168.10.17 4)打印/opt/test中所有匹配"main is failed"的行及其前后各1行 [root@mq-master02 ~]# cat /opt/test |grep "main is failed" -C1 192.168.10.13 It's so bad! main is failed! 192.168.10.14 -- 192.168.10.16 It's so bad! main is failed! 192.168.10.17 5)把/opt/test中所有匹配"main is failed"的行及其前1行的結果打印到/root/result.log中,並加上時間 [root@mq-master02 ~]# echo -e "$(date)\n$(cat /opt/test|grep "main is failed" -B1)"> /root/result.log [root@mq-master02 ~]# cat /root/result.log Wed Oct 10 20:34:15 CST 2018 192.168.10.13 It's so bad! main is failed! -- 192.168.10.16 It's so bad! main is failed! [root@mq-master02 ~]# echo -e "$(date)\n$(cat /opt/test|grep "main is failed" -B1) \n" > /root/result.log [root@mq-master02 ~]# echo -e "$(date)\n$(cat /opt/test|grep "main is failed" -B1) \n" >> /root/result.log [root@mq-master02 ~]# echo -e "$(date)\n$(cat /opt/test|grep "main is failed" -B1) \n" >> /root/result.log [root@mq-master02 ~]# cat /root/result.log Wed Oct 10 20:35:27 CST 2018 192.168.10.13 It's so bad! main is failed! -- 192.168.10.16 It's so bad! main is failed! Wed Oct 10 20:35:29 CST 2018 192.168.10.13 It's so bad! main is failed! -- 192.168.10.16 It's so bad! main is failed! Wed Oct 10 20:35:29 CST 2018 192.168.10.13 It's so bad! main is failed! -- 192.168.10.16 It's so bad! main is failed! [root@mq-master02 ~]# echo -e "$(date +%Y年%m月%d日) $(date +%A) $(date +%H時%M分%S秒)\n$(echo "今天是個好日子啊") \n" > /root/result.log You have new mail in /var/spool/mail/root [root@mq-master02 ~]# echo -e "$(date +%Y年%m月%d日) $(date +%A) $(date +%H時%M分%S秒)\n$(echo "今天是個好日子啊") \n" >> /root/result.log [root@mq-master02 ~]# echo -e "$(date +%Y年%m月%d日) $(date +%A) $(date +%H時%M分%S秒)\n$(echo "今天是個好日子啊") \n" >> /root/result.log [root@mq-master02 ~]# cat /root/result.log 2018年10月10日 Wednesday 20時36分49秒 今天是個好日子啊 2018年10月10日 Wednesday 20時36分52秒 今天是個好日子啊 2018年10月10日 Wednesday 20時36分54秒 今天是個好日子啊
示例2
ip列表文件 [root@kevin ~]# cat /opt/ip.list 192.168.10.11 192.168.10.12 192.168.10.13 192.168.10.14 192.168.10.15 192.168.10.16 192.168.10.17 main進程狀態的檢查腳本: [root@kevin ~]# cat /opt/script/6_main_check.sh #!/bin/bash for i in $(cat /opt/ip.list) do /usr/bin/rsync -e "ssh -p22" -avpgolr /usr/bin/main_check $i:/usr/bin/ > /dev/null 2>&1 ssh -p22 root@$i "echo $i;sh /usr/bin/main_check" done [root@kevin ~]# cat /usr/bin/main_check #!/bin/bash NUM=$(ps -ef|grep -w main|grep -v grep|wc -l) if [ $NUM -eq 0 ];then echo "Oh!My God! It's broken! main is stoped!" else echo "Don't worry! main is running!" fi 檢查腳本執行結果 [root@kevin ~]# sh /opt/script/6_main_check.sh 192.168.10.11 Don't worry! main is running! 192.168.10.12 Don't worry! main is running! 192.168.10.13 Don't worry! main is running! 192.168.10.14 Don't worry! main is running! 192.168.10.15 Don't worry! main is running! 192.168.10.16 Don't worry! main is running! 192.168.10.17 Don't worry! main is running! 檢查腳本執行結果的打印腳本 [root@kevin ~]# cat /mnt/main_check_result.sh #!/bin/bash NUM=$(/bin/bash /opt/script/6_main_check.sh |grep -w "main is stoped"|wc -l) CONTENT=$(/bin/bash /opt/script/6_main_check.sh |grep -w "main is stoped") if [ $NUM -ne 0 ];then echo -e "$(date +%Y年%m月%d日) $(date +%A) $(date +%H時%M分%S秒)\n$(/bin/bash /opt/script/6_main_check.sh |grep "main is stoped" -B1)\n">> /mnt/main_check_result.log else echo -e "$(date +%Y年%m月%d日) $(date +%A) $(date +%H時%M分%S秒)\n$(echo "當前時段所有機器的main進程運行正常,無需擔心哈!")\n">> /mnt/main_check_result.log fi main檢查的結果文件內容 [root@kevin ~]# cat /mnt/main_check_result.log 2018年10月10日 星期三 20時30分41秒 當前時段所有機器的main進程運行正常,無需擔心哈! 2018年10月10日 Wednesday 20時30分46秒 當前時段所有機器的main進程運行正常,無需擔心哈! 2018年10月10日 Wednesday 20時35分45秒 當前時段所有機器的main進程運行正常,無需擔心哈! 2018年10月10日 Wednesday 20時40分45秒 當前時段所有機器的main進程運行正常,無需擔心哈! 以上的腳本:不管main進程狀態檢查結果是否正常,都打印一個結果到/mnt/main_check_result.log文件中, 其實檢查結果正常的時候,可以不必打印結果(即echo "****" > /dev/null 2 >&1); 只有檢查結果不正常的時候才打印結果,這樣比較好點。 對/mnt/main_check_result.log文件大小做判斷,當該文件大於60M(即61865984)時就清空。 [root@kevin ~]# ls -l /mnt/main_check_result.log -rw-r--r--. 1 root root 16998 Nov 19 2017 /mnt/main_check_result.log [root@kevin ~]# ls -l /mnt/main_check_result.log|awk '{print $5}' 16998 [root@kevin ~]# ls -l /mnt/main_check_result.log|awk '{print $9}' /mnt/main_check_result.log [root@kevin ~]# vim /root/main_check_result.log_del.sh #!/bin/bash size=$(ls -l /mnt/main_check_result.log|awk '{print $5}') file=$(ls -l /mnt/main_check_result.log|awk '{print $9}') if [ $size -gt 61865984 ] ; then echo $file; echo $size echo >$file fi [root@kevin ~]# chmod 755 /root/main_check_result.log_del.sh [root@kevin ~]# crontab -e 0 1 * * 6 /bin/bash -x /root/main_check_result.log_del.sh >/dev/null 2>&1