Shell-Script
使用腳本編輯類似 INI 的文件
我正在編寫一個腳本來自動在 Docker 中設置 Puppet 代理配置文件。
基本上,我需要確保以下部分位於
/etc/puppet/puppet.conf
:[agent] server=$PUPPETMASTER_HOSTNAME masterport=$PUPPETMASTER_PORT
到目前為止,我在 Puppet 代理 runit 腳本中所做的是:
function write_puppet_config () { read -d '' puppet_config <<EOF [agent] server=$1 masterport=$2 EOF echo -e "$puppet_config" >> /etc/puppet/puppet.conf } # default puppet master port is 8410 test -z "$PUPPET_MASTER_TCP_PORT" && export PUPPET_MASTER_TCP_PORT="8410" # if there is a puppet master host defined, rewrite the config to match if [ ! -z "$PUPPET_MASTER_TCP_HOST" ]; then write_puppet_config "$PUPPET_MASTER_TCP_HOST" "$PUPPET_MASTER_TCP_PORT" fi
問題應該很明顯了。如果 Puppet 配置已經指定了配置,我只是附加了另一個
[agent]
部分,這很糟糕。我可以打開條件邏輯(即:如果存在則 grep,如果存在則用 sed 重寫它),但是有沒有辦法從命令行進行編輯?我想基本上執行一個命令,上面寫著“如果沒有代理部分,請添加它,然後確保伺服器和主埠在該部分中設置為正確的值。”
我知道像這樣的結構化工具存在於 XML 中,但是 INI 樣式的文件呢?
以下是一些腳本範例。這些是最低限度的,並且不會為錯誤檢查、命令行選項等而煩惱。我已經指出我是否自己執行了腳本來驗證它的正確性。
紅寶石
inifile
為此腳本安裝rubygem。此腳本經過測試。#!/usr/bin/env ruby # filename: ~/config.rb require 'inifile' PUPPETMASTER_HOSTNAME='hello' PUPPETMASTER_PORT='world' ini = IniFile::load('/etc/puppet/puppet.conf') ini['agent']['server'] = PUPPETMASTER_HOSTNAME ini['agent']['masterport'] = PUPPETMASTER_PORT ini.save
用法:
$ chmod 700 ~/config.rb $ sudo ~/config.rb # or, if using rvm, rvmsudo ~/config.rb
Perl
Config::IniFiles
使用或您的作業系統包管理器安裝cpan
(如果有可用的包)。此腳本未經測試,因為我已停止perl
在我的系統上使用。它可能需要一些工作,歡迎更正。#!/usr/bin/env perl # filename: ~/config.pl use Config::IniFiles; my $PUPPETMASTER_HOSTNAME='perl'; my $PUPPETMASTER_PORT='1234'; my $ini = Config::IniFiles->new(-file => '/etc/puppet/puppet.conf'); if (! $ini->SectionExists('agent')) { $ini->AddSection('agent'); } if ($ini->exists('agent', 'server')) { $ini->setval('agent', 'server', $PUPPETMASTER_HOSTNAME); } else { $ini->newval('agent', 'server', $PUPPETMASTER_HOSTNAME); } if ($ini->exists('agent', 'masterport')) { $ini->setval('agent', 'masterport', $PUPPETMASTER_PORT); } else { $ini->newval('agent', 'masterport', $PUPPETMASTER_PORT); } $ini->RewriteConfig();
用法:
$ chmod 700 ~/config.pl $ sudo ~/config.pl
awk
該腳本對 Bash 和 *nix 更友好,並使用 *nix OS 的通用實用程序,
awk
. 此腳本經過測試。#!/usr/bin/env awk # filename: ~/config.awk BEGIN { in_agent_section=0; is_host_done=0; is_port_done=0; host = "awk.com"; port = "4567"; } in_agent_section == 1 { if ($0 ~ /^server[[:space:]]*=/) { print "server="host; is_host_done = 1; next; } else if ($0 ~ /^masterport[[:space:]]*=/) { print "masterport="port; is_port_done = 1; next; } else if ($0 ~ /^\[/) { in_agent_section = 0; if (! is_host_done) { print "server="host; } if (! is_port_done) { print "masterport="port; } } } /^\[agent\]/ { in_agent_section=1; } { print; }
用法:
$ awk -f ~/config.awk < /etc/puppet/puppet.conf > /tmp/puppet.conf $ sudo mv /tmp/puppet.conf /etc/puppet/puppet.conf
看看
crudini
,這是為此設計的一個shell工具conf=/etc/puppet/puppet.conf crudini --set "$conf" agent server "$PUPPET_MASTER_TCP_HOST" crudini --set "$conf" agent masterport "$PUPPET_MASTER_TCP_PORT"
或單個原子呼叫,例如:
echo " [agent] server=$1 masterport=$2" | crudini --merge /etc/puppet/puppet.conf