首页
学习
活动
专区
圈层
工具
发布
44 篇文章
1
[PyUserInput]模拟鼠标和键盘模拟
2
银行排队模拟(离散事件模拟)
3
Linux网络模拟
4
Linux TC(Traffic Control)作为损伤仪的基础配置和使用
5
深入学习Docker网络(看这篇就完全够了)
6
【鸿蒙 HarmonyOS】鸿蒙手机模拟器 ( 鸿蒙远程模拟器 | 鸿蒙远程模拟器运行手机应用 )
7
探索嵌入式应用框架(EAF)
8
多 OS 混合部署框架
9
嵌入式系统架构浅谈:编程设计模式 (一)---访问硬件的设计模式
10
事件驱动和消息驱动
11
原来 8 张图,就能学废 Reactor 和 Proactor
12
Linux df -h 命令hang住没有反应
13
kafka消费组信息采集异常(hang住)排查
14
ext4 io hung模拟脚本
15
解决 umount 命令卸载磁盘时busy/卡死的问题
16
程序卡死在void HardFault_Handler的解决办法
17
执行sed命令卡死CPU消耗100%一例分析
18
记一次因Redis使用不当导致应用卡死过程
19
字节对齐不慎引发的挂死问题
20
解引用NULL为什么会导致程序挂死?
21
记64位地址截断引发的挂死问题
22
websocket 在线工具_websocket添加请求头
23
【嵌入式Linux应用开发】SquareLine Studio与LVGL模拟器
24
详解Handler机制中消息队列的出队逻辑
25
Android UpdateEngine模块流程(含序列图)
26
物联网时代的嵌入式开发平台
27
400+条实用C/C++框架、库、工具整理 ,你能想到的都在这里了
28
ESP32芯片IO解读
29
M5Stack在ubuntu上进行开发编译
30
【抽象那些事】不完整的抽象&多方面抽象&未用的抽象&重复的抽象
31
H264,你不知道的小技巧
32
linux 创建虚拟块设备,制作文件系统并挂载,用于测试lustre
33
基于linux开发uvc摄像头_uvc协议扩展
34
清晰讲解LSB、MSB和大小端模式及网络字节序
35
在树莓派中使用 MicroPython 接入 MQTT
36
MicroPython 玩转硬件系列1:环境搭建
37
嵌入式系统架构浅谈:编程设计模式 (二)---嵌入并发和资源管理的设计模式
38
嵌入式软件架构设计之分层设计
39
IC之路(一)Proteus-Arduino仿真环境搭建
40
图像处理基础(六)-libjpeg常用算法
41
OpenCV双目标定
42
L-K光流推导及OpenCV代码实现
43
NDI Webcam Input工具,那些你不知道的知识!
44
使用QEMU chroot进行固件本地调试
清单首页其它文章详情

执行sed命令卡死CPU消耗100%一例分析

现象

MySQL服务器安装MHA,sed命令修改安装脚本时卡死:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# sed -i  "s/.*vip.*ping valid.*/#&/g" mha_install.sh 
^C
[root@TJ-DB-6CU552YPXS backup]#

top查看,sed进程CPU使用率100%:

代码语言:javascript
复制
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                   
14343 root      20   0  104m 1020  852 R 100.0  0.0   0:13.94 sed

分析

pstack打印进程堆栈信息:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS ~]# pstack 14343
#0  0x00007f123d474e46 in gconv () from /usr/lib64/gconv/GBK.so
#1  0x0000003f8368c6ab in mbrtowc () from /lib64/libc.so.6
#2  0x00000000004052ed in ?? ()
#3  0x0000000000405373 in ?? ()
#4  0x0000000000406323 in ?? ()
#5  0x0000000000407875 in ?? ()
#6  0x00000000004026e4 in ?? ()
#7  0x0000003f8361f0bd in __libc_start_main () from /lib64/libc.so.6
#8  0x0000000000402029 in ?? ()
#9  0x00007ffcde547f38 in ?? ()
#10 0x000000000000001c in ?? ()
#11 0x0000000000000004 in ?? ()
#12 0x00007ffcde5498d0 in ?? ()
#13 0x00007ffcde5498d4 in ?? ()
#14 0x00007ffcde5498d7 in ?? ()
#15 0x00007ffcde5498da in ?? ()
#16 0x0000000000000000 in ?? ()

