0Pricing
DevOps Bootcamp · Pelajaran

Mode Ketat dengan set -euo pipefail

Aktifkan perilaku gagal-seketika dan pahami dengan tepat error mana yang ditangkap atau terlewatkan oleh setiap flag mode ketat.

Mode Ketat dengan set -euo pipefail adalah pelajaran DevOps Bootcamp gratis di CoddyKit. Ini adalah pelajaran 1 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar DevOps Bootcamp, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus DevOps Bootcamp mencakup 4 pelajaran total.

Mengapa Bash Gagal Secara Diam-Diam Secara Bawaan

Secara bawaan, Bash tetap berjalan meskipun perintah gagal. Hal ini menyebabkan masalah tersembunyi yang sulit dilacak dalam skrip produksi.

Perhatikan skrip yang mencoba membuat cadangan berikut:

  • Salah ketik pada jalur menyebabkan cp gagal
  • Bash mengabaikan kegagalan tersebut dan melanjutkan
  • Skrip melaporkan keberhasilan meskipun data tidak pernah dicadangkan

Inilah masalah kegagalan diam-diam. Mode ketat mengatasinya dengan membuat Bash berperilaku seperti bahasa terkompilasi: segera berhenti saat terjadi masalah.

#!/usr/bin/env bash
# Without strict mode — dangerous default behavior

cp /important/data /backups/data   # fails (path doesn't exist)
echo "Backup complete"              # still prints — false confidence!
rm -rf /tmp/staging                # still runs — potentially destructive

Tiga Tanda Utama: set -euo pipefail

Mode ketat diaktifkan dengan menempatkan baris berikut di dekat bagian atas setiap skrip:

set -euo pipefail

Perintah ini mengaktifkan tiga pengaman berbeda:

  • -e — Segera keluar jika suatu perintah mengembalikan status bukan nol
  • -u — Perlakukan variabel yang belum ditetapkan sebagai kesalahan (alih-alih mengembangkannya menjadi string kosong)
  • -o pipefail — Alur gagal jika perintah mana pun di dalamnya gagal, bukan hanya perintah terakhir

Bersama-sama, ketiganya membentuk header pertahanan standar untuk skrip Bash yang serius. Setiap tanda menangkap jenis bug yang berbeda.

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

echo "Strict mode is now active"
echo "Every command failure will abort the script"

Memahami set -e (errexit)

set -e (yang juga ditulis sebagai set -o errexit) menyebabkan skrip segera keluar saat suatu perintah keluar dengan status bukan nol.

Perilaku penting yang perlu diketahui:

  • Perintah sederhana: false, grep pattern file (tidak ada kecocokan), dan ls /nonexistent semuanya memicu keluar
  • Kode keluar dari perintah terakhir dalam skrip menjadi kode keluar skrip
  • Perintah dalam kondisi if dikecualikan—-e tidak aktif untuk ekspresi pengujian
  • Perintah yang diikuti || true juga dikecualikan (lihat bagian berikutnya)

Anggap -e sebagai garis pertahanan pertama Anda agar skrip tidak terus berjalan secara diam-diam setelah kegagalan.

#!/usr/bin/env bash
set -e

echo "Before failure"
ls /this/path/does/not/exist   # exits here with code 2
echo "This line never runs"

Memahami set -u (nounset)

set -u (yang juga ditulis sebagai set -o nounset) membuat Bash memperlakukan setiap rujukan ke variabel yang belum ditetapkan sebagai kesalahan fatal.

Tanpa -u, salah ketik seperti $FLENAME alih-alih $FILENAME diam-diam diperluas menjadi string kosong, sehingga perintah berperilaku tidak semestinya—atau bahkan berbahaya (bayangkan rm -rf "$TMPDIR/" saat $TMPDIR belum ditetapkan).

Pengecualian penting:

  • ${VAR:-default} — penggantian nilai bawaan yang aman dan tidak memicu -u
  • ${VAR:+value} — ekspansi bersyarat yang juga aman
  • "$@" dan "$*" dikecualikan saat tidak ada argumen posisi yang diberikan
