0Pricing
DevOps Bootcamp · Ders

set -euo pipefail ile Katı Mod

Hızlı başarısız olma davranışını etkinleştirin ve her katı mod seçeneğinin hangi hataları yakalayıp hangilerini kaçırdığını tam olarak anlayın.

set -euo pipefail ile Katı Mod, CoddyKit'te ücretsiz bir DevOps Bootcamp dersidir. Bu, 4 dersinin 1. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DevOps Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DevOps Bootcamp kursu toplamda 4 dersten oluşur.

Bash Varsayılan Olarak Neden Sessizce Başarısız Olur

Bash varsayılan olarak komutlar başarısız olsa bile çalışmayı sürdürür. Bu durum üretim betiklerinde fark edilmesi ve hatasının ayıklanması zor, sinsi felaketlere yol açar.

Yedek oluşturmaya çalışan şu betiği düşünün:

  • Bir yoldaki yazım hatası cp komutunun başarısız olmasına neden olur
  • Bash başarısızlığı yok sayar ve çalışmayı sürdürür
  • Veriler hiç yedeklenmemiş olsa da betik başarı bildirir

Sorun, sessiz başarısızlıktır. Sıkı kip, bir şeyler yanlış gittiğinde hemen durmasını sağlayarak Bash'in derlenmiş bir dil gibi davranmasını sağlar.

#!/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

Üç Temel Seçenek: set -euo pipefail

Sıkı kip, her betiğin üst kısmına şu satır eklenerek etkinleştirilir:

set -euo pipefail

Bu, üç ayrı korumayı etkinleştirir:

  • -e — Herhangi bir komut sıfır olmayan bir durum döndürürse hemen çık
  • -u — Tanımlanmamış değişkenleri hata olarak ele al (boş dizeye genişletmek yerine)
  • -o pipefail — Bir işlem hattındaki yalnızca son komut değil, herhangi bir komut başarısız olursa işlem hattı başarısız olur

Birlikte, ciddi Bash betikleri için standart savunmacı üst bilgiyi oluştururlar. Her seçenek farklı bir hata sınıfını yakalar.

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

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

set -e (errexit) Davranışını Anlama

set -e (ayrıca set -o errexit olarak da yazılır), bir komut sıfır olmayan bir durumla çıktığında betiğin hemen çıkmasına neden olur.

Bilinmesi gereken temel davranışlar:

  • Basit komutlar: false, grep pattern file (eşleşme yok), ls /nonexistent komutlarının tümü çıkışı tetikler
  • Betiğin son komutunun çıkış kodu, betiğin çıkış kodu olur
  • if koşullarındaki komutlar istisnadır — -e, sınama ifadesi için devreye girmez
  • Ardından || true gelen komutlar da istisnadır (sonraki bölümlere bakın)

-e'yi bir başarısızlıktan sonra sessizce çalışmayı sürdürmeye karşı ilk savunma hattınız olarak düşünün.

#!/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"

set -u (nounset) Davranışını Anlama

set -u (ayrıca set -o nounset olarak da yazılır), Bash'in tanımlanmamış bir değişkene yapılan her başvuruyu kritik hata olarak ele almasını sağlar.

-u olmadan, $FILENAME yerine yazılan $FLENAME gibi bir yazım hatası sessizce boş dizeye genişler ve komutların beklenmedik, hatta tehlikeli biçimde davranmasına neden olur ( $TMPDIR tanımlanmamışken rm -rf "$TMPDIR/" çalıştırıldığını düşünün).

Önemli istisnalar:

  • ${VAR:-default} — güvenli varsayılan ikamesidir, -u'yu tetiklemez
  • ${VAR:+value} — koşullu genişletmedir, bu da güvenlidir
  • Konumsal bağımsız değişken geçirilmediğinde "$@" ve "$*" istisnadır
#!/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

-o pipefail Davranışını Anlama

pipefail olmadan bir işlem hattının çıkış durumu yalnızca son komut tarafından belirlenir. Önceki başarısızlıklar sessizce yok sayılır.

pipefail olmadan örnek:

  • cat /missing/file | wc -l
  • cat 1 çıkış koduyla başarısız olur, ancak wc -l 0 koduyla başarılı olur
  • Veriler kaybolmuş olsa bile işlem hattı 0 döndürür — başarı!