sed卡在字符集转换gconv ()函数上,mha_install.sh文件字符集为uft-8,os当前session字符集为gbk:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# file -i mha_install.sh 
mha_install.sh: text/x-shellscript; charset=utf-8
[root@TJ-DB-6CU552YPXS backup]# locale
LANG=zh_CN.gbk
LC_CTYPE="zh_CN.gbk"
LC_NUMERIC="zh_CN.gbk"
LC_TIME="zh_CN.gbk"
LC_COLLATE="zh_CN.gbk"
LC_MONETARY="zh_CN.gbk"
LC_MESSAGES="zh_CN.gbk"
LC_PAPER="zh_CN.gbk"
LC_NAME="zh_CN.gbk"
LC_ADDRESS="zh_CN.gbk"
LC_TELEPHONE="zh_CN.gbk"
LC_MEASUREMENT="zh_CN.gbk"
LC_IDENTIFICATION="zh_CN.gbk"
LC_ALL=
[root@TJ-DB-6CU552YPXS backup]#

即文件中某些内容通过sed命令从uft-8转gbk时卡死,设置环境变量LANG=en_US,不进行字符集转换,再次执行sed命令快速返回结果:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# export LANG=en_US
[root@TJ-DB-6CU552YPXS backup]# sed -i  "s/.*vip.*ping valid.*/#&/g" mha_install.sh 
[root@TJ-DB-6CU552YPXS backup]#

sed命令到底是读到哪一行内容出了问题?使用二分查找,很快便定位了问题所在行为325:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# head -n 324 mha_install.sh|tail -1|sed -n '1p'

[root@TJ-DB-6CU552YPXS backup]# head -n 325 mha_install.sh|tail -1|sed -n '1p'
^C
[root@TJ-DB-6CU552YPXS backup]# head -n 325 mha_install.sh|tail -1
        #生成密钥对
[root@TJ-DB-6CU552YPXS backup]#

从输出不难猜测,应该是注释符号和中文之间没有空格,导致sed命令卡死,下面我们论证测试:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# cat fxtest.txt 
# 生成密钥对
#生成密钥对[root@TJ-DB-6CU552YPXS backup]#

[root@TJ-DB-6CU552YPXS backup]# head -n 1 fxtest.txt |sed -n '1,$p'
# 生成密钥对
[root@TJ-DB-6CU552YPXS backup]# head -n 2 fxtest.txt |sed -n '1,$p'
# 生成密钥对
^C
[root@TJ-DB-6CU552YPXS backup]#

这个安装脚本已经运行多次了,一直都没问题,为何在这台机器上出了问题?机器操作系统为centos 6,估计是sed版本低导致,查看sed版本:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# sed --version
GNU sed  4.2.1

找一台centos 7机器,查看sed版本:

代码语言:javascript
复制
[root@fxtest01 ~]# sed --version
sed (GNU sed) 4.2.2

将 centos 7上sed拷贝到这台centos 6,再次执行同样操作,很快输出结果:

代码语言:javascript
复制
[root@TJ-DB-6CU552YPXS backup]# head -n 2 fxtest.txt |sed -n '1,$p'
# 生成密钥对
^C
[root@TJ-DB-6CU552YPXS backup]#chmod +x sed && head -n 2 fxtest.txt |./sed -n '1,$p'
# 生成密钥对
#生成密钥对[root@TJ-DB-6CU552YPXS backup]#

总结

1、注释符号和汉字之间养成使用空格分隔习惯。

2、一些低版本工具在某些特殊情况下可能会触发bug,仔细分析及比对,总会找到问题根源。

本文关键字:#sed# #cpu# #字符集#

下一篇
举报
领券