Linux-komentorivin ja Bash-komentosarjojen hallinta · Oppitunti

Turvalliset väliaikaistiedostot ja lukitushakemistot

Luo mktempilla ja flockilla kilpailutilanteilta suojattuja väliaikaisia resursseja ja estä skriptien samanaikaiset ajot.

Oppitunti 3/413 vaihetta

Turvalliset väliaikaistiedostot ja lukitushakemistot on ilmainen Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Linux-komentorivin ja Bash-komentosarjojen hallinta-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssilla on yhteensä 4 oppituntia.

Miksi väliaikaiset tiedostot ovat tietoturvariski

Bash-komentosarjat tarvitsevat usein väliaikaista tallennustilaa — välituloksia, lukitusmerkintöjä ja valmistelualueita. Väliaikaisten tiedostojen huolimaton luominen avaa kuitenkin vakavia haavoittuvuuksia.

  • Rotutilanteet: toinen prosessi voi arvata tiedostonimen ja luoda tiedoston ensin, jolloin kirjoitukset ohjautuvat väärin.
  • Symbolisten linkkien hyökkäykset: hyökkääjä luo odotettuun polkuun symbolisen linkin, joka osoittaa arkaluontoiseen tiedostoon, kuten tiedostoon /etc/passwd.
  • Jäljelle jäävät tiedostot: jos komentosarja kaatuu, väliaikaisia tiedostoja kasaantuu ja ne voivat paljastaa arkaluontoisia tietoja.

Kaksi keskeistä työkalua, joilla nämä ongelmat voidaan poistaa, ovat mktemp ja flock. Tässä oppitunnissa opitte käyttämään molempia turvallisesti ja vikasietoisesti.

Turvallisten väliaikaisten tiedostojen luominen mktemp-komennolla

mktemp luo väliaikaisen tiedoston satunnaisella, ennalta arvaamattomalla nimellä ja palauttaa sen polun. Se luo tiedoston atomisesti, joten mikään muu prosessi ei voi varata nimeä ensin.

  • Syntaksi: mktemp [TEMPLATE] — mallin lopussa on oltava vähintään kolme X-merkkiä.
  • Jokainen X korvataan satunnaisella merkillä, jolloin syntyy yksilöllinen nimi, kuten /tmp/script.aB3kQz.
  • Tiedosto luodaan automaattisesti oikeuksilla 0600 (vain omistaja voi lukea sitä).

Tallentakaa palautettu polku aina heti muuttujaan, jotta voitte käyttää sitä ja siivota tiedoston myöhemmin.

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

# Create a secure temp file
TMPFILE=$(mktemp /tmp/myapp.XXXXXX)
echo "Temp file created at: $TMPFILE"

# Write data to it
echo "some intermediate result" > "$TMPFILE"

# Read it back
cat "$TMPFILE"

# Clean up
rm -f "$TMPFILE"

Siivotkaa aina trapin avulla

Jos komentosarja päättyy odottamatta — virheen, signaalin tai set -e-asetuksen laukaisemana — väliaikaiset tiedostot jäävät jäljelle, ellette rekisteröi siivouskäsittelijää.

trap-sisäänrakennettu komento suorittaa komennon, kun shell vastaanottaa signaalin tai päättyy. Väliaikaisten tiedostojen siivouksen vakiomalli on:

  • Rekisteröikää trap heti väliaikaisen tiedoston luomisen jälkeen.
  • Rekisteröikää trap tapahtumalle EXIT, jotta siivous suoritetaan sekä normaalin että poikkeavan päättymisen yhteydessä.
  • Rekisteröikää lisäksi trap tapahtumille INT ja TERM, jos komentosarja suoritetaan pitkään tai vuorovaikutteisesti.

Näin varmistetaan, ettei orpotiedostoja jää jäljelle, vaikka komentosarja lopetettaisiin kesken suorituksen.

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

TMPFILE=$(mktemp /tmp/report.XXXXXX)

# Register cleanup before doing any real work
cleanup() {
    rm -f "$TMPFILE"
    echo "Cleaned up $TMPFILE" >&2
}
trap cleanup EXIT