pipefail etkinleştirildiğinde Bash, başarısız olan en sağdaki komutun çıkış kodunu döndürür. Bu, işlem hattı başarısızlıklarının görünür ve yakalanabilir olmasını sağlar.

Not: pipefail bir harf seçeneği değildir — -o pipefail ile ayarlanmalıdır.

#!/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"

Kasıtlı Komut Başarısızlıkları — || true Kullanımı

Bazen bir komutun başarısız olmasına izin verilir. set -e kullanırken tolere edilen başarısızlıkları açıkça belirtmeniz gerekir; aksi hâlde betik durur.

Önerilen çözüm, her zaman başarılı olan bir geri dönüş ekleyen || true ifadesidir:

  • command || true — başarısızlığı tamamen yok sayar
  • command || echo "Warning: step failed, continuing" — günlüğe kaydeder ve devam eder
  • command || { echo "fatal"; exit 1; } — özel başarısızlık işleme

Bu yaklaşım, kodda niyetinizi açıkça belirtir: sıradan bir komut “bu başarılı olmalı” anlamına gelir; || true ise “bu başarısız olabilir ve bu sorun değil” anlamına gelir.

#!/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"

set -e Neleri YAKALAMAZ

set -e için iyi bilinen istisnalar ve tuzaklar vardır. Bunları anlamak, yanlış bir güven duygusunu önler:

  • if / while / until koşullarındaki komutlar — sınama ifadesi tasarım gereği istisnadır
  • ! ile değili alınan komutlar — ! false çıkışı tetiklemez
  • || öncesindeki son komut — örneğin false || handle_error
  • Bazı bağlamlarda alt kabuğun çıkış durumu — örneğin bazı Bash sürümlerinde VAR=$(failing_command)
  • İşlev dönüş değerleri — yalnızca bir işlevdeki son komut dikkate alınır

Sıkı kip, açık hata denetiminin yerine geçmez; kazara oluşan başarısızlıkların çoğunu yakalayan bir güvenlik ağıdır.

#!/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"

Sıkı Kipte Alt Kabuklar ve İşlevler

Sıkı kip ayarları alt kabuklar tarafından devralınır, ancak işlevlerde ve komut ikamelerinde incelikli biçimde davranır.

Temel kurallar:

  • İşlevler, çağıran kabuktan -e, -u ve pipefail ayarlarını devralır
  • Bir işlevin sıfır olmayan dönüşü, çağıran kabuğun çıkmasına neden olur (-e ayarlanmışsa) — çağrı bir koşulda veya || sonrasında değilse
  • Komut ikamesi $(): eski Bash sürümlerinde $() içindeki başarısız bir komut üst kabukta -e'yi tetiklemeyebilir; güvenli olmak için önce atayıp sonra ayrı kullanın
  • Açık alt kabuklar () tüm seçenekleri devralır
#!/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"

Sıkı Kipi Hata Yakalamayla Birleştirme

Sıkı kip, Bash'e ne zaman duracağını söyler. ERR üzerinde bir trap kullanmak, betik çıkmadan önce temizlik veya tanılama çalıştırmanızı sağlar.

Yaygın yaklaşım şöyledir:

  • Üst kısımda sıkı kipi ayarlayın
  • Bir cleanup veya on_error işlevi tanımlayın
  • trap 'on_error' ERR ile kaydedin
  • Başarı veya başarısızlıktan bağımsız olarak garantili temizlik için isteğe bağlı olarak EXIT üzerinde de tuzak kurun

Önemli: ERR tuzağının işlevler ve alt kabuklar tarafından da devralınması için set -E (büyük E; errtrace olarak da adlandırılır) kullanın — aksi hâlde tuzaklar yalnızca ana kabuk gövdesinde çalışır.

#!/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"

Sıkı Kipi Yerel Olarak Devre Dışı Bırakma

Bazen bir kod bloğu kasıtlı olarak “dağınık” olur — örneğin isteğe bağlı araçların varlığını denemek veya hata anlamına gelmeyen nedenlerle sıfır olmayan değer döndüren eski komutları çalıştırmak. Sıkı kipi geçici olarak devre dışı bırakıp ardından geri yükleyebilirsiniz.

