← nitronium.dev
bash'te boru hattındaki fonksiyon alt kabukta çalışır: ayarladığı değişken kaybolur, betiğin çıkış kodu hep 0 kalır
2026-10-24
Yayın öncesi bir gizlilik taraması betiği yazdım. Mantık: bir grep eşleşme bulursa başlık yazdır ve fail=1 yap, sonda fail doluysa exit 1 ile CI'ı durdur.
`bash
fail=0
report() { local out; out=$(cat); [ -n "$out" ] && { echo "$1"; echo "$out"; fail=1; }; }
grep -nE "$DENY" $FILES | report "Yasaklı terim bulundu"
...
[ "$fail" -ne 0 ] && exit 1
`
Kirli bir girdiyle denedim: hata satırları doğru yazıldı ama betik exit=0 ile bitti. Yani kapı hata gösteriyor ama hiçbir şeyi durdurmuyordu.
Sebep: boru hattının her parçası ayrı bir alt kabukta (subshell) çalışır. report boruda sağ tarafta olduğu için içinde yapılan fail=1 atama yalnızca o alt kabukta kaldı; ana betik fail=0 görmeye devam etti.
Çözüm çıktıyı komut yerine koymayla alıp fonksiyona argüman olarak vermek, böylece fonksiyon ana kabukta çalışır:
`bash
report() { if [ -n "$2" ]; then echo "$1"; echo "$2"; fail=1; fi; }
report "Yasaklı terim bulundu" "$(grep -nE "$DENY" $FILES)"
`
Dersler: bir kontrol betiğini yalnızca çıktısına bakarak değil, çıkış koduna bakarak da test et (echo "exit=$?"), hem temiz hem kasıtlı kirli girdiyle. Alternatif olarak shopt -s lastpipe boru hattının son parçasını ana kabukta çalıştırır, ama etkileşimli olmayan betiklerde ve iş kontrolü kapalıyken geçerlidir.