![如何使用相同的值填充许多配置文件](https://linux22.com/image/112521/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E7%9B%B8%E5%90%8C%E7%9A%84%E5%80%BC%E5%A1%AB%E5%85%85%E8%AE%B8%E5%A4%9A%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6.png)
我有很多程序,并且所有程序在其配置文件中都有一些相同的值(大多数(如果不是全部)都在 中/etc
)。
假设它是主机名,存储在 Apache、Postfix、SQL、clamAV 等的配置文件中......有时我需要更改这些值。我现在要做的就是编辑所有这些文件并查找并用新值替换以前的值。
我想在一处更改它,并正确设置所有这些文件。我想到了bash的export
变量、source
命令或者类似的东西;但是,由于配置文件不可执行,我认为它不会起作用。
推荐的方法是什么?
答案1
显然,您必须确定要管理的所有参数以及它们出现的所有位置。 (呃。) 你已经知道了。
以下方法可能会让您走上正确的道路:
选择一个永远不会出现在配置文件之一中的字符串。 (这听起来像你必须第一次尝试就做好。事实并非如此。如果您选择一个字符串(例如,
@@
)并且稍后需要在其中一个文件中使用该字符串,则可以修复它。您只需要重做很多设置即可。)例如,很久以前,Unix有一个版本控制系统,称为源代码控制系统(SCCS);它将字符串用作
@(#)
永远不会自然出现在文件中的字符串。据我所知,SCCS 不再使用(至少不多),所以使用它应该是安全的@(#)
。或者您可以使用类似!user2461440?
、 或任何您的真实姓名。您可以包含控制字符;例如,Ctrl+A或Ctrl+ G。选择参数占位符的命名约定。这可以是一些简单明了的东西,例如,,,
@(#){HOSTNAME}
等等。@(#){IP}
@(#){GATEWAY}
创建所有配置文件的模板版本,例如
apache.template
等。编辑这些模板以将所有出现的要操作的参数替换为相应的参数占位符(来自上一段)。您应该将这些(以及以下内容)放在安全、偏僻的地方,例如/root
.写一个像这样的脚本:
HOST=Zanzibar IP=10.11.12.42 ︙ LOG=/var/log/lumber ︙ fullpath[apache]=/etc/apache.conf fullpath[postfix]=/etc/postfix/configuration ︙ for file in apache postfix … do path=${fullpath[$file]} sed -e "s/@(#){HOSTNAME}/$HOST/g" \ -e "s/@(#){IP}/$IP/g" \ ︙ -e "s|@(#){LOG}|$LOG|g" \ ︙ "$file.template" > "$path.new" && mv "$path" "$path.bak" && mv "$path.new" "$path" done
@(#){LOG}
请注意,替换为的子命令$LOG
使用了不同的分隔符 (|
),因为该$LOG
值包含/
s。因此,请注意,字符串@(#)
不得包含此分隔符 (|
)。 (当然,它不能包含标准 (/
) 分隔符。)数组(例如,
fullpath[apache]
)并非在所有 shell 中都有效。如果您没有 bash 或其他支持数组的 shell,则需要调整脚本来模拟或解决它们。您可能需要向脚本添加
chown
和命令才能正确设置文件的系统属性。chmod
或者,如果你真的真的确保您的脚本正常工作,您可以修改它以覆盖适当的文件,如sed … > "$path"
从而保留inode及其属性,并且不使用命令
mv
或.new
和.bak
文件。当您想要更改您选择自动执行的参数之一时,请
HOST=Wonderland
在脚本开头编辑相应的赋值语句(例如, )。如果您不想编辑脚本,请将脚本分成两个文件:一个包含参数值(HOST=…
、IP=…
等...),另一个执行配置文件的所有处理。第二个脚本将是source
第一个获取参数值的脚本。这样,当参数值更改时,您只需编辑包含这些值的(脚本)文件,而不是主脚本。请确保不要手动编辑文件,因为这些更改将在您下次运行参数化脚本时被覆盖。相反,编辑相应的模板文件并重新运行脚本。您可能需要在文件中添加注释以提醒您这一点。 (如果您不喜欢为仅影响其中一个配置文件的更改重新生成所有配置文件的想法,您可以修改脚本,使其能够仅重新生成选定的文件。)