Güvenli yaklaşım:

  • set +e ile durumu kaydedin (-e'yi devre dışı bırakır), bloğu çalıştırın ve ardından set -e ile yeniden etkinleştirin
  • Ya da bir alt kabuk kullanın: ( set +e; ... ); böylece üst kabuğun seçenekleri hiçbir zaman etkilenmez
  • Riskli blok biter bitmez seçenekleri her zaman yeniden etkinleştirin — seçenekleri kapalı bırakmak yaygın bir hata kaynağıdır

Blok birden fazla komut içeriyorsa alt kabuk biçimini tercih edin; bu biçim, çıkışta seçenekleri otomatik olarak geri yükler.

#!/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

Eksiksiz Sıkı Kip Betiği Şablonu

Bu derste ele alınan tüm sıkı kip en iyi uygulamalarını bir araya getiren, üretime hazır bir şablon aşağıdadır:

  • set -Eeuo pipefail — errtrace dâhil dört seçeneğin tümü
  • IFS=$'\n\t' — daha güvenli sözcük bölme (boşluklara göre bölmeyi önler)
  • Tanılama ve temizlik için ERR + EXIT tuzakları
  • İsteğe bağlı parametreler için açık varsayılan değerler
  • Değişken kapsamını sınırlamak için readonly ve local

Hızlı başarısız olma davranışından ve izlenebilir hatalardan hemen yararlanmak için bu şablonu her karmaşık olmayan Bash betiğinin başına kopyalayın.

#!/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 "$@"

Bilgi Kontrolü: pipefail Davranışı

pipefail seçeneğinin işlem hattı çıkış kodlarını nasıl etkilediğini anlayıp anlamadığınızı test edin.

Özet: set -euo pipefail ile Katı Mod

Bu derste, katı modu kullanarak Bash betiklerinin hızlı ve belirgin biçimde başarısız olmasını nasıl sağlayacağınızı öğrendiniz.

Üç seçenek ve korudukları durumlar:

  • -e (errexit) — sıfır olmayan herhangi bir komut durumunda çıkar; koşullarda ve || sonrasında bunun dışında tutulur
  • -u (nounset) — tanımlanmamış değişken başvurularında işlemi sonlandırır; isteğe bağlı değişkenler için ${VAR:-default} kullanın
  • -o pipefail — yalnızca son aşama değil, herhangi bir aşama başarısız olursa tüm işlem hattını başarısız kılar

Tamamlayıcı uygulamalar:

  • -E (errtrace) ekleyerek ERR tuzaklarının işlevlere yayılmasını sağlayın
  • Tanılama ve temizleme için ERR ve EXIT üzerinde trap kullanın
  • Başarısızlıkları bilerek tolere etmek için || true kullanın
  • Eski veya yoklama amaçlı kod için alt kabukların içinde set +e ile seçeneği geçici olarak devre dışı bırakın

Katı mod her derde deva değildir; istisnalarını bilin. Ancak güvenilir ve savunmacı Bash betikleri yazmak için en etkili tek alışkanlıktır.

Sıkça Sorulan Sorular

“set -euo pipefail ile Katı Mod” dersi ücretsiz mi?

Evet — “set -euo pipefail ile Katı Mod” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DevOps Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DevOps Bootcamp kursu toplamda 4 dersten oluşur.

“set -euo pipefail ile Katı Mod” dersinde ne öğreneceğim?

Hızlı başarısız olma davranışını etkinleştirin ve her katı mod seçeneğinin hangi hataları yakalayıp hangilerini kaçırdığını tam olarak anlayın. DevOps Bootcamp ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

DevOps Bootcamp öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te DevOps Bootcamp, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 1. dersidir.

“set -euo pipefail ile Katı Mod” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu DevOps Bootcamp dersinde kod yazıp çalıştırabilir miyim?

Evet. Her DevOps Bootcamp dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. set -euo pipefail ile Katı Mod
  2. Temizleme ve Sinyaller için Trap İşleyicileri
  3. Güvenli Geçici Dosyalar ve Kilit Dizinleri
  4. İdempotent Betikler ve Geri Çekilmeli Yeniden Deneme Mantığı
← DevOps Bootcamp Sayfasına Dön