回答:
これは非常に可能です。これを実装する非常に簡単な方法は、テンプレートファイルを実際にスクリプトにして、次のようなシェル変数を使用することです。
#! /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
コマンドラインでversion=$1
and を指定することでpath=$2
、これを構成可能にすることもできますbash script /foo/bar/baz 1.2.3
。したがって、次のように実行できます。-
EOFが行は無視される前に空白が発生する前に、プレーンな使用<<EOF
あなたがその振る舞いをしたくない場合。
これを行う別の方法は、検索を使用して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
これは、ストリングVERSIONおよびPATHの各インスタンスを置き換えます。これらの文字列がテンプレートファイルに含まれる他の理由がある場合は、検索と置換をVERSIONまたは%VERSION%にしたり、誤ってトリガーされる可能性が低いものにしたりできます。
以外のツールは必要ありません/bin/sh
。フォームのテンプレートファイルが与えられた
Version: ${version}
Path: ${path}
または、混合シェルコードが含まれている場合でも
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)
シェルの解析可能な構成ファイル
version="1.2.3-r42"
path="/some/place/under/the/rainbow/where/files/dance/in/happiness"
cost="42"
これを展開するのは簡単なことです
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
実際、シェル変数の構成ファイルconfig_file
へのパスとのテンプレートファイルへのパスを指定すると、template_file
必要なことは次のとおりです。
. ${config_file}
template="$(cat ${template_file})"
eval "echo \"${template}\""
これはおそらく、テンプレートファイルとして完全なシェルスクリプト(@mtinbergのソリューション)を持つよりもきれいです。
完全な単純なテンプレート展開プログラム:
#!/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
これにより、拡張が標準出力に出力されます。標準出力をファイルにリダイレクトするか、上記を明白な方法で変更して、目的の出力ファイルを生成します。
警告:ファイルにエスケープされていない二重引用符("
)が含まれている場合、テンプレートファイルの展開は機能しません。セキュリティ上の理由から、テンプレートファイルが外部エンティティによって生成された場合、いくつかの明らかな健全性チェックを含めるか、さらに良いことにシェルエスケープ変換を実行する必要があります。
Linux CLIで簡単にこれを行う最も簡単な方法はenvsubst
、環境変数を使用することです。
テンプレートファイルの例apache.tmpl
:
<VirtualHost *:${PORT}>
ServerName ${SERVER_NAME}
ServerAlias ${SERVER_ALIAS}
DocumentRoot "${DOCUMENT_ROOT}"
</VirtualHost>
envsubst
結果を実行して新しいファイルに出力しますmy_apache_site.conf
:
export PORT="443"
export SERVER_NAME="example.com"
export SERVER_ALIAS="www.example.com"
export DOCUMENT_ROOT="/var/www/html/"
envsubst < apache.tmpl > my_apache_site.conf
出力:
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot "/var/www/html/"
</VirtualHost>
新しいファイルを生成するシェルコードではなく、軽量で実際のテンプレートが必要な場合、通常の選択肢はsed
&awk
またはperl
です。リンクは次のとおりです。http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/
私は、そのクラスでperl、tcl、python、rubyなどの実際の言語を使用します。スクリプト用に構築されたもの。彼らは皆、グーグルで良い、シンプルなテンプレートツールとたくさんの例を持っています。
そのためにshtplを使用します。(私のプライベートプロジェクト、つまり、広く使用されていないことを意味します。しかし、とにかくテストしたいかもしれません)
たとえば、csvファイルから/ etc / network / interfacesを生成するには、次のようにします。
CSVファイルのコンテンツ(ここでは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
テンプレート(ここではinterfaces.tpl):
#% IFS=';'
#% while read "Val1" "Val2" "Val3" "Val4"; do
auto $Val1
iface $Val1 inet static
address $Val2
netmask $Val3
gateway $Val4
#% done < "$CSVFILE"
コマンド:
$ CSVFILE=test.csv sh -c "$( shtpl interfaces.tpl )"
結果:
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
楽しい!
私は最近、ジンジャのようなテンプレート構文を使用してまさにそれを達成するbashスクリプトを公開しました。cookieと呼ばれます。デモは次のとおりです。
私はおそらくこのパーティーに遅れています。しかし、私はまったく同じ問題につまずき、数行のコードで独自のBASHテンプレートエンジンを作成することを選択しました。
これがあるとしましょうfile.template
:
# My template
## Author
- @NAME@ <@EMAIL@>
そして、このrules
ファイル:
NAME=LEOPOLDO WINSTON
EMAIL=leothewinston\@leoserver.com
このコマンドを実行します:
templater rules < file.template
あなたはこれを得る:
# My template
## Author
- LEOPOLDO WINSTON <leothewinston@leoserver.com>
次の方法でインストールできます。
bpkg install vicentebolea/bash-templater
これはプロジェクトサイトです
ヒアドキュメント+制御文字を使用して、@ FooFの優れた答え(改行はコメントにフォーマットされませんでした)を拡張するために、任意の文字とファイル名を許可できます。
template() {
# if [ "$#" -eq 0 ] ; then return; fi # or just error
eval "cat <<$(printf '\x04\x04\x04');
$(cat $1)
"
}
これはヌル以外の文字を受け入れ^D
、独自の行で3 バイトが検出された場合にのみ早期に切り捨てます(現実的にはありません)。zshはヌルターミネータもサポートしているため、printf '\x00\x00\x00'
動作します。 template
次のような危険なファイル名でも機能します。
for num in `seq 10`; do
template 'foo "$ .html' # works
done
シェルテンプレートは、任意のコマンドを「展開」できることに注意してください$(launch_nukes.sh --target $(curl -sL https://freegeoip.app/csv/ | cut -d, -f 9,10))
。大きな力で…
編集:本当にsudo -u nobody sh
(または他の安全なユーザーに)事前にファイルを起動したくない場合。