私が達成したいのは:
1.)$ version $ path(Apache configなど)などの変数を使用して、設定ファイルをテンプレートとして使用する
2.)テンプレートの変数を「入力」し、生成されたファイルをディスクに書き込むシェルスクリプトを用意します。
これはシェルスクリプトで可能ですか。私がこれを達成できるいくつかのコマンド/ツールまたはいくつかの優れたリンクを挙げていただければ幸いです。
これは非常に可能です。これを実装する非常に簡単な方法は、テンプレートファイルを実際にスクリプトにして、次のようなシェル変数を使用することです。
#! /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
と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>
そのために 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
楽しい!
新しいファイルを生成するシェルコードではなく、軽量で実際のテンプレートが必要な場合、通常の選択肢はsed
&awk
またはPerl
です。これが1つのリンクです: http://savvyadmin.com/generate-text-from-templates-scripts-and-csv-data/
私、Perl、tcl、python、Rubyまたはそのクラスの他の何かなどの実際の言語を使用します。スクリプト用に構築されたものです。それらはすべて、優れたシンプルなテンプレートツールと多数の例を備えていますグーグルで。
ユーザーが二重引用符を手動でアンエスケープする必要がないように、FooFの回答を改善しました。
#!/bin/bash
template="$(cat $1)"
template=$(sed 's/\([^\\]\)"/\1\\"/g; s/^"/\\"/g' <<< "$template")
eval "echo \"${template}\""
私は最近、ジンジャのようなテンプレート構文を使用してそれを実現する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 <[email protected]>
次の方法でインストールできます。
bpkg install vicentebolea/bash-templater
これはプロジェクトです サイト
ヒアドキュメント+制御文字を使用して@FooFの素晴らしい答え(改行がコメントでフォーマットされなかった)を拡張するには、任意の文字を許可できますandファイル名:
_template() {
# if [ "$#" -eq 0 ] ; then return; fi # or just error
eval "cat <<$(printf '\x04\x04\x04');
$(cat $1)
"
}
_
これは、null以外の文字を受け入れ、3つの_^D
_バイトが自分の行で検出された場合にのみ早期に切り捨てます(実際には決してありません)。 zshはnullターミネーターもサポートしているため、_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
_(または他の安全なユーザー)を使用してください。