Penguasaan Baris Perintah Linux & Penskripan Bash · Pelajaran

Menyediakan Templat Konfigurasi dengan envsubst dan heredoc

Jana konfigurasi masa jalan daripada pemboleh ubah persekitaran menggunakan envsubst dan heredoc yang dipetik

Pelajaran 2 daripada 413 langkah

Menyediakan Templat Konfigurasi dengan envsubst dan heredoc ialah pelajaran Penguasaan Baris Perintah Linux & Penskripan Bash percuma di CoddyKit. Ini ialah pelajaran 2 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Penguasaan Baris Perintah Linux & Penskripan Bash, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Penguasaan Baris Perintah Linux & Penskripan Bash merangkumi sejumlah 4 pelajaran.

Mengapa Penghasilan Templat Config Masa Jalan Penting

Dalam aliran kerja DevOps dan bekas, fail konfigurasi seperti nginx.conf, prometheus.yml dan docker-compose.yml sering perlu berubah antara persekitaran — pementasan, produksi dan DR. Menetapkan nilai secara terus menghasilkan ketidakselarasan serta pendedahan rahsia.

Penyelesaiannya ialah penghasilan templat config masa jalan: sertakan templat dengan ruang letak, kemudian masukkan nilai sebenar semasa permulaan daripada pemboleh ubah persekitaran. Ini memastikan imej anda tidak berubah dan config anda boleh diaudit.

  • Tiada rahsia dibenamkan dalam imej
  • Artifak yang sama dinaikkan pangkat merentasi persekitaran
  • Config dijana sejurus sebelum proses bermula

Dua alat yang saling melengkapi menjadikan perkara ini mudah dalam Bash: envsubst dan heredok berpetik.

envsubst: Penjana Config Satu Baris

envsubst ialah utiliti GNU kecil yang membaca stdin, menggantikan ruang letak $VARIABLE dan ${VARIABLE} dengan nilai daripada persekitaran semasa, kemudian menulisnya ke stdout.

Ia disertakan bersama pakej gettext dan tersedia dalam hampir setiap distro Linux serta imej asas Docker.

  • Berfungsi dengan sebarang format teks: NGINX, YAML, TOML, JSON, INI
  • Tidak menilai sintaks shell — hanya menggantikan rujukan pemboleh ubah
  • Selamat: ia tidak akan melaksanakan arahan dalam templat
#!/usr/bin/env bash
# Install check (usually already present)
which envsubst || apt-get install -y gettext-base

# Minimal demo
export APP_PORT=8080
export APP_HOST=api.example.com

echo 'server { listen ${APP_PORT}; server_name ${APP_HOST}; }' | envsubst
# Output: server { listen 8080; server_name api.example.com; }

Penggantian Pemboleh Ubah Terpilih

Secara lalai, envsubst menggantikan setiap $VAR yang ditemuinya. Ini boleh mengubah pemboleh ubah NGINX seperti $uri atau $host — itu ialah arahan NGINX sebenar, bukannya pemboleh ubah persekitaran anda.

Hantar senarai pemboleh ubah yang jelas sebagai argumen pertama untuk mengehadkan penggantian kepada nama tersebut sahaja:

envsubst '$VAR1 $VAR2'

Argumen itu ialah rentetan berpetik tunggal (supaya shell tidak mengembangkannya) yang mengandungi nama pemboleh ubah yang ingin anda gantikan, dipisahkan dengan ruang atau baris baharu.

#!/usr/bin/env bash
export APP_PORT=8080
export APP_HOST=api.example.com

# NGINX template contains both our vars AND nginx vars ($uri, $host)
TEMPLATE='server {
  listen ${APP_PORT};
  server_name ${APP_HOST};
  location / {
    proxy_set_header Host $host;
    proxy_pass http://backend$uri;
  }
}'

# Only substitute APP_PORT and APP_HOST — leave $host and $uri untouched
echo "$TEMPLATE" | envsubst '${APP_PORT} ${APP_HOST}'

Fail Templat pada Cakera

Untuk config sebenar, simpan templat sebagai fail (contohnya, nginx.conf.template) bersama Dockerfile anda. Semasa permulaan bekas, jalankan envsubst untuk menghasilkan fail config akhir sebelum melancarkan daemon.

Ini ialah corak standard yang digunakan oleh imej Docker NGINX rasmi.

#!/usr/bin/env bash
# File: nginx.conf.template
# (In practice this lives on disk; we write it here for demo purposes)
cat > /tmp/nginx.conf.template << 'TMPL'
server {
    listen ${NGINX_PORT};
    server_name ${SERVER_NAME};
    root /var/www/${APP_ENV};

    location / {
        proxy_pass http://app:${APP_PORT};
    }
}
TMPL

