Flock és fork pontos működése?

Készítettem egy scriptet, ami az aktuális mappában létrehoz egy lock fájlt, és egy -TERM szignálig nyitva is tartja, majd lezárja és letörli. Az elindított script megpróbálja létrehozni a lock fájl. Ha sikerül neki, kiírja a PID értékét, amit a kill parancsnak meg kell adni a zárolás feloldásához, és visszatér 0 értékkel. Ha TIMEOUT másodpercig nem sikerül, akkor visszatér 1 értékkel.

Parancssorból futtatva jól működik, de egy másik bash scriptből hívva a scipt futását megállítja. Pontosabban, ha úgy hívom meg, hogy a visszaadott PID értékét elteszem egy változóba, akkor fagy csak be. Azaz V=$(script) vagy V=`script` soroknál. A lock fájl ugyan  létrejön, de a script futása megáll legelső futtatásra is.

#!/bin/bash
TIMEOUT=3
LOCKFILE="./file.lock"

function wait_for_signal() {
    trap "rm $LOCKFILE" SIGTERM
    until false ; do
        sleep 1
    done
}

touch $LOCKFILE
exec {FD}<>$LOCKFILE
if ! flock -x -w $TIMEOUT $FD; then
    exit 1
else # Lock acquired
    wait_for_signal &
    echo $!
    exit 0
fi

Megírtam ez a scriptet perl-ben is, a perl saját lock-jával és forkjával, és pont ugyanígy működik.

Ezek szerint nem értem pontosan a lock és/vagy a fork működését, vagy valamit nem tudok.

Tudtok segíteni benne, mi a hiba, mitől fagy be egy scriptbe ágyazva a programom, és hogyan tudnám elérni, hogy scriptből hívva ugyanúgy jól működjön, mint parancssorból?

( Kérem az AI-copy válaszok mellőzését, azon már túl vagyok. )

Hozzászólások

Annyit még megpróbáltam, hogy C-ben is elkészítettem ugyanezt a kódot ... és abban is ugyanígy viselkedik.

Szerkesztve: 2024. 09. 27., p – 14:41

Ez az FD ez micsoda benne, hol van definiálva? Valahogy nem értem. Ilyen V=$(script) sort se látok benne.

Amire gondolni tudok, hogy az if feltétel mindig igaz, és nem hajtódik végre az else ág, vagy az a gond, hogy a lockfile-nál relatív utat adtál meg, nem abszolútat. Elsőre megnézném, hogy milyen hibakóddal lép ki a script, mikor azonnal megáll.

The world runs on Excel spreadsheets. (Dylan Beattie)

Az FD a fájlazonosító létrehozása - gondolom. Bash-ban nem vagyok olyan jó, egy példascriptben így volt. Más nyelveken ugye ott a fájl azonosító változója szerepel.

A V= pedig már ennek a scriptnek (mondjuk lock.sh) a felhasználásakor jelenik meg. Ha egy scriptben a "V=`lock.sh`" vagy "V=$(lock.sh)" sor szerepel, akkor a script lefagy - gondolom, vár valamire.

Érdekes módon, ha a felhasználó scriptem egy fájlba irányítja a PID-et (azaz a lock.sh script kimenetét), akkor rendben lefut. Vagyis ezzel a kóddal nincs baj:

lock.sh > tmp.pid
V=`cat tmp.pid`

Ilyen formában rendben lefut.

Bash script debugoláshoz hasznos lehet, ha a sor elején nem szimplán /bin/bash áll, hanem /bin/bash -x

En úgy emlékszem hogy bash-ban amikor sub-shellt indítasz átadja/másolja a nyitott FD-ket és ez viszi magával a lock-ot is. De már régen kellett ilyet nyomoznom és nem is biztos hogy most releváns.

A lock file-t ne te hozd létre kézzel ha FD-re lockolsz és nem állomány névre.

Én valami ilyesmivel próbálkoznék, csak fejből írom mert sietnem kell:

{
   if flock -x -n 42 -w 30
   then
      echo "Lock acquired"
   else
      echo "Better luck next time"
   fi
} 42> "$LOCKFILE"