# Do work — even if this fails, cleanup() will run
echo "Processing..." > "$TMPFILE"
grep "result" "$TMPFILE" || true

echo "Done. File will be removed on exit."

Väliaikaishakemistojen luominen komennolla mktemp -d

Joskus tarvitsette kokonaisen hakemiston useiden tiedostojen valmistelua varten — esimerkiksi arkiston rakentamiseen tai tar-paketin purkamiseen ennen käsittelyä. Komennolla mktemp -d voitte luoda turvallisen väliaikaishakemiston.

  • Hakemisto luodaan käyttöoikeuksilla 0700 (vain omistajan käyttöoikeus).
  • Poistakaa hakemisto rm -rf-komennolla trap-käsittelijässä — poistakaa varmuuden vuoksi vain muuttujan sisältämä polku, ei koskaan kovakoodattua polkua.
  • Käyttäkää kaksoislainausmerkkejä ja varmistakaa turvallisuuden lisäämiseksi, ettei muuttuja ole tyhjä, ennen kuin kutsutte komentoa rm -rf.
#!/usr/bin/env bash
set -euo pipefail

TMPDIR=$(mktemp -d /tmp/extract.XXXXXX)

cleanup() {
    # Guard: only rm if variable is set and non-empty
    [[ -n "${TMPDIR:-}" ]] && rm -rf "$TMPDIR"
}
trap cleanup EXIT

echo "Working in $TMPDIR"

# Simulate staging files
echo "file one" > "$TMPDIR/part1.txt"
echo "file two" > "$TMPDIR/part2.txt"

ls "$TMPDIR"
echo "All done."

Samanaikaisten komentosarjojen suoritusten ongelma

Cron-työt, systemd-ajastimet ja manuaalisesti käynnistetyt komentosarjat voivat helposti käynnistää saman komentosarjan useita esiintymiä samanaikaisesti. Tämä aiheuttaa seuraavia ongelmia:

  • Moninkertainen käsittely: Samat tietokantatietueet tai tiedostot käsitellään kahdesti.
  • Vioittunut tuloste: Kaksi esiintymää kirjoittaa samaan tulostiedostoon samanaikaisesti.
  • Umpilukot tai osittainen tila: Molemmat esiintymät muokkaavat jaettuja resursseja lomittain ja ennalta arvaamattomassa järjestyksessä.

Perinteinen ratkaisu oli kirjoittaa PID-tiedosto ja tarkistaa se käynnistyksen yhteydessä — tähän lähestymistapaan liittyy kuitenkin kilpailutilanne tarkistuksen ja kirjoituksen välissä. Oikea nykyaikainen ratkaisu on flock, joka käyttää ytimen neuvoteltavaa lukitusmekanismia ja takaa kilpailutilanteilta vapaan lukituksen.

Lukitseminen flock-komennolla: yhden rivin malli

flock hankkii neuvoteltavan lukituksen tiedostokuvaajalle ennen komennon suorittamista. Yksinkertaisimmillaan koko komentosarja voidaan kääriä komentoriviltä seuraavasti:

flock -n /var/lock/myscript.lock bash myscript.sh

  • -n (non-blocking): lopettaa heti tilakoodilla 1, jos lukitus on jo käytössä, sen sijaan että jäisi odottamaan.
  • Ilman valitsinta -n flock odottaa, kunnes lukitus vapautuu — tämä sopii jonottamiseen.
  • Lukitustiedosto itsessään on vain merkki; sen sisällöllä ei ole merkitystä. Tiedoston voi huoletta säilyttää suoritusten välillä.
  • Kun lukituksen omistava prosessi päättyy, ydin vapauttaa lukituksen automaattisesti — manuaalista siivousta ei tarvita.
#!/usr/bin/env bash
# launcher.sh — prevents concurrent runs of worker.sh
set -euo pipefail

LOCKFILE="/tmp/myworker.lock"