#!/usr/bin/env bash
set -euo pipefail

# Safe: provide a default for optional vars
OUTPUT_DIR="${1:-/tmp/output}"
LOG_LEVEL="${LOG_LEVEL:-info}"

echo "Writing to: $OUTPUT_DIR"
echo "Log level: $LOG_LEVEL"

# This would abort the script:
# echo "$UNDEFINED_VAR"   # bash: UNDEFINED_VAR: unbound variable

Memahami -o pipefail

Tanpa pipefail, status keluar suatu alur hanya ditentukan oleh perintah terakhir. Kegagalan sebelumnya ditelan secara diam-diam.

Contoh tanpa pipefail:

  • cat /missing/file | wc -l
  • cat gagal dengan kode keluar 1, tetapi wc -l berhasil dengan kode 0
  • Alur mengembalikan 0—berhasil! Padahal data telah hilang.

Dengan pipefail diaktifkan, Bash mengembalikan kode keluar dari perintah paling kanan yang gagal. Dengan demikian, kegagalan alur terlihat dan dapat ditangani.

Catatan: pipefail bukan tanda berupa satu huruf—pengaturannya harus menggunakan -o pipefail.

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

# With pipefail: this aborts if grep finds nothing (exit 1)
# grep returns 1 when no match found
ps aux | grep "[n]ginx" | awk '{print $2}'

echo "If we reach here, nginx is running"

Kegagalan Perintah yang Disengaja — Menggunakan || true

Terkadang suatu perintah boleh gagal. Dengan set -e, Anda harus menyatakan kegagalan yang ditoleransi secara eksplisit; jika tidak, skrip akan berhenti.

Solusi idiomatisnya adalah || true, yang menambahkan pengganti yang selalu berhasil:

  • command || true — sepenuhnya mengabaikan kegagalan
  • command || echo "Warning: step failed, continuing" — mencatat peringatan dan melanjutkan
  • command || { echo "fatal"; exit 1; } — penanganan kegagalan khusus

Pola ini memperjelas maksud Anda dalam kode: perintah biasa berarti “ini harus berhasil”; || true berarti “ini boleh gagal dan tidak masalah”.

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

# Remove temp dir if it exists — OK if it doesn't
rm -rf /tmp/my_workspace || true
mkdir -p /tmp/my_workspace

# Check if a service is running — OK if not
if systemctl is-active --quiet nginx 2>/dev/null || true; then
  echo "nginx is active"
fi

# Grep that may find nothing — OK
grep 'ERROR' /var/log/app.log || true

echo "Done"

Hal yang TIDAK Ditangkap oleh set -e

set -e memiliki pengecualian dan jebakan yang sudah dikenal. Memahaminya mencegah rasa percaya diri yang keliru:

  • Perintah dalam kondisi if / while / until—ekspresi pengujian dikecualikan berdasarkan rancangan
  • Perintah yang dinegasikan dengan !—! false tidak memicu keluar
  • Perintah terakhir sebelum ||—misalnya false || handle_error
  • Status keluar subshell dalam konteks tertentu—misalnya VAR=$(failing_command) pada beberapa versi Bash
  • Nilai pengembalian fungsi—hanya perintah terakhir dalam fungsi yang diperhitungkan

Mode ketat bukan pengganti pemeriksaan kesalahan secara eksplisit—mode ini adalah jaring pengaman yang menangkap sebagian besar kegagalan yang tidak disengaja.

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

# These do NOT trigger -e:
if false; then echo "never"; fi         # -e exempt in conditions
! false                                  # negation exempts
false || echo "handled"                 # || exempts the left side

# This DOES trigger -e (no condition, no ||):
# false

echo "Script continues after exempted failures"

Subshell dan Fungsi dengan Mode Ketat

Pengaturan mode ketat diwariskan oleh subshell, tetapi berperilaku secara halus dalam fungsi dan substitusi perintah.

