Saya sedang mengerjakan skrip shell yang melakukan perubahan tertentu pada file txt hanya jika memang ada, namun loop pengujian ini tidak berfungsi, saya bertanya-tanya mengapa? Terima kasih!
Saya tidak bisa mengatakan bahwa saya terkejut; loop itu tidak mencoba mengubah apa pun.
Ignacio Vazquez-Abrams
Titik koma berlebihan. Dengan cara apa loop tes itu tidak berfungsi? Ini akan tidur berulang selama 2 detik sampai file /tmp/list.txt ada.
Jonathan Leffler
5
Bekerja untuk saya - loop berakhir ketika file dibuat di luar skrip.
1
Faktanya, loop ini hanya berfungsi untuk menunggu sampai file ada di sana, sisa skrip saya melakukan perubahan ...: p
Zenet
1
Kemudian loop sementara bekerja, hanya saya ... maaf.
Zenet
Jawaban:
149
Ketika Anda mengatakan "tidak berhasil", bagaimana Anda tahu itu tidak berhasil?
Anda dapat mencoba mencari tahu apakah file tersebut benar-benar ada dengan menambahkan:
while [ ! -f /tmp/list.txt ]
do
sleep 2 # or less like 0.2done
ls -l /tmp/list.txt
Anda juga dapat memastikan bahwa Anda menggunakan shell Bash (atau terkait) dengan mengetik 'echo $ SHELL'. Saya pikir CSH dan TCSH menggunakan semantik yang sedikit berbeda untuk loop ini.
Mengapa Anda menggunakan pemeriksaan file terbalik? Bukankah seharusnya sementara [-f /tmp/list.txt] digunakan?
valentt
2
@valentt Tidak ada loop hew yang mengatakan secara harfiah "sementara file NOT ada, lakukan tidur" .. jika Anda menghapus 'NOT' loop akan langsung putus
Kenyakorn Ketsombut
2
dalam 1 baris:while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
DrumM
55
Jika Anda menggunakan linux dan telah menginstal alat inotify, Anda dapat melakukan ini:
file=/tmp/list.txt
while [ ! -f "$file" ]
do
inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)"done
Ini mengurangi penundaan yang disebabkan oleh tidur sambil tetap mengumpulkan setiap "x" detik. Anda dapat menambahkan lebih banyak acara jika Anda mengantisipasinya diperlukan.
1 untuk efisiensi. Menyatukan dengan tidur itu jelek. Untuk orang-orang yang tidak mengetahui inotifywait - ada dalam paket inotify-tools.
Michał Šrajer
7
Itu alat yang sangat berguna. Bagi siapa pun yang bertanya-tanya mengapa loop, ini untuk menangani kemungkinan kondisi balapan antara pembuatan dan menunggu dan karena inotifywait harus --excludememfilter nama file, tetapi tidak --includemengabaikan semuanya kecuali nama file. Perintah di atas harus menggunakan -qqargumen daripada >&/dev/nullmeskipun.
Craig Ringer
t adalah --timeout, bukan frekuensi pemeriksaan, bukan? Inti dari inotifywait adalah bahwa tidak ada pemungutan suara
Alex Dean
1
@AlexDean Batas waktu adalah untuk mencegah kondisi balapan. Polling dengan tidur lambat karena loop tidak akan keluar selama tidur, tetapi inotifywait akan keluar sebelum batas waktu jika melihat suatu peristiwa.
yingted
1
@AlexDean Ya, tapi itu perlu untuk mencegah kondisi balapan TOCTTOU. Jika tidak, inotifywaitbisa hang tanpa batas jika file dibuat tepat sebelum mulai mendengarkan acara.
yingted
4
Saya memiliki masalah yang sama, letakkan! di luar tanda kurung;
while ! [ -f /tmp/list.txt ];
doecho"#"
sleep 1
done
Juga, jika Anda menambahkan gema di dalam loop, itu akan memberi tahu Anda apakah Anda masuk ke dalam loop atau tidak.
Saya mengalami masalah serupa dan itu membawa saya ke sini jadi saya hanya ingin meninggalkan solusi saya untuk siapa saja yang mengalami hal yang sama.
Saya menemukan bahwa jika saya menjalankan cat /tmp/list.txtfile tersebut akan kosong, meskipun saya yakin ada konten yang langsung ditempatkan di file. Ternyata jika saya meletakkan sleep 1;sebelum cat /tmp/list.txtitu bekerja seperti yang diharapkan. Pasti ada penundaan antara waktu file dibuat dan waktu itu ditulis, atau sesuatu seperti itu.
Kode terakhir saya:
while [ ! -f /tmp/list.txt ];
do
sleep 1;
done;
sleep 1;
cat /tmp/list.txt;
Semoga ini membantu menyelamatkan seseorang dari setengah jam yang membuat frustrasi!
Seperti @zane-hooper, saya mengalami masalah serupa di NFS. Pada filesystem paralel / terdistribusi, jeda antara Anda membuat file di satu mesin dan mesin lain "melihat" itu bisa sangat besar, jadi saya bisa menunggu hingga satu menit penuh setelah pembuatan file sebelum while loop keluar (dan ada juga efek sampingnya "melihat" file yang sudah dihapus).
Ini menciptakan ilusi bahwa skrip "tidak berfungsi" , padahal sebenarnya itu adalah sistem file yang menjatuhkan bola.
Ini membutuhkan waktu beberapa saat bagi saya untuk memikirkannya, semoga dapat menghemat waktu seseorang.
PS Ini juga menyebabkan sejumlah kesalahan "Stale file handler" yang mengganggu.
Berikut adalah versi dengan batas waktu sehingga setelah beberapa waktu pengulangan berakhir dengan kesalahan:
# After 60 seconds the loop will exit
timeout=60
while [ ! -f /tmp/list.txt ];
do# When the timeout is equal to zero, show an error and leave the loop.if [ "$timeout" == 0 ]; thenecho"ERROR: Timeout while waiting for the file /tmp/list.txt."exit 1
fi
sleep 1
# Decrease the timeout of one
((timeout--))
done
Jawaban:
Ketika Anda mengatakan "tidak berhasil", bagaimana Anda tahu itu tidak berhasil?
Anda dapat mencoba mencari tahu apakah file tersebut benar-benar ada dengan menambahkan:
while [ ! -f /tmp/list.txt ] do sleep 2 # or less like 0.2 done ls -l /tmp/list.txt
Anda juga dapat memastikan bahwa Anda menggunakan shell Bash (atau terkait) dengan mengetik 'echo $ SHELL'. Saya pikir CSH dan TCSH menggunakan semantik yang sedikit berbeda untuk loop ini.
sumber
while [ ! -f /tmp/list.txt ]; do sleep 2; done; ls -l /tmp/list.txt
Jika Anda menggunakan linux dan telah menginstal alat inotify, Anda dapat melakukan ini:
file=/tmp/list.txt while [ ! -f "$file" ] do inotifywait -qqt 2 -e create -e moved_to "$(dirname $file)" done
Ini mengurangi penundaan yang disebabkan oleh tidur sambil tetap mengumpulkan setiap "x" detik. Anda dapat menambahkan lebih banyak acara jika Anda mengantisipasinya diperlukan.
sumber
--exclude
memfilter nama file, tetapi tidak--include
mengabaikan semuanya kecuali nama file. Perintah di atas harus menggunakan-qq
argumen daripada>&/dev/null
meskipun.--timeout
, bukan frekuensi pemeriksaan, bukan? Inti dari inotifywait adalah bahwa tidak ada pemungutan suarainotifywait
bisa hang tanpa batas jika file dibuat tepat sebelum mulai mendengarkan acara.Saya memiliki masalah yang sama, letakkan! di luar tanda kurung;
while ! [ -f /tmp/list.txt ]; do echo "#" sleep 1 done
Juga, jika Anda menambahkan gema di dalam loop, itu akan memberi tahu Anda apakah Anda masuk ke dalam loop atau tidak.
sumber
Saya mengalami masalah serupa dan itu membawa saya ke sini jadi saya hanya ingin meninggalkan solusi saya untuk siapa saja yang mengalami hal yang sama.
Saya menemukan bahwa jika saya menjalankan
cat /tmp/list.txt
file tersebut akan kosong, meskipun saya yakin ada konten yang langsung ditempatkan di file. Ternyata jika saya meletakkansleep 1;
sebelumcat /tmp/list.txt
itu bekerja seperti yang diharapkan. Pasti ada penundaan antara waktu file dibuat dan waktu itu ditulis, atau sesuatu seperti itu.Kode terakhir saya:
while [ ! -f /tmp/list.txt ]; do sleep 1; done; sleep 1; cat /tmp/list.txt;
Semoga ini membantu menyelamatkan seseorang dari setengah jam yang membuat frustrasi!
sumber
Seperti @zane-hooper, saya mengalami masalah serupa di NFS. Pada filesystem paralel / terdistribusi, jeda antara Anda membuat file di satu mesin dan mesin lain "melihat" itu bisa sangat besar, jadi saya bisa menunggu hingga satu menit penuh setelah pembuatan file sebelum while loop keluar (dan ada juga efek sampingnya "melihat" file yang sudah dihapus).
Ini menciptakan ilusi bahwa skrip "tidak berfungsi" , padahal sebenarnya itu adalah sistem file yang menjatuhkan bola.
Ini membutuhkan waktu beberapa saat bagi saya untuk memikirkannya, semoga dapat menghemat waktu seseorang.
PS Ini juga menyebabkan sejumlah kesalahan "Stale file handler" yang mengganggu.
sumber
bekerja dengan bash dan sh keduanya:
touch /tmp/testfile sleep 10 && rm /tmp/testfile & until ! [ -f /tmp/testfile ] do echo "testfile still exist..." sleep 1 done echo "now testfile is deleted.."
sumber
Berikut adalah versi dengan batas waktu sehingga setelah beberapa waktu pengulangan berakhir dengan kesalahan:
# After 60 seconds the loop will exit timeout=60 while [ ! -f /tmp/list.txt ]; do # When the timeout is equal to zero, show an error and leave the loop. if [ "$timeout" == 0 ]; then echo "ERROR: Timeout while waiting for the file /tmp/list.txt." exit 1 fi sleep 1 # Decrease the timeout of one ((timeout--)) done
sumber
lakukan seperti ini
while true do [ -f /tmp/list.txt ] && break sleep 2 done ls -l /tmp/list.txt
sumber