Přeskočit na obsah

ERR trap zděděný do command substitution smaže sdílené soubory

import { Aside } from ‘@astrojs/starlight/components’;

Dlouhý automatizační skript (set -Eeuo pipefail, ERR trap s úklidem temp souborů) deterministicky selže o několik kroků později, než kde je skutečná příčina: HTTP klient najednou posílá requesty bez session cookies (server vrací redirect na login), přestože předchozí kroky se stejným cookie jarem fungovaly. V logu není o úklidu ani řádka.

  1. set -E dědí ERR trap do funkcí i command substitution (subshellů).
  2. Skript má krok, který záměrně očekává selhání příkazu a výstup si ukládá:
    Terminál
    OUT=$(psql -c "UPDATE chráněná_tabulka …" 2>&1) && RC=0 || RC=$?
  3. Selhání uvnitř $(...) vystřelí zděděný ERR trap v subshellu. Trap spustí cleanup (rm -f temp souborů) — ale filesystem je sdílený s rodičem, takže zmizí i soubory, které rodič dál potřebuje (cookie jar, response body, …).
  4. 2>&1 uvnitř substituce tiše zachytí i výstup trapu do proměnné — v logu se úklid vůbec neobjeví. Rodičovská || RC=$? větev selhání „ošetří” a skript pokračuje dál s rozbitým prostředím.

Selhání se projeví až u prvního dalšího kroku, který smazané soubory použije — a vypadá jako úplně jiná chyba (ztracená session, chybějící soubor…).

Odzbrojit trap uvnitř substituce — subshell si nese vlastní trap stav:

Terminál
OUT=$(trap - ERR; psql -c "UPDATE chráněná_tabulka …" 2>&1) && RC=0 || RC=$?
  • Response trace HTTP klienta: curl --trace-ascii ukáže WARNING: failed to open cookie file — soubor v době requestu neexistoval.
  • Minimální reprodukce mechanismu:
    Terminál
    bash -c 'set -Eeuo pipefail; J=$(mktemp)
    trap "rm -f \"$J\"; echo CLEANED" ERR
    OUT=$(false 2>&1) || true
    [ -e "$J" ] && echo OK || echo "SOUBOR SMAZAN, vystup trapu: $OUT"'
  • Idiom $(trap - ERR; …) pro všechna záměrně selhávající místa; vynutit statickým testem (regrese: každá substituce následovaná || RC=$? musí začínat trap - ERR;).
  • Cleanup funkce psát tak, aby smazání souborů bylo výhradně věcí rodiče (guard [ "${BASH_SUBSHELL:-0}" = "0" ] || return 0 na začátku trapu).
Přidal aiarchitekt.cz · 11. 8. 2026 2:00
Provozuje aiarchitekt.cz