export NGINX_PORT=80
export SERVER_NAME=myapp.example.com
export APP_ENV=production
export APP_PORT=3000

# Generate final config
envsubst '${NGINX_PORT} ${SERVER_NAME} ${APP_ENV} ${APP_PORT}' \
  < /tmp/nginx.conf.template \
  > /tmp/nginx.conf

cat /tmp/nginx.conf

Heredok Berpetik: Templat Sebaris Tanpa Fail Sementara

Heredok berpetik (menggunakan << 'EOF' dengan tanda petik tunggal di sekeliling pembatas) menghalang shell daripada mengembangkan pemboleh ubah atau menjalankan penggantian perintah dalam blok tersebut. Kandungan dianggap sebagai rentetan literal.

Ini menjadikan heredok cara yang sempurna untuk menulis templat secara sebaris dan menyalurkannya terus ke envsubst — tiada fail perantaraan diperlukan.

  • << EOF (tanpa petik) — shell mengembangkan $VAR serta-merta
  • << 'EOF' (berpetik) — kandungan ialah literal; pengembangan ditangguhkan kepada envsubst
#!/usr/bin/env bash
export DB_HOST=postgres.internal
export DB_PORT=5432
export DB_NAME=myapp_prod

# Quoted heredoc: shell does NOT expand $DB_HOST etc. yet
envsubst << 'EOF'
[database]
host     = ${DB_HOST}
port     = ${DB_PORT}
dbname   = ${DB_NAME}
EOF
# Output uses actual env var values — expansion done by envsubst, not the shell

Menggabungkan Heredok dengan Pengalihan Keluaran

Salurkan heredok berpetik melalui envsubst dan alihkan hasilnya ke fail dalam satu ungkapan. Ini ialah corak sintaks paling kemas untuk menjana fail konfigurasi dalam skrip titik masuk.

Gunakan penggantian terpilih ('${VAR1} ${VAR2}') apabila format sasaran (Prometheus, NGINX, dll.) mempunyai sintaks $variable sendiri yang perlu dilindungi.

#!/usr/bin/env bash
# entrypoint.sh — Docker container entrypoint
set -euo pipefail

export PROM_PORT=${PROM_PORT:-9090}
export SCRAPE_INTERVAL=${SCRAPE_INTERVAL:-15s}
export TARGET_HOST=${TARGET_HOST:-localhost:8080}

envsubst '${PROM_PORT} ${SCRAPE_INTERVAL} ${TARGET_HOST}' << 'EOF' > /etc/prometheus/prometheus.yml
global:
  scrape_interval: ${SCRAPE_INTERVAL}
  evaluation_interval: ${SCRAPE_INTERVAL}

scrape_configs:
  - job_name: 'app'
    static_configs:
      - targets: ['${TARGET_HOST}']

EOF

echo "[entrypoint] Prometheus config written on port ${PROM_PORT}"
exec prometheus --config.file=/etc/prometheus/prometheus.yml --web.listen-address=":${PROM_PORT}"

Nilai Lalai dan Pengesahan Sebelum Penggantian

Jangan sekali-kali menganggap semua pemboleh ubah yang diperlukan telah ditetapkan. Gunakan pengembangan parameter Bash untuk menyediakan nilai lalai atau menghentikan pelaksanaan dengan ralat yang jelas:

  • ${VAR:-default} — gunakan default jika VAR tidak ditetapkan atau kosong
  • ${VAR:?error message} — batalkan dengan ralat jika VAR tidak ditetapkan atau kosong

Tetapkan nilai ini sebelum memanggil envsubst supaya templat sentiasa menerima nilai nyata atau skrip berhenti lebih awal dengan mesej yang membantu.

#!/usr/bin/env bash
set -euo pipefail

# Required — abort if missing
: "${DATABASE_URL:?DATABASE_URL must be set}"
: "${SECRET_KEY:?SECRET_KEY must be set}"

# Optional with defaults
export APP_PORT=${APP_PORT:-8000}
export LOG_LEVEL=${LOG_LEVEL:-info}
export WORKERS=${WORKERS:-4}

envsubst '${DATABASE_URL} ${SECRET_KEY} ${APP_PORT} ${LOG_LEVEL} ${WORKERS}' \
  < /app/config/app.conf.template \
  > /app/config/app.conf

echo "[init] Config generated — port=${APP_PORT} workers=${WORKERS} log=${LOG_LEVEL}"

Menjana Konfigurasi Berbilang Bahagian dengan Berbilang Heredok

