Banyak jawaban yang menggunakan eval
dan echo
jenis pekerjaan, tetapi merusak berbagai hal, seperti beberapa baris, mencoba keluar dari karakter meta shell, keluar di dalam template yang tidak dimaksudkan untuk diperluas oleh bash, dll.
Saya memiliki masalah yang sama, dan menulis fungsi shell ini, yang sejauh yang saya tahu, menangani semuanya dengan benar. Ini masih akan menghapus baris baru dari templat, karena aturan substitusi perintah bash, tetapi saya tidak pernah menemukan itu menjadi masalah selama yang lainnya tetap utuh.
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"
}
Misalnya, Anda dapat menggunakannya seperti ini dengan parameters.cfg
yang sebenarnya adalah skrip shell yang hanya menetapkan variabel, dan template.txt
yang merupakan template yang menggunakan variabel-variabel tersebut:
. parameters.cfg
printf "%s\n" "$(apply_shell_expansion template.txt)" > result.txt
Dalam praktiknya, saya menggunakan ini sebagai semacam sistem template yang ringan.
Saya menemukan apa yang menurut saya adalah jawaban atas pertanyaan ini:envsubst
perintah:
echo "hello \$FOO world" > source.txt
export FOO=42
envsubst < source.txt
Ini menghasilkan:hello 42 world
Jika Anda ingin melanjutkan mengerjakan data dalam file destination.txt
, Dorong ini kembali ke file seperti ini:
envsubst < source.txt > destination.txt
Jika belum tersedia di distro Anda, ada di paket GNU gettext
.
@Rockallite
- Saya menulis skrip pembungkus kecil untuk mengatasi masalah '$'.
(BTW, ada "fitur" envsubst, dijelaskan di https://unix.stackexchange.com/a/294400/7088untuk memperluas hanya beberapa variabel dalam input, tetapi saya setuju bahwa keluar dari pengecualian jauh lebih nyaman.)
Ini skrip saya:
#! /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]"