File Sementara yang Aman dan Direktori Kunci
Gunakan mktemp dan flock untuk membuat resource sementara tanpa kondisi balapan serta mencegah skrip berjalan secara bersamaan.
File Sementara yang Aman dan Direktori Kunci adalah pelajaran Linux Command Line & Bash Scripting Mastery gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Linux Command Line & Bash Scripting Mastery, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Mengapa Berkas Sementara Berisiko bagi Keamanan
Skrip Bash sering memerlukan penyimpanan sementara — hasil antara, penanda kunci, dan area penahapan. Namun, membuat berkas sementara secara sembarangan dapat membuka kerentanan serius.
- Kondisi perlombaan: Proses lain dapat menebak nama berkas Anda dan membuat berkas tersebut lebih dahulu, sehingga mengalihkan penulisan Anda.
- Serangan tautan simbolis: Penyerang membuat tautan simbolis di jalur yang Anda harapkan, yang mengarah ke berkas sensitif seperti
/etc/passwd. - Berkas tersisa: Jika skrip mogok, berkas sementara akan menumpuk dan dapat membocorkan data sensitif.
Dua alat utama yang menghilangkan masalah ini adalah mktemp dan flock. Pelajaran ini menunjukkan cara menggunakan keduanya dengan aman dan defensif.
Membuat Berkas Sementara yang Aman dengan mktemp
mktemp membuat berkas sementara dengan nama acak yang sulit ditebak dan mengembalikan jalurnya. Perintah ini membuat berkas secara atomik, sehingga tidak ada proses lain yang dapat mengambil nama tersebut lebih dahulu.
- Sintaks:
mktemp [TEMPLATE]— templat harus diakhiri setidaknya oleh tiga karakterX. - Setiap
Xdiganti dengan karakter acak, sehingga menghasilkan nama unik seperti/tmp/script.aB3kQz. - Berkas secara otomatis dibuat dengan izin
0600(hanya dapat dibaca oleh pemiliknya).
Selalu simpan jalur yang dikembalikan ke dalam variabel segera agar Anda dapat menggunakannya dan membersihkannya nanti.
#!/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"Selalu Bersihkan dengan trap
Jika skrip Anda keluar secara tidak terduga — karena kesalahan, sinyal, atau pemicu set -e — berkas sementara akan tertinggal kecuali Anda mendaftarkan penangan pembersihan.
Perintah bawaan trap menjalankan perintah saat shell menerima sinyal atau keluar. Pola baku untuk membersihkan berkas sementara adalah:
- Daftarkan perangkap segera setelah membuat berkas sementara.
- Gunakan perangkap pada
EXITagar pembersihan berjalan saat keluar secara normal maupun tidak normal. - Gunakan juga perangkap
INTdanTERMjika skrip berjalan lama atau bersifat interaktif.
Dengan demikian, tidak ada berkas yatim yang tertinggal, bahkan jika skrip dihentikan di tengah eksekusi.
#!/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."Membuat Direktori Sementara dengan mktemp -d
Terkadang Anda memerlukan seluruh direktori untuk menampung beberapa berkas sementara—misalnya, saat membuat arsip atau mengekstrak tarball sebelum memprosesnya. Gunakan mktemp -d untuk membuat direktori sementara yang aman.
- Direktori dibuat dengan izin
0700(hanya pemilik yang dapat mengaksesnya). - Lakukan pembersihan dengan
rm -rfdi dalam trap Anda—pastikan hanya menghapus variabel, bukan jalur yang ditulis secara langsung. - Gunakan tanda kutip ganda dan pastikan variabel tidak kosong sebelum memanggil
rm -rfsebagai pemeriksaan keamanan tambahan.
#!/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."Masalah Eksekusi Skrip Secara Bersamaan
Pekerjaan Cron, pengatur waktu systemd, dan skrip yang dipicu secara manual dapat dengan mudah meluncurkan beberapa instans skrip yang sama secara bersamaan. Hal ini menyebabkan:
- Pemrosesan duplikat: Catatan basis data atau berkas yang sama diproses dua kali.
- Keluaran rusak: Dua instans menulis ke berkas keluaran yang sama secara bersamaan.
- Kebuntuan atau keadaan parsial: Kedua instans mengubah sumber daya bersama dalam urutan yang saling terselip dan tidak dapat diprediksi.
Perbaikan tradisionalnya adalah menulis berkas PID dan memeriksanya saat memulai—tetapi pendekatan ini memiliki celah perlombaan antara pemeriksaan dan penulisan. Solusi modern yang tepat adalah flock, yang menggunakan mekanisme penguncian penasihat dari kernel untuk mendapatkan kunci yang bebas dari kondisi perlombaan.
Penguncian dengan flock: Pola Satu Baris
flock memperoleh kunci penasihat pada deskriptor berkas sebelum menjalankan perintah. Penggunaan paling sederhana membungkus seluruh skrip Anda dari baris perintah:
flock -n /var/lock/myscript.lock bash myscript.sh
-n(tidak memblokir): langsung keluar dengan status 1 jika kunci sudah digunakan, alih-alih menunggu.- Tanpa
-n,flockmemblokir hingga kunci tersedia—berguna untuk membuat antrean. - Berkas kunci itu sendiri hanya penanda; isinya tidak penting. Berkas tersebut aman untuk dipertahankan di antara eksekusi.
- Saat proses yang memegang kunci keluar, kernel secara otomatis melepaskan kunci tersebut—tidak diperlukan pembersihan manual.
#!/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
fiflock di Dalam Skrip Menggunakan Deskriptor Berkas
Untuk melakukan penguncian di dalam skrip, bukan membungkusnya dari luar, gunakan exec untuk membuka deskriptor berkas, lalu panggil flock pada deskriptor tersebut. Ini adalah pola idiomatis yang digunakan dalam skrip produksi.
exec 200>"$LOCKFILE"membuka berkas pada deskriptor 200 untuk ditulis (dan membuatnya jika diperlukan).flock -n 200mencoba mengunci deskriptor 200 tanpa memblokir.- Karena kunci terikat pada deskriptor berkas (bukan nama berkas), kunci tersebut dilepaskan secara otomatis saat proses shell keluar.
- Nomor deskriptor 200–299 secara konvensional digunakan agar tidak berbenturan dengan stdin/stdout/stderr.
#!/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."Menggabungkan mktemp dan flock dalam Satu Skrip
Skrip defensif nyata memerlukan keduanya: kunci untuk mencegah eksekusi bersamaan dan berkas sementara yang aman untuk data perantara. Berikut pola lengkap yang menggabungkan kedua teknik tersebut:
- Dapatkan kunci terlebih dahulu—sebelum membuat berkas sementara apa pun—agar hanya satu instans yang melakukan pekerjaan.
- Buat sumber daya sementara setelah kunci dipastikan diperoleh.
- Daftarkan
trapsegera setelah membuat sumber daya sementara agar pembersihan tetap terjamin, apa pun cara skrip keluar. - Berkas kunci tidak pernah diletakkan di direktori sementara—berkas tersebut harus tetap ada di antara eksekusi agar dapat dirujuk oleh
flock.
#!/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"Direktori Kunci sebagai Mekanisme Kunci Alternatif
Pada sistem yang tidak menyediakan flock (seperti beberapa sistem tertanam atau sistem berkas jaringan seperti NFS), Anda dapat menggunakan direktori kunci sebagai gantinya. mkdir bersifat atomik pada sistem POSIX: perintah ini hanya berhasil jika direktori tersebut belum ada.
- Buat direktori kunci dengan
mkdir /tmp/myscript.lock.d—jika instans lain sudah membuatnya,mkdirlangsung gagal. - Simpan metadata (seperti PID) di dalam direktori untuk keperluan diagnosis.
- Selalu hapus direktori tersebut dalam
trappadaEXIT. - Catatan: Berbeda dari
flock, kunci direktori TIDAK dilepaskan secara otomatis jika proses dihentikan dengan-9atau mesin melakukan boot ulang—tambahkan pemeriksaan untuk mendeteksi kunci yang tersisa.
#!/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."Menunggu dengan Batas Waktu Menggunakan flock
Terkadang Anda ingin menunggu kunci, bukan langsung gagal—tetapi tidak ingin menunggu selamanya. flock mendukung batas waktu dengan opsi -w.
flock -w 10 200menunggu kunci hingga 10 detik, lalu keluar dengan status 1 jika kunci masih tidak tersedia.- Ini ideal untuk skrip yang harus mengantre setelah proses sebelumnya yang berlangsung singkat, tetapi menyerah jika proses sebelumnya macet.
- Gabungkan
-wdengan pesan kesalahan yang bermakna dan menyertakan konteks—jalur berkas kunci serta lama waktu Anda menunggu—agar operator dapat mendiagnosis kemacetan dengan cepat.
#!/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."Daftar Periksa Defensif: Sumber Daya Sementara yang Aman
Sebelum merilis skrip apa pun yang menggunakan berkas sementara atau penguncian, periksa daftar berikut:
- Gunakan
mktemp, jangan pernah menggunakan jalur yang ditulis langsung—/tmp/myapp.tmpdapat diprediksi dan dieksploitasi. - Simpan jalur segera—
TMPFILE=$(mktemp ...)sebelum perintah lain apa pun. - Daftarkan
trap cleanup EXITsegera setelah pembuatan—bukan di akhir skrip. - Gunakan tanda kutip ganda pada semua penggunaan variabel—
rm -f "$TMPFILE", jangan pernahrm -f $TMPFILE. - Utamakan
flockdaripada berkas PID—dikelola kernel dan dilepaskan secara otomatis saat terjadi kerusakan. - Gunakan
-ntanpa pemblokiran secara bawaan—kunci yang memblokir secara diam-diam dapat menyembunyikan masalah kinerja. - Letakkan berkas kunci di luar direktori sementara—agar tetap ada setelah trap pembersihan dijalankan.
- Uji perilaku pembersihan—jalankan skrip lalu gunakan
kill -9untuk menghentikannya di tengah eksekusi; pastikan tidak ada berkas tersisa (untuk skrip berbasisflock; kunci direktori memerlukan penanganan tambahan).
Pemeriksaan Pengetahuan: Perilaku Opsi flock
Sebuah pekerjaan Cron berjalan setiap menit dan memproses berkas bersama. Anda ingin setiap pemanggilan baru langsung keluar dengan kesalahan jika eksekusi sebelumnya masih aktif, tanpa menunggu. Pemanggilan flock mana yang menerapkan hal ini dengan benar?
Ringkasan: Berkas Sementara yang Aman dan Direktori Kunci
Dalam pelajaran ini, Anda mempelajari dua alat penting untuk pengelolaan sumber daya defensif di Bash:
mktempmembuat berkas sementara dengan izin yang tidak dapat diprediksi dan aman (0600) serta direktori (0700), sehingga menghilangkan kondisi perlombaan dan serangan tautan simbolis yang sering terjadi pada jalur yang ditulis langsung.trap cleanup EXITmenjamin penghapusan berkas sementara saat keluar dengan cara apa pun—normal, dipicu kesalahan, atau dipicu sinyal—jika didaftarkan segera setelah pembuatan.flockmenyediakan penguncian penasihat yang diberlakukan kernel: gunakan-nuntuk segera gagal saat terjadi perebutan kunci,-w Nuntuk menunggu dengan batas waktu, dan polaexec 200>fileuntuk penguncian di dalam skrip yang dilepaskan kernel secara otomatis saat proses keluar.- Direktori kunci (
mkdir) menyediakan cadangan portabel untuk lingkungan yang tidak menyediakanflock, tetapi memerlukan deteksi eksplisit terhadap kunci yang tersisa. - Selalu simpan berkas kunci di luar direktori sementara dan gunakan tanda kutip ganda pada setiap variabel yang digunakan dalam pembersihan.
Menggabungkan mktemp + flock + trap menghasilkan skrip yang aman terhadap pemanggilan bersamaan, kerusakan tak terduga, dan manipulasi sistem berkas oleh pihak yang berniat jahat.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “File Sementara yang Aman dan Direktori Kunci” gratis?
Ya — teks lengkap “File Sementara yang Aman dan Direktori Kunci” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Linux Command Line & Bash Scripting Mastery, upgrade ke CoddyKit PRO. Kursus Linux Command Line & Bash Scripting Mastery mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “File Sementara yang Aman dan Direktori Kunci”?
Gunakan mktemp dan flock untuk membuat resource sementara tanpa kondisi balapan serta mencegah skrip berjalan secara bersamaan. Kamu berlatih Linux Command Line & Bash Scripting Mastery dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Linux Command Line & Bash Scripting Mastery?
Tidak diperlukan pengalaman sebelumnya. Linux Command Line & Bash Scripting Mastery di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “File Sementara yang Aman dan Direktori Kunci” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Linux Command Line & Bash Scripting Mastery ini?
Ya. Setiap pelajaran Linux Command Line & Bash Scripting Mastery menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Mode Ketat dengan set -euo pipefail
- Penangan Trap untuk Pembersihan dan Sinyal
- File Sementara yang Aman dan Direktori Kunci
- Skrip Idempoten dan Logika Percobaan Ulang dengan Backoff