Untuk konfigurasi kompleks yang dibina daripada bahagian logik, anda boleh menjana setiap bahagian secara berasingan dan mencantumkannya, atau menggunakan satu heredok yang merangkumi seluruh fail. Kedua-dua pendekatan berfungsi — pilih berdasarkan kebolehbacaan.

Apabila bahagian disertakan secara bersyarat (contohnya, blok TLS hanya jika laluan sijil ditetapkan), pendekatan berbilang heredok dengan blok if lebih kemas.

#!/usr/bin/env bash
set -euo pipefail

export APP_HOST=${APP_HOST:-localhost}
export APP_PORT=${APP_PORT:-8080}
export TLS_CERT=${TLS_CERT:-}
export TLS_KEY=${TLS_KEY:-}

CONFIG_FILE=/tmp/app.conf

# Base section
envsubst '${APP_HOST} ${APP_PORT}' << 'BASE' > "$CONFIG_FILE"
[server]
host = ${APP_HOST}
port = ${APP_PORT}
BASE

# Conditional TLS section — only appended when cert is provided
if [[ -n "$TLS_CERT" && -n "$TLS_KEY" ]]; then
  envsubst '${TLS_CERT} ${TLS_KEY}' << 'TLS' >> "$CONFIG_FILE"

[tls]
cert_file = ${TLS_CERT}
key_file  = ${TLS_KEY}
TLS
  echo "[init] TLS enabled"
else
  echo "[init] TLS disabled (no cert/key provided)"
fi

cat "$CONFIG_FILE"

Corak Titik Masuk Docker

Corak titik masuk Docker yang disyorkan menggunakan skrip shell (docker-entrypoint.sh) untuk menjana konfigurasi semasa permulaan, kemudian menyerahkan kawalan kepada proses utama dengan exec. Menggunakan exec menggantikan proses shell dengan daemon, jadi isyarat (SIGTERM, SIGINT) sampai terus kepada daemon — penting untuk penutupan yang terkawal.

Fail templat ditambahkan ke dalam imej pada masa binaan; nilai disuntik pada masa jalan daripada docker run -e atau Kubernetes env: / envFrom:.

#!/usr/bin/env bash
# docker-entrypoint.sh
set -euo pipefail

# Validate required env vars
for var in DATABASE_URL REDIS_URL SECRET_KEY; do
  : "${!var:?$var is required}"
done

export APP_PORT=${APP_PORT:-8000}
export WORKERS=${WORKERS:-$(nproc)}

echo "[entrypoint] Generating configuration..."
envsubst '${DATABASE_URL} ${REDIS_URL} ${SECRET_KEY} ${APP_PORT} ${WORKERS}' \
  < /app/config/settings.toml.template \
  > /app/config/settings.toml

echo "[entrypoint] Starting server on port ${APP_PORT} with ${WORKERS} workers"
exec gunicorn app:application \
  --bind "0.0.0.0:${APP_PORT}" \
  --workers "${WORKERS}"

Corak ConfigMap + envsubst Kubernetes

Dalam Kubernetes, pemboleh ubah persekitaran disuntik melalui env: atau envFrom: dalam spesifikasi Pod. Titik masuk bekas anda memanggil envsubst untuk menghasilkan konfigurasi sebelum proses bermula — tiada ConfigMap bagi setiap persekitaran diperlukan.

Ini memastikan nilai khusus persekitaran berada dalam Rahsia dan ConfigMaps Kubernetes (untuk data tidak sensitif), manakala templat konfigurasi berada dalam imej. Satu imej, banyak persekitaran.

  • Binaan: COPY nginx.conf.template /etc/nginx/templates/
  • Masa jalan: titik masuk menjalankan envsubst, menulis /etc/nginx/nginx.conf
  • K8s menyuntik: APP_PORT, BACKEND_HOST daripada Secret/ConfigMap

Menyahpepijat envsubst: Mencari Pemboleh Ubah yang Hilang atau Belum Diselesaikan

