【问题标题】:Replace/sync only certain lines using Bash, SSH and rsync仅使用 Bash、SSH 和 rsync 替换/同步某些行
【发布时间】:2015-12-28 16:47:37
【问题描述】:

我正在寻找一种快速而肮脏的单线来仅同步远程配置文件中的某些设置。需要保留独特的内容并同步通用设置。示例:

Config1.conf:

HOSTNAME=COMP1
IP=10.10.13.10

LOCATION=SITE_A
BUILDING=DEPT_IT
ROOM=COMP_LAB1

远程-Config2.txt:

HOSTNAME=COMP2
IP=10.10.13.11

LOCATION=FOO
BUILDING=BAR
ROOM=BAZ

我只需要通过 ssh 同步或复制替换 底部 3 行。顺便说一句,行号是可以预测的。在这种情况下,总是第 4,5 和 6 行。

这是一个工作的想法,但缺少一个(我用来替换本地配置中的变量的非标准实用程序的标准替换):

for var in $(ssh root@10.10.8.12 'sed -n "4,6p" /etc/conf1.conf');do <missing piece> ${var/=*}=${var/*=} local-conf.conf; done

所以这使用变量扩展和非标准实用程序,但需要像 sed 或 Perl 例程来替换本地 conf 中的信息。

更新
最后一行代码确实有效。测试和工作!但是 - 缺少的部分是自定义的非标准实用程序。我在问是否有人可以想出一些东西,使用标准的 Linux 工具来代替它。

一种解决方案是取左侧并匹配,然后替换右侧。这基本上就是该实用程序所做的。在 conf 中查找变量然后设置它。使用变量扩展是一种方法(如图所示)。

【问题讨论】:

  • 您需要以临时名称将整个配置同步到远程(或以临时名称将远程带到本地),然后您可以使用 ssh 将新配置放在一起。类似rsync Config1.conf remote:/tmp/temp1.conf,然后创建新配置ssh remote 'head -n+2 /tmp/temp1.conf &gt; /tmp/tempnew.conf',然后ssh remote 'tail -n+3 remote:/path/to/Config2.txt &gt;&gt; /tmp/tempnew.conf',然后你可以在验证后将/tmp/tempnew.conf复制到Config2.txt。
  • 这是一个很好的解决方案,但我正在寻找操作较少的解决方案。不过谢谢!
  • 为什么这被否决了?这是一个合理且实际的问题——我已经从概念上介绍了它会/可能如何工作。我已经展示了代码——顺便说一句,我提出的最后一行代码确实有效,但依赖于非标准实用程序。我需要一些东西来代替那个实用程序。我什至没有使用备受诟病的eval。那么是什么给出的呢?
  • 你有一群心不在焉的想成为的人,他们通过否决问题而不是做这个网站的目的并真正试图帮助某人来让自己感觉更重要。 . 很难过... 至于你的方法,我喜欢这个想法,但无论你如何切片,它仍然归结为多行替换,通常需要中间临时文件。 (不要个人反对,只考虑来源......)

标签: bash ssh rsync


【解决方案1】:

这是一个替代解决方案,它不需要命令对文件内容有特殊的了解:

  1. 复制您要同步的文件。然后,在副本中,故意破坏(任意修改)您想要同步的行。只要行数相同并且它们永远不会与实际文件内容匹配,他们说什么都没关系。玩得开心。这将成为您的基础版本。您的示例可能如下所示:

    HOSTNAME=foo
    IP=bar
    
    LOCATION=SITE_A
    BUILDING=DEPT_IT
    ROOM=COMP_LAB1
    
  2. rsync 将远程文件放到一个临时位置。这是远程版本。

  3. 对于每个文件,取三路差异。

    diff3 -3 <localfile> <basefile> <remotefile>
    

    diff3 的输出是一个“ed 脚本”,它描述了要对本地文件进行哪些编辑,使其看起来像远程文件。

    -3 选项告诉它只输出不冲突的差异。这就是我们首先破坏基础文件的原因:所以那些行有冲突。

  4. 获得文件的 ed 脚本后,您可以直观地检查它(如果您愿意),然后使用 patch 应用更新:

    cat <ed-script> | patch --ed <localfile>
    

因此,要递归执行此操作,您可能需要:

cd $localdir
for file in `find . -type f`; do
    diff3 -3 "$file" "$basedir/$file" "$remotedir/$file" | patch --ed "$file"
done

您可能需要添加一些检查以确保基本文件和远程文件确实存在。

【讨论】:

  • 这更符合我正在寻找的内容。我会解决这个问题,看看情况如何。谢谢!
猜你喜欢
  • 1970-01-01
  • 2011-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多