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 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 pelo shell como
version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"
é uma questão 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 shell config_file
e o caminho para o arquivo de modelo template_file
, tudo o que você precisa fazer é:
. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""
Talvez seja mais bonito do que ter um shell script completo como arquivo de modelo (a solução da @ mtinberg).
O programa completo de expansão de modelos ingênuos:
#!/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; basta redirecionar a saída padrão para um arquivo ou modificar as opçõ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 contivesse aspas duplas sem escape ( "
). Por motivos de segurança, provavelmente devemos incluir algumas verificações óbvias de integridade ou, melhor ainda, executar uma transformação de escape de shell se o arquivo de modelo for gerado por entidade externa.
A maneira mais fácil de fazer isso simplesmente na CLI do Linux é usar
envsubst
e variáveis de ambiente.Arquivo de modelo de exemplo
apache.tmpl
:Execute
envsubst
e envie o resultado para o novo arquivomy_apache_site.conf
:Saída:
fonte
Você provavelmente deveria procurar um sistema de gerenciamento de configuração como Puppet ou Chef . Eles podem facilmente fazer o que você descreve acima e muito mais.
fonte
name
, a cadeia de caracteres<%= name %>
em um modelo será substituídaname
pelo valor de. Como você definename
fora do modelo difere entre os dois sistemas, obviamente.Se você deseja modelos leves e reais, em vez de código shell que gera novos arquivos, as opções comuns são
sed
&awk
ouperl
. Aqui está um link: http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/Eu usaria uma linguagem real como perl, tcl, python, ruby ou qualquer outra coisa nessa classe. Algo criado para scripts. Todos eles têm boas ferramentas simples de modelagem e vários exemplos no google.
fonte
Eu uso o shtpl para isso. (projeto particular meu, o que significa que ele não é amplamente utilizado. Mas talvez você queira testá-lo de qualquer maneira)
Por exemplo, você deseja gerar um / etc / network / interfaces a partir de um arquivo csv, pode fazer o seguinte:
Conteúdo do arquivo CSV (aqui test.csv):
Modelo (aqui interfaces.tpl):
Comando:
Resultado:
Apreciar!
fonte
Aprimorei a resposta do FooF para que o usuário não precise descolar aspas duplas manualmente:
fonte
Recentemente, publiquei um script bash que realiza exatamente isso usando uma sintaxe de modelo semelhante a um jinja. Chama-se cookie . Aqui está uma demonstração:
fonte
Provavelmente estou atrasado para esta festa. No entanto, deparei-me com o mesmo problema e optei por criar meu próprio mecanismo de modelo BASH em algumas linhas de código:
Vamos dizer que você tem isso
file.template
:E esse
rules
arquivo:Você executa este comando:
Você obtém isso:
Você pode instalá-lo:
Este é o site do projeto
fonte
Para expandir a ótima resposta do @ FooF (as novas linhas não foram formatadas nos comentários), usando caracteres heredoc + controle, você pode permitir caracteres e nomes de arquivos arbitrários :
Isso aceita qualquer caractere não nulo e somente trunca antecipadamente se
^D
forem encontrados 3 bytes em sua própria linha (realisticamente nunca). O zsh suporta até terminadores nulos, entãoprintf '\x00\x00\x00'
funcionaria.template
até funciona para nomes de arquivos traiçoeiros como:Cuidado com os modelos de shell podem "expandir" comandos arbitrários, por exemplo
$(launch_nukes.sh --target $(curl -sL https://freegeoip.app/csv/ | cut -d, -f 9,10))
. Com grande poder ...Editar: se você realmente não deseja que seus arquivos iniciem armas nucleares para você, apenas
sudo -u nobody sh
(ou algum outro usuário seguro) de antemão.fonte