如何避免重复执行sed命令向rsyslog.service追加内存配置行
避免重复执行sed命令导致systemd服务配置重复
我们在RedHat 7.x机器上使用以下sed命令,给rsyslog的systemd服务配置追加内存限制相关项:
sed -i '/\[Service\]/a MemoryAccounting=yes\nMemoryCurrent=8192000\nMemoryLimit=8192000' /lib/systemd/system/rsyslog.service
该命令可成功在[Service]行后插入目标配置,但重复执行会导致配置行重复出现:
[Service] MemoryAccounting=yes MemoryCurrent=8192000 MemoryLimit=8192000 MemoryAccounting=yes MemoryCurrent=8192000 MemoryLimit=8192000
以下几种方案可实现目标配置已存在时跳过编辑:
方案1:扩展sed命令,内置存在性检查
通过sed的分支和循环逻辑,先检查[Service]块内是否已有目标配置项,不存在才执行插入:
sed -i '/\[Service\]/ { :loop n /^\[/ b end /MemoryAccounting=yes/ b end b loop :end /MemoryAccounting=yes/ ! { x /\[Service\]/ s/$/\nMemoryAccounting=yes\nMemoryCurrent=8192000\nMemoryLimit=8192000/ x } }' /lib/systemd/system/rsyslog.service
逻辑说明:
- 定位到
[Service]行后,遍历后续内容直到下一个[开头的块 - 若遍历过程中找到
MemoryAccounting=yes,直接结束处理 - 若未找到,则在
[Service]行末尾追加目标配置
方案2:先用grep判断,再执行sed(直观易读)
先通过grep检查文件中是否已存在目标配置,仅当不存在时才执行sed命令:
if ! grep -q "MemoryAccounting=yes" /lib/systemd/system/rsyslog.service; then sed -i '/\[Service\]/a MemoryAccounting=yes\nMemoryCurrent=8192000\nMemoryLimit=8192000' /lib/systemd/system/rsyslog.service # 重载配置并重启服务 systemctl daemon-reload systemctl restart rsyslog.service fi
这种方式逻辑简单,适合对sed复杂语法不熟悉的场景。
方案3:用awk实现精确的块内检查
awk对分段配置文件的处理更清晰,可精准定位[Service]块并检查配置:
awk ' /\[Service\]/ { print found=0 while (getline line > 0) { if (line ~ /^\[/) { if (!found) { print "MemoryAccounting=yes" print "MemoryCurrent=8192000" print "MemoryLimit=8192000" } print line break } if (line ~ /MemoryAccounting=yes/) found=1 print line } next } 1' /lib/systemd/system/rsyslog.service > /tmp/rsyslog.tmp && mv /tmp/rsyslog.tmp /lib/systemd/system/rsyslog.service
逻辑说明:
- 找到
[Service]行后,逐行读取块内内容 - 标记是否已存在
MemoryAccounting=yes - 当遇到下一个配置块开头时,若未找到目标配置则插入,随后继续处理文件剩余内容
配置更新后必要操作
无论采用哪种方案,修改systemd服务配置后都需要执行:
systemctl daemon-reload systemctl restart rsyslog.service
内容的提问来源于stack exchange,提问作者Judy
相关产品推荐
相关产品推荐