if ! flock -n "$LOCKFILE" bash -c 'echo "Running worker..."; sleep 2; echo "Done."'; then
    echo "Another instance is already running. Exiting." >&2
    exit 1
fi

flock-komento komentosarjan sisällä tiedostokuvaajaa käyttäen

Jos haluatte lukita komentosarjan sisältä sen sijaan, että kääritte sen ulkopuolelta, avatkaa tiedostokuvaaja komennolla exec ja kutsukaa sen jälkeen flock-komentoa kyseiselle kuvaajalle. Tätä idiomista mallia käytetään tuotantokäytössä olevissa komentosarjoissa.

  • exec 200>"$LOCKFILE" avaa tiedoston kirjoittamista varten tiedostokuvaajalle 200 ja luo tiedoston tarvittaessa.
  • flock -n 200 yrittää lukita tiedostokuvaajan 200 estämättä suoritusta.
  • Koska lukitus liittyy tiedostokuvaajaan (ei tiedoston nimeen), se vapautuu automaattisesti shell-prosessin päättyessä.
  • Tiedostokuvaajien numeroita 200–299 käytetään perinteisesti, jotta ne eivät sekoitu vakiosyötteeseen, -tulosteeseen tai -virhetulosteeseen.
#!/usr/bin/env bash
set -euo pipefail

LOCKFILE="/tmp/myjob.lock"

# Open lock file on FD 200
exec 200>"$LOCKFILE"

# Attempt non-blocking lock
if ! flock -n 200; then
    echo "ERROR: Another instance of this script is running." >&2
    exit 1
fi

echo "Lock acquired. Starting work..."
sleep 1
echo "Work complete. Lock will be released on exit."

mktemp- ja flock-komentojen yhdistäminen samassa komentosarjassa

Oikeasti puolustautuvissa komentosarjoissa tarvitaan molempia: lukitus estämään samanaikaiset suoritukset ja turvalliset väliaikaistiedostot väliaikaisia tietoja varten. Tässä on näiden tekniikoiden yhdistetty kokonaismalli:

  • Hankkikaa lukitus ensin — ennen väliaikaistiedostojen luomista — jotta vain yksi esiintymä tekee mitään työtä.
  • Luokaa väliaikaiset resurssit vasta, kun lukitus on varmistettu.
  • Rekisteröikää trap heti väliaikaisten resurssien luomisen jälkeen, jotta siivous tehdään varmasti riippumatta siitä, miten komentosarja päättyy.
  • Lukitustiedostoa ei koskaan sijoiteta väliaikaishakemistoon — sen on säilyttävä suoritusten välillä, jotta flock voi viitata siihen.
#!/usr/bin/env bash
set -euo pipefail

LOCKFILE="/tmp/report_builder.lock"
exec 200>"$LOCKFILE"

if ! flock -n 200; then
    echo "Already running — aborting." >&2
    exit 1
fi

# Now safe to create temp resources
TMPDIR=$(mktemp -d /tmp/report.XXXXXX)
TMPLOG=$(mktemp /tmp/report_log.XXXXXX)

cleanup() {
    rm -rf "${TMPDIR:-}"
    rm -f  "${TMPLOG:-}"
}
trap cleanup EXIT

echo "Building report in $TMPDIR" | tee "$TMPLOG"
echo "Step 1 complete"             >> "$TMPLOG"
cat "$TMPLOG"

Lukitushakemistot vaihtoehtoisena lukitusmekanismina

Järjestelmissä, joissa flock ei ole käytettävissä (esimerkiksi joissakin sulautetuissa järjestelmissä tai NFS:n kaltaisissa verkkotiedostojärjestelmissä), voitte käyttää lukitushakemistoja. mkdir on POSIX-järjestelmissä atominen: se onnistuu vain, jos hakemistoa ei ole ennestään.

  • Luokaa lukitushakemisto komennolla mkdir /tmp/myscript.lock.d — jos toinen esiintymä on jo luonut sen, mkdir epäonnistuu heti.
  • Tallentakaa hakemistoon vianmääritystä varten metatietoja, kuten PID.
  • Poistakaa hakemisto aina trap-käsittelijässä tapahtuman EXIT yhteydessä.
  • Varoitus: Toisin kuin flock-lukitus, hakemistolukitus EI vapaudu automaattisesti, jos prosessi lopetetaan valitsimella -9 tai kone käynnistyy uudelleen — lisätkää vanhentuneen lukituksen tunnistus.
