Saya mencoba untuk menulis skrip shell yang akan menunggu file muncul di /tmp
direktori bernama sleep.txt
dan setelah ditemukan program akan berhenti, jika tidak saya ingin program berada dalam keadaan tertidur (ditangguhkan) sampai file tersebut ditemukan . Sekarang, saya berasumsi bahwa saya akan menggunakan perintah uji. Jadi, kira-kira seperti itu
(if [ -f "/tmp/sleep.txt" ];
then stop
else sleep.)
Saya baru menulis skrip shell dan bantuan apa pun sangat dihargai!
shell-script
files
Mo Gainz
sumber
sumber
$MAILPATH
.Jawaban:
Di Linux, Anda dapat menggunakan subsistem kernel inotify untuk secara efisien menunggu penampilan file dalam direktori:
(dengan asumsi Bash untuk
<()
sintaks redirection output)Keuntungan dari pendekatan ini dibandingkan dengan polling interval waktu tetap seperti di
adalah bahwa kernel lebih banyak tidur. Dengan spesifikasi peristiwa yang tidak sah seperti
create,open
skrip hanya dijadwalkan untuk dieksekusi ketika file di bawah/tmp
dibuat atau dibuka. Dengan polling interval waktu yang tetap Anda membuang siklus CPU untuk setiap kenaikan waktu.Saya menyertakan
open
acara untuk juga mendaftartouch /tmp/sleep.txt
ketika file sudah ada.sumber
inotifywait -e create,open --format '%f' --quiet /tmp/sleep.txt --monitor > /dev/null ; # continues once /tmp/sleep.txt is created/opened
?inotifywait
itu sendiri adalah loop sementara, dan menghasilkan garis setiap kali file dibuka / dibuat. Jadi Anda perlu loop sementara untuk memecah ketika itu diubah.sleep.txt
pada suatu titik waktu. Dengan demikian, tidak ada kondisi balapan. Pertanyaan itu tidak mengandung apa pun yang mengisyaratkan skenario yang ada dalam pikiran Anda.Cukup letakkan tes Anda di
while
loop:sumber
sleep
adalah jumlah detik untuk menunggu di setiap iterasi - Anda dapat mengubahnya tergantung pada kebutuhan Anda.Ada beberapa masalah dengan beberapa
inotifywait
pendekatan berbasis yang diberikan sejauh ini:sleep.txt
file yang telah dibuat pertama sebagai nama sementara dan kemudian diganti namanya menjadisleep.txt
. Satu harus mencocokkan untukmoved_to
acara di sampingcreate
sleep.txt
telah dibuat. Bagaimana jikafoo\nsleep.txt\nbar
file telah dibuat misalnya?inotifywait
dimulai dan menginstal arloji? Makainotifywait
akan menunggu selamanya untuk file yang sudah ada di sini. Anda harus memastikan file belum ada di sana setelah arloji diinstal.inotifywait
berjalan (setidaknya sampai file lain dibuat) setelah file ditemukan.Untuk mengatasinya, Anda bisa melakukan:
Perhatikan bahwa kami sedang mengawasi pembuatan
sleep.txt
di direktori saat ini,.
(jadi Anda akan melakukancd /tmp || exit
sebelumnya dalam contoh Anda). Direktori saat ini tidak pernah berubah, jadi ketika saluran pipa itu kembali dengan sukses, itu adalahsleep.txt
di direktori saat ini yang telah dibuat.Tentu saja, Anda dapat menggantinya
.
dengan yang di/tmp
atas, tetapi ketikainotifywait
sedang berjalan,/tmp
bisa saja dinamai ulang beberapa kali (tidak mungkin untuk/tmp
, tetapi sesuatu untuk dipertimbangkan dalam kasus umum) atau sistem file baru yang dipasang di atasnya, jadi ketika pipa kembali, mungkin tidak menjadi/tmp/sleep.txt
yang telah dibuat tetapi/new-name-for-the-original-tmp/sleep.txt
sebaliknya./tmp
Direktori baru juga bisa dibuat dalam interval dan yang tidak akan ditonton, jadi yangsleep.txt
dibuat di sana tidak akan terdeteksi.sumber
Jawaban yang diterima benar-benar berfungsi (terima kasih maxschlepzig) tetapi membiarkan pemantauan inotifywait di latar belakang hingga skrip Anda keluar. Satu-satunya jawaban yang cocok persis dengan kebutuhan Anda (yaitu menunggu sleep.txt muncul di dalam / tmp) tampaknya adalah milik Stephane, jika direktori yang akan dimonitor oleh inotifywait diubah dari titik (.) Ke '/ tmp'.
Namun, jika Anda bersedia menggunakan direktori sementara SAJA untuk meletakkan flag sleep.txt Anda dan dapat bertaruh bahwa tidak ada orang lain yang akan meletakkan file apa pun di direktori itu, cukup meminta inotifyunggu untuk menonton direktori ini karena kreasi file sudah cukup:
Langkah 1: buat direktori yang akan Anda pantau:
Langkah 2: pastikan direktori benar-benar ada
Langkah 3: tunggu sampai file APA SAJA muncul di dalamnya
$directoryToPutSleepFile
File yang Anda masukkan
$directoryToPutSleepFile
dapat dinamai sleep.txt awake.txt, apa pun. Saat file apa pun dibuat di dalam$directoryToPutSleepFile
skrip Anda akan terus melewatiinotifywait
pernyataan.sumber
sleep.txt
dibuat di antara dua inotifyunggu permintaan.sleep.txt
dibuat. Coba misalnyatouch /tmp/foo /tmp/sleep.txt
, maka satu instanceinotifywait
akan melaporkanfoo
dan keluar, dan pada saat inotifywait berikutnya dimulai, sleep.txt sudah lama ada di sana sehingga inotifywait tidak akan mendeteksi pembuatannya.secara umum sangat sulit untuk membuat apa pun kecuali tes sederhana / loop tidur dapat diandalkan. Masalah utama adalah bahwa tes akan berpacu dengan pembuatan file - kecuali tes diulang, acara buat bisa dilewatkan. Sejauh ini, inilah taruhan terbaik Anda dalam sebagian besar kasus di mana Anda akan menggunakan Shell:
Jika Anda merasa ini tidak cukup karena masalah kinerja, maka menggunakan Shell mungkin bukan ide yang bagus.
sumber
Berdasarkan jawaban yang diterima dari maxschlepzig (dan sebuah ide dari jawaban yang diterima di /superuser/270529/monitoring-a-file-until-a-string-is-found ) Saya mengusulkan yang berikut ditingkatkan ( dalam pandangan saya) jawaban yang juga bisa berfungsi dengan batas waktu:
Jika file tidak dibuat / dibuka dalam batas waktu yang diberikan, maka status keluar adalah 124 (sesuai dokumentasi batas waktu (halaman manual)). Jika itu dibuat / dibuka, maka status keluar adalah 0 (berhasil).
Ya, inotifywait berjalan dalam sub-shell dengan cara ini dan sub-shell itu hanya akan selesai berjalan ketika batas waktu terjadi atau ketika skrip utama keluar (mana yang lebih dulu).
sumber