Aturan utama:

  • Fungsi mewarisi -e, -u, dan pipefail dari shell pemanggil
  • Pengembalian bukan nol dari suatu fungsi menyebabkan pemanggil keluar (saat -e ditetapkan)—kecuali pemanggilan berada dalam kondisi atau setelah ||
  • Substitusi perintah $(): pada Bash versi lama, perintah yang gagal di dalam $() mungkin tidak memicu -e pada induknya; tetapkan nilainya lalu gunakan secara terpisah agar aman
  • Subshell eksplisit () mewarisi semua tanda
#!/usr/bin/env bash
set -euo pipefail

setup_workspace() {
  local dir="$1"
  mkdir -p "$dir"          # fails here if permissions denied
  cd "$dir"
  echo "Ready in $(pwd)"
}

# Safe pattern: assign result then use it
TODAY=$(date +%Y-%m-%d)   # capture separately
WORKDIR="/tmp/run_${TODAY}"

setup_workspace "$WORKDIR"
echo "Workspace: $WORKDIR"

Menggabungkan Mode Ketat dengan Penjebakan Kesalahan

Mode ketat memberi tahu Bash kapan harus berhenti. trap pada ERR memungkinkan Anda menjalankan pembersihan atau diagnostik sebelum skrip keluar.

Pola umumnya adalah:

  • Tetapkan mode ketat di bagian atas
  • Definisikan fungsi cleanup atau on_error
  • Daftarkan fungsi tersebut dengan trap 'on_error' ERR
  • Jika diperlukan, pasang trap EXIT juga untuk pembersihan yang terjamin, baik saat berhasil maupun gagal

Penting: gunakan set -E (E kapital, juga disebut errtrace) agar trap ERR juga diwariskan oleh fungsi dan subshell—tanpanya, trap hanya aktif di badan shell utama.

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

on_error() {
  local exit_code=$?
  local line_number=${BASH_LINENO[0]}
  echo "ERROR: command failed with code ${exit_code} at line ${line_number}" >&2
}

cleanup() {
  echo "Cleaning up temporary files..." >&2
  rm -rf /tmp/my_run_dir 2>/dev/null || true
}

trap on_error ERR
trap cleanup EXIT

mkdir -p /tmp/my_run_dir
echo "hello" > /tmp/my_run_dir/output.txt
cat /tmp/my_run_dir/output.txt
echo "Done"

Menonaktifkan Mode Ketat Secara Lokal

Terkadang suatu blok kode memang sengaja “berantakan”—misalnya, saat memeriksa keberadaan alat opsional atau menjalankan perintah lama yang mengembalikan nilai bukan nol bukan karena kesalahan. Anda dapat menonaktifkan mode ketat sementara lalu mengaktifkannya kembali.

Pola yang aman:

  • Simpan keadaan dengan set +e (menonaktifkan -e), jalankan blok tersebut, lalu aktifkan kembali dengan set -e
  • Atau gunakan subshell ( set +e; ... ) agar tanda pada shell induk tidak pernah terpengaruh
  • Selalu aktifkan kembali tanda-tanda tersebut segera setelah blok berisiko selesai—membiarkannya nonaktif adalah sumber bug yang umum

Utamakan bentuk subshell jika blok tersebut melibatkan beberapa perintah, karena tanda-tanda akan dipulihkan secara otomatis saat subshell keluar.

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

# Probe for optional tools without aborting
HAS_JQ=false
(
  set +e
  command -v jq > /dev/null 2>&1
  [[ $? -eq 0 ]] && echo "jq_found"
) && HAS_JQ=true || true

if [[ "$HAS_JQ" == "true" ]]; then
  echo "jq is available — using JSON output"
else
  echo "jq not found — using plain text"
fi

Templat Skrip Mode Ketat Lengkap

