ed和ex是unix轻量行编辑器,ed适合简单确定性修改,ex支持复杂正则与多命令;二者均适用于容器/嵌入式环境,需配合备份、验证与权限检查确保安全。

ed 和 ex 是 Unix 早期就存在的行编辑器,轻量、无依赖、完全脚本化,特别适合在容器、嵌入式或最小化系统中做非交互式配置修改。它们不依赖终端控制、不启动交互界面,天然适配自动化场景。
用 ed 实现精准行级替换(推荐用于简单、确定位置的修改)
ed 的核心逻辑是“地址+命令”,先定位行,再执行操作。它默认不输出内容,适合静默批处理。
- 修改某一行中的值(例如把 Port 22 改成 Port 2222):
printf '%s\n' '/^Port[[:space:]]/s/=.*/= 2222/' w q | ed -s /etc/ssh/sshd_config - 说明:
– /^Port[[:space:]]/ 定位以 Port 开头、后跟空白字符的行;
– s/=.*/= 2222/ 替换等号及之后全部内容;
– w 写入文件,q 退出;
– -s 静默模式,避免提示信息干扰脚本。 - 若目标行被注释(如 #Port 22),可先解注释再改:
printf '%s\n' '%s/^#[[:space:]]*\(Port[[:space:]]\)/\1/' '/^Port[[:space:]]/s/=.*/= 2222/' w q | ed -s /etc/ssh/sshd_config
用 ex(vi 的非交互模式)处理更复杂逻辑
ex 是 vi 的底层行模式,语法兼容 vim,支持正则、范围、条件替换,在运维脚本中比 ed 更易读、功能更强。
- 全局替换带空格的键值对(兼容 key=value 和 key = value):
ex -sc '%s/^\([[:space:]]*PermitRootLogin[[:space:]]*\)=.*/\1= no/' -c'%x' /etc/ssh/sshd_config - 说明:
– -s 静默;
– -c 执行命令;
– %s/.../.../ 对全文执行替换;
– \([[:space:]]*PermitRootLogin[[:space:]]*\) 捕获 key 及其周围空格,确保格式不变;
– %x 保存并退出。 - 只改未注释的行,跳过 # 或 ; 开头的配置:
ex -sc '/^[^#;[:space:]]/s/^\([[:space:]]*TCPKeepAlive[[:space:]]*\)=.*/\1= yes/' -c'%x' /etc/ssh/sshd_config
安全实践:备份 + 验证 + 权限检查
直接修改系统配置有风险,脚本中应固化防护动作。
- 强制备份原文件(加时间戳):
cp /etc/sysctl.conf /etc/sysctl.conf.$(date -u +%Y%m%d_%H%M%S).bak - 执行前验证目标行是否存在:
grep -q '^[[:space:]]*vm.swappiness' /etc/sysctl.conf || { echo "key not found"; exit 1; } - 修改后校验语法(如 sysctl.conf 要求数字):
sysctl --system --dry-run >/dev/null 2>&1 || { echo "syntax error"; exit 1; } - 确保权限未被破坏(尤其 /etc/shadow 类敏感文件):
chmod 644 /etc/ssh/sshd_config && chown root:root /etc/ssh/sshd_config
什么时候选 ed,什么时候选 ex?
二者都可靠,但适用场景略有不同:
- ed 更轻:单二进制、无 libc 依赖,适合 initramfs、Alpine、BusyBox 环境;适合纯行号定位(如第5行删掉)、简单模式匹配;
- ex 更强:支持多模式正则、范围操作(:10,20s/.../.../)、多命令链(-c'%s/.../.../e | %s/.../.../e | x'),适合中等复杂度配置管理;
- 注意:macOS 的 ed/ex 默认是 BSD 版,部分 GNU 扩展不支持,生产脚本建议显式检测或统一用 Linux 容器环境运行。











