eval
を使用した回答の多く そして echo
ただし、複数行、シェル メタ文字のエスケープの試行、bash による展開を意図していないテンプレート内でのエスケープなど、さまざまな点で中断します。
私は同じ問題を抱えており、このシェル関数を作成しました。これは、私が知る限り、すべてを正しく処理します。これは、bash のコマンド置換規則により、テンプレートから末尾の改行のみを削除しますが、他のすべてがそのまま残っている限り、それが問題になることはありません.
apply_shell_expansion() {
declare file="$1"
declare data=$(< "$file")
declare delimiter="__apply_shell_expansion_delimiter__"
declare command="cat <<$delimiter"$'\n'"$data"$'\n'"$delimiter"
eval "$command"
}
たとえば、 parameters.cfg
でこのように使用できます これは実際には変数を設定するだけのシェル スクリプトであり、template.txt
これらの変数を使用するテンプレートです:
. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
実際には、これを一種の軽量テンプレート システムとして使用しています。
私は、この質問に対する答えだと思うものに出くわしました:envsubst
コマンド:
echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt
この出力:hello 42 world
ファイル destination.txt
内のデータで作業を続けたい場合 、これを次のようなファイルにプッシュします:
envsubst < source.txt > destination.txt
お使いのディストリビューションでまだ利用できない場合は、GNU パッケージ gettext
にあります。 .
@Rockallite
- 「$」の問題に対処するために、小さなラッパー スクリプトを作成しました。
(ところで、https://unix.stackexchange.com/a/294400/7088 で説明されている envsubst の「機能」があり、入力内の変数の一部のみを展開しますが、例外をエスケープする方がはるかに便利であることに同意します。)
これが私のスクリプトです:
#! /bin/bash
## -*-Shell-Script-*-
CmdName=${0##*/}
Usage="usage: $CmdName runs envsubst, but allows '\$' to keep variables from
being expanded.
With option -sl '\$' keeps the back-slash.
Default is to replace '\$' with '$'
"
if [[ $1 = -h ]] ;then echo -e >&2 "$Usage" ; exit 1 ;fi
if [[ $1 = -sl ]] ;then sl='\' ; shift ;fi
sed 's/\\\$/\${EnVsUbDolR}/g' | EnVsUbDolR=$sl\$ envsubst "[email protected]"