Berikut templat siap produksi yang menggabungkan semua praktik terbaik mode ketat yang dibahas dalam pelajaran ini:

  • set -Eeuo pipefail — keempat tanda, termasuk errtrace
  • IFS=$'\n\t' — pemisahan kata yang lebih aman (menghindari pemisahan berdasarkan spasi)
  • Trap ERR + EXIT untuk diagnostik dan pembersihan
  • Nilai bawaan eksplisit untuk parameter opsional
  • readonly dan local untuk membatasi cakupan variabel

Salin templat ini di awal setiap skrip Bash yang tidak sederhana untuk segera memperoleh manfaat dari perilaku berhenti-cepat dan kesalahan yang dapat dilacak.

#!/usr/bin/env bash
set -Eeuo pipefail
IFS=$'\n\t'

# ── Constants ────────────────────────────────────────────
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "$0")"

# ── Trap handlers ────────────────────────────────────────
err_handler() {
  echo "[${SCRIPT_NAME}] ERROR on line ${BASH_LINENO[0]}: exit ${?}" >&2
}
cleanup() {
  echo "[${SCRIPT_NAME}] Exiting" >&2
}
trap err_handler ERR
trap cleanup EXIT

# ── Defaults ─────────────────────────────────────────────
ENV="${1:-production}"
MAX_RETRIES="${MAX_RETRIES:-3}"

# ── Main ─────────────────────────────────────────────────
main() {
  echo "Running in env=${ENV}, max_retries=${MAX_RETRIES}"
  echo "Script dir: ${SCRIPT_DIR}"
}

main "$@"

Pemeriksaan Pengetahuan: Perilaku pipefail

Uji pemahaman Anda tentang pengaruh pipefail terhadap kode keluar alur pemrosesan.

Rangkuman: Mode Ketat dengan set -euo pipefail

Dalam pelajaran ini, Anda mempelajari cara membuat skrip Bash gagal dengan cepat dan jelas menggunakan mode ketat.

Tiga opsi dan hal yang dilindunginya:

  • -e (errexit) — keluar saat status perintah bernilai bukan nol; dikecualikan dalam kondisi dan setelah ||
  • -u (nounset) — membatalkan eksekusi saat merujuk variabel yang belum ditetapkan; gunakan ${VAR:-default} untuk variabel opsional
  • -o pipefail — membuat seluruh alur pemrosesan gagal jika tahap mana pun gagal, bukan hanya tahap terakhir

Praktik pelengkap:

  • Tambahkan -E (errtrace) agar perangkap ERR diteruskan ke dalam fungsi
  • Gunakan trap pada ERR dan EXIT untuk diagnosis dan pembersihan
  • Gunakan || true untuk sengaja menoleransi kegagalan
  • Nonaktifkan sementara dengan set +e di dalam subproses untuk kode lama atau kode pemeriksaan

Mode ketat bukanlah solusi untuk semua masalah — pahami pengecualiannya — tetapi ini adalah kebiasaan tunggal yang paling efektif untuk menulis skrip Bash yang andal dan defensif.

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Mode Ketat dengan set -euo pipefail” gratis?

Ya — teks lengkap “Mode Ketat dengan set -euo pipefail” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus DevOps Bootcamp, upgrade ke CoddyKit PRO. Kursus DevOps Bootcamp mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Mode Ketat dengan set -euo pipefail”?

Aktifkan perilaku gagal-seketika dan pahami dengan tepat error mana yang ditangkap atau terlewatkan oleh setiap flag mode ketat. Kamu berlatih DevOps Bootcamp dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai DevOps Bootcamp?

Tidak diperlukan pengalaman sebelumnya. DevOps Bootcamp di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 4.

Berapa lama pelajaran “Mode Ketat dengan set -euo pipefail” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran DevOps Bootcamp ini?

Ya. Setiap pelajaran DevOps Bootcamp menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Mode Ketat dengan set -euo pipefail
  2. Penangan Trap untuk Pembersihan dan Sinyal
  3. File Sementara yang Aman dan Direktori Kunci
  4. Skrip Idempoten dan Logika Percobaan Ulang dengan Backoff
← Kembali ke DevOps Bootcamp