#!/usr/bin/env bash
set -euo pipefail

LOCKDIR="/tmp/myscript.lock.d"

# Atomic mkdir — fails if directory already exists
if ! mkdir "$LOCKDIR" 2>/dev/null; then
    # Check if the holding PID is still alive
    HOLDER_PID=$(cat "$LOCKDIR/pid" 2>/dev/null || echo "")
    if [[ -n "$HOLDER_PID" ]] && kill -0 "$HOLDER_PID" 2>/dev/null; then
        echo "Locked by PID $HOLDER_PID. Exiting." >&2
        exit 1
    else
        echo "Stale lock detected. Removing and continuing." >&2
        rm -rf "$LOCKDIR"
        mkdir "$LOCKDIR"
    fi
fi

echo "$$" > "$LOCKDIR/pid"
trap 'rm -rf "$LOCKDIR"' EXIT

echo "Lock acquired via directory. Running..."
sleep 1
echo "Done."

Aikarajaan perustuva odotus flock-komennolla

Joskus haluatte odottaa lukitusta sen sijaan, että epäonnistuisitte heti — mutta ette kuitenkaan halua odottaa ikuisesti. flock tukee aikakatkaisua valitsimella -w.

  • flock -w 10 200 odottaa lukitusta enintään 10 sekuntia ja päättyy sen jälkeen tilakoodilla 1, jos lukitus ei edelleenkään ole saatavilla.
  • Tämä sopii erinomaisesti komentosarjoille, joiden pitäisi jonottaa lyhyen aikaa kestävän edeltäjän taakse mutta luovuttaa, jos edeltäjä juuttuu.
  • Yhdistäkää -w merkitykselliseen virheilmoitukseen, joka sisältää asiayhteyden — lukitustiedoston polun ja odotusajan — jotta ylläpitäjät voivat selvittää jumiutumiset nopeasti.
#!/usr/bin/env bash
set -euo pipefail

LOCKFILE="/tmp/data_sync.lock"
TIMEOUT=15

exec 200>"$LOCKFILE"

echo "Waiting up to ${TIMEOUT}s for lock on $LOCKFILE..."

if ! flock -w "$TIMEOUT" 200; then
    echo "ERROR: Could not acquire lock after ${TIMEOUT}s." \
         "Another instance may be hung." >&2
    exit 1
fi

echo "Lock acquired. Syncing data..."
sleep 1
echo "Sync complete."

Puolustautuvan ohjelmoinnin tarkistuslista: turvalliset väliaikaisresurssit

Käykää tämä tarkistuslista läpi ennen minkä tahansa väliaikaistiedostoja tai lukitusta käyttävän komentosarjan julkaisemista:

  • Käyttäkää mktemp-komentoa, älkää koskaan kovakoodattuja polkuja — /tmp/myapp.tmp on ennakoitava ja hyödynnettävissä.
  • Tallentakaa polku heti — TMPFILE=$(mktemp ...) ennen mitään muuta komentoa.
  • Rekisteröikää trap cleanup EXIT heti luomisen jälkeen — ei vasta komentosarjan lopussa.
  • Laittakaa kaikki muuttujien käytöt kaksoislainausmerkkeihin — rm -f "$TMPFILE", ei koskaan rm -f $TMPFILE.
  • Suosikaa flock-komentoa PID-tiedostojen sijaan — ydin hallinnoi lukitusta ja vapauttaa sen automaattisesti kaatumisen yhteydessä.
  • Käyttäkää oletusarvoisesti estämätöntä -n-valitsinta — hiljaiset odottavat lukitukset peittävät suorituskykyongelmat.
  • Sijoittakaa lukitustiedosto väliaikaishakemiston ulkopuolelle — jotta se säilyy siivouksen jälkeen.
  • Testatkaa siivouksen toiminta — suorittakaa komentosarja ja tappakaa se komennolla kill -9 kesken suorituksen; varmistakaa, ettei jäljelle jää tiedostoja (tämä koskee flock-pohjaisia komentosarjoja; hakemistolukitukset vaativat lisätoimia).

