在日常运维中,经常需要监控某个进程,并打印某个进程的监控结果,通常需要打印匹配某个结果的行以及其前后各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

shell脚本中打印所有匹配某些关键字符的行或前后各N行的更多相关文章

  1. shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出

    shell脚本中sqlite3命令查询数据库失败返回空,并将错误信息打印到标准错误输出 如: #/bin/sh local ret='sqlite3 test.db "select test ...

  2. centos shell脚本编程2 if 判断 case判断 shell脚本中的循环 for while shell中的函数 break continue test 命令 第三十六节课

    centos  shell脚本编程2 if 判断  case判断   shell脚本中的循环  for   while   shell中的函数  break  continue  test 命令   ...

  3. Shell脚本中的while getopts用法小结

    getpots是Shell命令行参数解析工具,旨在从Shell Script的命令行当中解析参数.getopts被Shell程序用来分析位置参数,option包含需要被识别的选项字符,如果这里的字符后 ...

  4. Shell脚本中判断输入参数个数的方法投稿:junjie 字体:[增加 减小] 类型:转载

    Shell脚本中判断输入参数个数的方法 投稿:junjie 字体:[增加 减小] 类型:转载   这篇文章主要介绍了Shell脚本中判断输入参数个数的方法,使用内置变量$#即可实现判断输入了多少个参数 ...

  5. shell脚本中局部变量local

    shell脚本中局部变量 在shell中定义函数可以使代码模块化,便于复用代码.不过脚本本身的变量和函数的变量的作用域问题可能令你费解,在这里梳理一下这个问题. (1)Shell脚本中定义的变量是gl ...

  6. shell脚本中常见的一些特殊符号和作用详解

    这篇文章主要介绍了shell脚本中常见的一些特殊符号和它的作用详解,总结的很简洁,容易看懂,需要的朋友可以参考下   在编写Shell脚本时,我们需要会用到各种各样的特殊符号,通过这些特殊符号可以使我 ...

  7. shell脚本中一些特殊变量

    在shell脚本中,一些常见的特殊变量表示方式还是需要知道的 如下就是一些经常用到的特殊变量表示方法: $0    当前脚本名$1 $2...    传入脚本or函数的参数(大于10需大括号括起来)$ ...

  8. Linux shell脚本中shift

    Linux shell脚本中shift的用法说明 shift命令用于对参数的移动(左移),通常用于在不知道传入参数个数的情况下依次遍历每个参数然后进行相应处理(常见于Linux中各种程序的启动脚本). ...

  9. linux crontab执行shell脚本中包含相对路径的问题

    实例一 test.sh文件 echo `date`>test.log 配置crontab 设置 */1 * * * * sh /data/test.sh 在/data/目录下,未找到test.l ...

随机推荐

  1. java重定向与请求转发的区别

    最近工作不算太忙,今天在这里对java中的重定向和请求转发稍作总结,希望能帮助到大家. 请求转发: request.getRequestDispatcher().forward(); 重定向: res ...

  2. java基础-day15

    第01天 java面向对象 今日内容介绍 u 包和权限修饰符 u 内部类 第1章   包和权限修饰符 1.1      包的概述 java的包,其实就是我们电脑系统中的文件夹,包里存放的是类文件. 当 ...

  3. protobuf和protostuff的区别

    在我们的开发过程中,序列化是经常需要处理的问题,比如在做分布式访问数据时,或者是在做redis缓存存储数据时,如果我们涉及的知识面不够广的话,可能会简单的使用JDK的序列化,也即在需要序列化的类上im ...

  4. Codeforces812B Sagheer, the Hausmeister 2017-06-02 20:47 85人阅读 评论(0) 收藏

    B. Sagheer, the Hausmeister time limit per test 1 second memory limit per test 256 megabytes input s ...

  5. 最通熟易懂的Hadoop HDFS实践攻略

    HDFS是用来解决什么问题?怎么解决的? 如何在命令行下操作HDFS? 如何使用Java API来操作HDFS? 在了解基本思路和操作方法后,进一步深究HDFS具体的读写数据流程 学习并实践本文教程后 ...

  6. 怎样去写线程安全的代码(Java)

    使用多线程就可能会存在线程安全的问题.很多 java 程序员对写多线程都很挣扎,或者仅仅理解那些是线程安全的代码,那些不是.这篇文章我并不是详述线程安全,详述同步机制的文章,相反我只是用一个简单的非线 ...

  7. AngularJS transclude 理解及例子

    一.概念理解 transclude可以在指令中让使用者自定义模板,也就是说,指令中模板的一部分,让指令的使用者动态指定:与指定中的Scope属性值为{}时候的作用类似,scope属性让指令使用者动态制 ...

  8. ASP.NET MVC Owin 基本理解

    一.OWIN OWIN(Open Web Interface for .Net),定义了一个服务器(IIS)和Web应用程序(MVC,Webform)通信的标准接口,并且通过抽象层使得这两个在微软平台 ...

  9. Java学习--循环语句1

    1. break public class BreakDemo{ // 完成一个四则运算的功能 public static void main(String args[]){ for(int i=0; ...

  10. NFS Server宕机后,NFS Client主机上df命令挂死

    方法1: 使用root用户:Oracle@NDMCDB05:~> su -Password: NDMCDB05:~ # cat /etc/mtab /dev/sda2 / reiserfs rw ...