Apabila konfigurasi yang dijana mengandungi ${VAR} literal dan bukannya nilai, pemboleh ubah itu tidak dieksport atau tidak dimasukkan dalam senarai penggantian. Gunakan teknik berikut untuk menyahpepijat:

  • printenv | sort — senaraikan semua pemboleh ubah yang dieksport
  • Bandingkan ruang letak dalam templat dengan pemboleh ubah yang dieksport menggunakan grep
  • Jalankan envsubst dan cari dalam keluarannya corak ${ yang masih tinggal
  • Gunakan set -u dalam skrip pemanggil supaya rujukan pemboleh ubah yang tidak ditetapkan dalam kod Bash membatalkan pelaksanaan serta-merta
#!/usr/bin/env bash
set -euo pipefail

TEMPLATE=/tmp/app.conf.template
OUTPUT=/tmp/app.conf

# Write a demo template
cat > "$TEMPLATE" << 'EOF'
host=${DB_HOST}
port=${DB_PORT}
name=${DB_NAME}
EOF

export DB_HOST=db.internal
export DB_PORT=5432
# DB_NAME intentionally left unset

envsubst < "$TEMPLATE" > "$OUTPUT"

# Detect unresolved placeholders
if grep -qE '\$\{[A-Z_]+\}' "$OUTPUT"; then
  echo "ERROR: unresolved placeholders found:"
  grep -oE '\$\{[A-Z_]+\}' "$OUTPUT" | sort -u
  exit 1
fi

echo "Config OK:"
cat "$OUTPUT"

Semakan Pengetahuan: Penggantian Terpilih dengan envsubst

Pertimbangkan templat konfigurasi NGINX yang mengandungi kedua-dua pemboleh ubah aplikasi anda ${APP_PORT} dan pemboleh ubah natif NGINX $uri. Anda menjalankan perintah berikut:

envsubst < nginx.conf.template > nginx.conf

Apakah hasilnya?

Imbas Kembali Pelajaran: Menyediakan Templat Konfigurasi dengan envsubst dan Heredok

Kini anda mempunyai kit alat bertaraf pengeluaran untuk menjana konfigurasi masa jalan dalam Bash:

  • envsubst menggantikan ruang letak ${VAR} dalam mana-mana fail teks menggunakan persekitaran semasa — tanpa perlu menulis skrip atau melakukan pelolosan khas
  • Penggantian terpilih (envsubst '${VAR1} ${VAR2}') melindungi pemboleh ubah natif dalam NGINX, Prometheus dan alat yang serupa daripada penggantian tidak sengaja
  • Heredok berpetik (<< 'EOF') menangguhkan pengembangan shell supaya kandungan templat sampai kepada envsubst tanpa berubah — tiada fail sementara diperlukan
  • Sahkan sebelum menggantikan: gunakan ${VAR:?message} untuk menghentikan pelaksanaan apabila pemboleh ubah wajib tiada dan ${VAR:-default} untuk pemboleh ubah pilihan
  • Corak titik masuk Docker: jana konfigurasi semasa bekas dimulakan, kemudian gunakan exec pada daemon supaya isyarat dikendalikan dengan betul
  • Nyahpepijat ruang letak yang belum diselesaikan dengan mencari dalam keluaran corak ${ yang masih tinggal sebelum proses bermula

Corak ini memastikan imej bekas anda tidak boleh diubah, rahsia anda tidak disimpan dalam kawalan sumber dan konfigurasi anda konsisten merentas setiap persekitaran.

Percuma untuk bermula

Pelajari Bash dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
22
Pelajaran
88

Soalan Lazim

Adakah pelajaran “Menyediakan Templat Konfigurasi dengan envsubst dan heredoc” percuma?

Ya — teks penuh “Menyediakan Templat Konfigurasi dengan envsubst dan heredoc” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Penguasaan Baris Perintah Linux &amp; Penskripan Bash, tingkat taraf kepada CoddyKit PRO. Kursus Penguasaan Baris Perintah Linux &amp; Penskripan Bash merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Menyediakan Templat Konfigurasi dengan envsubst dan heredoc”?

Jana konfigurasi masa jalan daripada pemboleh ubah persekitaran menggunakan envsubst dan heredoc yang dipetik Anda berlatih Penguasaan Baris Perintah Linux &amp; Penskripan Bash menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Penguasaan Baris Perintah Linux &amp; Penskripan Bash?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Penguasaan Baris Perintah Linux &amp; Penskripan Bash di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 4.

Berapa lamakah pelajaran “Menyediakan Templat Konfigurasi dengan envsubst dan heredoc” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Penguasaan Baris Perintah Linux &amp; Penskripan Bash ini?

Ya. Setiap pelajaran Penguasaan Baris Perintah Linux &amp; Penskripan Bash menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Menulis Dockerfile dan Titik Masuk Shell yang Ringkas
  2. Menyediakan Templat Konfigurasi dengan envsubst dan heredoc
  3. Menskripkan Sumber Awan melalui CLI dan jq
  4. Probe Kesihatan, Gerbang Kesediaan dan Gelung Menunggu
← Kembali ke Penguasaan Baris Perintah Linux &amp; Penskripan Bash