Templating com o Linux em um script de shell?

21

o que eu quero realizar é:

1.) Ter um arquivo de configuração como modelo, com variáveis como $ version $ path (por exemplo, configuração do apache)

2.) Ter um script de shell que "preenche" as variáveis do modelo e grava o arquivo gerado no disco.

Isso é possível com um script de shell. Eu ficaria muito grato se você pode nomear alguns comandos / ferramentas que eu posso fazer isso ou alguns bons links.

    
por Markus 06.07.2011 / 23:33

8 respostas

20

Isso é muito possível. Uma maneira muito simples de implementar isso seria que o arquivo de modelo fosse realmente o script e usasse variáveis de shell como

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
cat > /tmp/destfile <<-EOF
here is some config for version $version which should
also reference this path $path
EOF

Você pode até tornar isso configurável na linha de comando, especificando version=$1 e path=$2 , para que você possa executá-lo como bash script /foo/bar/baz 1.2.3 . O - antes do EOF causa espaços em branco antes que as linhas sejam ignoradas, use <<EOF simples se você não quiser esse comportamento.

Outra maneira de fazer isso seria usar a funcionalidade de pesquisa e substituição do sed

#! /bin/bash
version="1.2.3"
path="/foo/bar/baz"
sed -e "s/VERSION/$version/g" -e "s/PATH/$path/" /path/to/templatefile > /tmp/destfile

que substituiria cada instância das strings VERSION e PATH. Se houver outras razões para essas sequências estarem no arquivo de modelo, você poderá fazer sua pesquisa e substituir VERSÃO ou% VERSION% ou algo menos provável de ser acionado acidentalmente.

    
por 06.07.2011 / 23:41
12

Nenhuma ferramenta necessária além de /bin/sh . Dado um arquivo de modelo do formulário

Version: ${version}
Path: ${path}

ou mesmo com código de shell misto incluído

Version: ${version}
Path: ${path}
Cost: ${cost}\$
$(i=1; for w in one two three four; do echo Param${i}: ${w}; i=$(expr $i + 1); done)

e um arquivo de configuração analisável do shell, como

version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"

é simples expandir isso para

Version: 1.2.3-r42
Path: /some/place/under/the/rainbow/where/files/dance/in/happiness
Cost: 42$
Param1: one
Param2: two
Param3: three
Param4: four

De fato, dado o caminho para o arquivo de configuração na variável de shell config_file e o caminho para o arquivo de modelo em template_file , tudo o que você precisa fazer é:

. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""

Isso talvez seja mais bonito do que ter um script de shell completo como o arquivo de modelo (a solução @ mtinberg).

O programa completo de expansor de modelo ingênuo:

#!/bin/sh

PROG=$(basename $0)

usage()
{
    echo "${PROG} <template-file> [ <config-file> ]"
}

expand()
{
    local template="$(cat $1)"
    eval "echo \"${template}\""
}

case $# in
    1) expand "$1";;
    2) . "$2"; expand "$1";;
    *) usage; exit 0;;
esac

Isso produzirá a expansão para a saída padrão; apenas redireciona a saída padrão para um arquivo ou modifica as informações acima de maneira óbvia para produzir o arquivo de saída desejado.

Advertências: A expansão do arquivo de modelo não funcionaria se o arquivo continha aspas duplas sem escape ( " ). Por motivos de segurança, provavelmente devemos incluir algumas verificações de sanidade óbvias ou, melhor ainda, realizar a transformação de escape de shell se o arquivo de modelo for gerado por entidade externa.

    
por 16.06.2015 / 14:47
4

Você provavelmente deve procurar em um sistema de gerenciamento de configuração como Puppet ou Chef . Estes podem facilmente fazer o que você descreve acima e muito mais.

    
por 06.07.2011 / 23:34
4

Se você quiser modelos leves e reais em vez de código de shell que geram novos arquivos, as opções usuais são sed & awk ou perl . Aqui está um link: link

Eu usaria uma linguagem real como perl, tcl, python, ruby ou qualquer outra coisa nessa classe. Algo construído para scripts. Todos eles têm boas ferramentas de templates simples e muitos exemplos no google.

    
por 06.07.2011 / 23:43
4

Eu uso shtpl para isso. (projeto privado meu, o que significa que não é amplamente usado. Mas talvez você queira testá-lo mesmo assim)

Por exemplo, você quer gerar um / etc / network / interfaces de um arquivo csv, você pode fazer assim:

Conteúdo do arquivo CSV (aqui test.csv):

eth0;10.1.0.10;255.255.0.0;10.1.0.1
eth1;192.168.0.10; 255.255.255.0;192.168.0.1

Template (aqui interfaces.tpl):

#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1 
iface $Val1 inet static
  address $Val2 
  netmask $Val3 
  gateway $Val4 

#% done < "$CSVFILE"

Comando:

$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"

Resultado:

auto eth0 
iface eth0 inet static
  address 10.1.0.10 
  netmask 255.255.0.0 
  gateway 10.1.0.1 

auto eth1 
iface eth1 inet static
  address 192.168.0.10 
  netmask  255.255.255.0 
  gateway 192.168.0.1

Aproveite!

    
por 21.10.2012 / 19:52
1

Eu melhorei a resposta do FooF para que o usuário não precise cancelar aspas duplas manualmente:

#!/bin/bash
template="$(cat $1)"
template=$(sed 's/\([^\]\)"/\"/g; s/^"/\"/g' <<< "$template")
eval "echo \"${template}\""
    
por 06.08.2018 / 11:31
0

Estou provavelmente atrasado para esta festa. No entanto, eu tropecei no mesmo problema e optei por criar meu próprio mecanismo de modelo BASH em algumas linhas de código:

Digamos que você tenha este file.template :

# My template
## Author
 - @NAME@ <@EMAIL@>

E esse arquivo rules :

NAME=LEOPOLDO WINSTON
EMAIL=leothewinston\@leoserver.com

Você executa este comando:

templater rules < file.template

Você recebe isto:

# My template
## Author
 - LEOPOLDO WINSTON <[email protected]>

Você pode instalá-lo por:

 bpkg install vicentebolea/bash-templater

Este é o projeto site

    
por 02.07.2018 / 12:45
0

Eu publiquei recentemente um script bash que realiza apenas isso usando uma sintaxe de modelo semelhante a jinja. É chamado de cookie . Aqui está uma demonstração:

    
por 14.11.2018 / 04:33

Tags