You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用简洁命令注释Ansible Vault加密变量及其后续缩进内容?

问题描述

我正在编写Ansible Playbook,用于自动存储由Play生成的Ansible Vault加密密钥,密钥在YAML文件中的格式如下:

---
my_secret_thing: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          64356439663234656438636635316531623966623736396235376562613039356435623135366164
          3939626637326538663934636637643761etcetcetc

当密钥变更时,我需要注释掉整个旧密钥并添加新密钥。最初我用以下Ansible任务来注释旧密钥:

- name: Comment out previous secret
    run_once: True
    ansible.builtin.shell: "grep '^my_secret_thing' $PWD/{{ env }}_group_vars/secrets.yml && START=$(cat $PWD/{{ env }}_group_vars/secrets.yml |grep -n '^my_secret_thing'|cut -d ':' -f 1) && END=$(expr $START + 10) && sed -i \"$START,$END s/^/#/\" $PWD/{{ env }}_group_vars/secrets.yml"
    delegate_to: 127.0.0.1
    ignore_errors: True # Otherwise will 'fail' if no token is currently stored

一开始我假设每个密钥占用固定10行,但实际情况并非如此。所以我想替换这个Shell命令,实现匹配my_secret_thing:这一行,然后注释该行以及所有后续以10个空格开头的行,直到遇到下一个无缩进的变量行(行首无空格)。我自己写了一段bash脚本,但希望能用更简洁的单行命令实现,请问有什么建议?

附我编写的bash脚本:

#!/bin/bash

MATCH=0
COUNT=0
IFS=$'\n'
for LINE in `cat secrets.yml`;
do
  if [ $MATCH -eq 0 ];
  then
    if [ `echo $LINE |grep '^my_secret_stuff:'` ];
    then
      MATCH=1
      continue
    else
      continue
    fi
  fi
  if [ $MATCH -eq 1 ];
  then
    if [ $MATCH -eq 1 ] && [ `echo $LINE |grep '^ \{10\}'` ];
    then
      let COUNT++
      continue
    elif [ `echo $LINE |grep '^[a-z_]*:'` ];
    then
      break
    fi
  fi
done
unset IFS
echo $COUNT
解决方案

可以用sed或awk的多行匹配功能实现需求,替代复杂的循环脚本,以下是两种简洁的单行命令方案:

方案1:使用sed命令

sed -i '/^my_secret_thing:/,/^[^ ]/ {/^my_secret_thing:/s/^/#/; /^          /s/^/#/}' $PWD/{{ env }}_group_vars/secrets.yml

命令说明:

  • /^my_secret_thing:/,/^[^ ]/:定义匹配范围,从my_secret_thing:开头的行开始,直到遇到行首非空格的行结束。
  • {/^my_secret_thing:/s/^/#/; /^ /s/^/#/}:在范围内执行两个替换操作:
    1. 给my_secret_thing:开头的行首添加#注释
    2. 给以10个空格开头的密钥内容行首添加#注释

注:如果是macOS环境的BSD sed,需要在-i后加空参数,命令调整为:

sed -i '' '/^my_secret_thing:/,/^[^ ]/ {/^my_secret_thing:/s/^/#/; /^          /s/^/#/}' $PWD/{{ env }}_group_vars/secrets.yml

方案2:使用awk命令(逻辑更清晰)

awk '/^my_secret_thing:/ {flag=1} flag {sub(/^/,"#")} /^[^ ]/ && flag {flag=0} 1' $PWD/{{ env }}_group_vars/secrets.yml > temp.yml && mv temp.yml $PWD/{{ env }}_group_vars/secrets.yml

命令说明:

  1. /^my_secret_thing:/ {flag=1}:匹配到目标变量行时,开启标记flag
  2. flag {sub(/^/,"#")}:标记开启时,给当前行首添加#注释
  3. /^[^ ]/ && flag {flag=0}:遇到行首非空格的行且标记开启时,关闭标记
  4. 1:打印所有行(包括注释后的行)

将awk命令替换到Ansible任务中:

- name: Comment out previous secret
    run_once: True
    ansible.builtin.shell: |
      awk '/^my_secret_thing:/ {flag=1} flag {sub(/^/,"#")} /^[^ ]/ && flag {flag=0} 1' $PWD/{{ env }}_group_vars/secrets.yml > temp.yml && mv temp.yml $PWD/{{ env }}_group_vars/secrets.yml
    delegate_to: 127.0.0.1
    ignore_errors: True

内容的提问来源于stack exchange,提问作者anfieldroad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 22:35:20