Tietotesti: flock-valitsinten toiminta

Cron-työ suoritetaan minuutin välein, ja se käsittelee jaettua tiedostoa. Haluatte, että uusi suoritus päättyy heti virheeseen, jos edellinen suoritus on vielä käynnissä, eikä jää odottamaan. Mikä flock-kutsu toteuttaa tämän oikein?

Kertaus: turvalliset väliaikaistiedostot ja lukitushakemistot

Tässä oppitunnissa opitte Bashin kaksi keskeistä työkalua resurssien puolustautuvaan hallintaan:

  • mktemp luo ennakoimattomia ja turvallisilla käyttöoikeuksilla varustettuja väliaikaistiedostoja (0600) ja -hakemistoja (0700), mikä poistaa kovakoodattuihin polkuihin liittyvät kilpailutilanteet ja symbolisten linkkien hyökkäykset.
  • trap cleanup EXIT varmistaa väliaikaistiedoston poistamisen kaikissa lopetustilanteissa — normaalin lopetuksen, virheen tai signaalin aiheuttaman lopetuksen yhteydessä — kun se rekisteröidään heti luomisen jälkeen.
  • flock tarjoaa ytimen pakottaman neuvoteltavan lukituksen: käyttäkää -n-valitsinta epäonnistumiseen heti kilpailutilanteessa, -w N -valitsinta aikarajattuun odotukseen ja exec 200>file-mallia komentosarjan sisäiseen lukitukseen, jonka ydin vapauttaa automaattisesti prosessin päättyessä.
  • Lukitushakemistot (mkdir) tarjoavat siirrettävän vararatkaisun ympäristöihin, joissa flock ei ole käytettävissä, mutta edellyttävät vanhentuneen lukituksen nimenomaista tunnistusta.
  • Pidättehän lukitustiedoston aina väliaikaishakemiston ulkopuolella ja käytätte kaksoislainausmerkkejä jokaisen siivouksessa käytettävän muuttujan ympärillä.

Yhdistämällä mktemp + flock + trap saatte komentosarjoja, jotka ovat suojattuja samanaikaisilta suorituksilta, ennakoimattomilta kaatumisilta ja vihamieliseltä tiedostojärjestelmän manipuloinnilta.

Aloita maksutta

Opi Bash tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
22
Oppitunnit
88

Usein kysytyt kysymykset

Onko oppitunti ”Turvalliset väliaikaistiedostot ja lukitushakemistot” ilmainen?

Kyllä – oppitunnin ”Turvalliset väliaikaistiedostot ja lukitushakemistot” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssin, päivitä CoddyKit PROhon. Linux-komentorivin ja Bash-komentosarjojen hallinta-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Turvalliset väliaikaistiedostot ja lukitushakemistot”?

Luo mktempilla ja flockilla kilpailutilanteilta suojattuja väliaikaisia resursseja ja estä skriptien samanaikaiset ajot. Harjoittelet Linux-komentorivin ja Bash-komentosarjojen hallinta-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Linux-komentorivin ja Bash-komentosarjojen hallinta-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Linux-komentorivin ja Bash-komentosarjojen hallinta-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Turvalliset väliaikaistiedostot ja lukitushakemistot”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunnilla?

Kyllä. Jokainen Linux-komentorivin ja Bash-komentosarjojen hallinta-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Tiukka tila komennolla set -euo pipefail
  2. Trap-käsittelijät siivousta ja signaaleja varten
  3. Turvalliset väliaikaistiedostot ja lukitushakemistot
  4. Idempotentit skriptit ja uudelleenyritys viiveen kasvaessa
← Takaisin: Linux-komentorivin ja Bash-komentosarjojen hallinta