- Saat melakukan percobaan koneksi berulang untuk memeriksa status server web dalam skrip Bash, bisa muncul masalah ketika server secara tak terduga masuk ke loop tak terbatas
timeout, alat untuk mengatasi hal ini, menetapkan batas waktu eksekusi perintah dan saat terlampaui akan mengirim sinyal untuk mencoba menghentikan proses
- Karena tidak bisa diterapkan langsung pada shell built-in seperti
until, hal ini dapat diatasi dengan membungkus proses bash atau memisahkan skrip
Menunggu server web di skrip Bash dan masalah loop tak terbatas
- Dalam praktik, skrip Bash digunakan untuk menyiapkan server web dan memeriksa statusnya
- Strukturnya menunda pekerjaan berikutnya sampai server aktif, dan pada dasarnya berjalan tanpa masalah
- Namun, jika terjadi crash saat server sedang memulai, skrip bisa masuk ke loop tak terbatas sehingga perlu solusi
Contoh penggunaan until dan keterbatasannya
Pengenalan utilitas timeout
- Perintah
timeout akan menghentikan perintah dengan mengirim sinyal (SIGTERM dan sebagainya) jika tidak selesai dalam waktu yang ditentukan
- Contoh: pada
timeout 1s sleep 5, setelah 1 detik akan dicoba menghentikan proses sleep
- Saat dihentikan, perintah mengembalikan kode keluar abnormal (misalnya 124)
Upaya menggabungkan timeout dan until serta masalahnya
Solusi: membungkus proses Bash atau memakai skrip eksternal
1 komentar
Komentar Hacker News
Trik yang paling saya sukai dan kurang dikenal adalah penggunaan fault injection
straceuntuk menguji kegagalan berbagai system callPenjelasan lebih rinci tersedia di tautan terkait
Ada yang berbagi pengalaman bahwa fitur ini benar-benar menakjubkan dan berharap sudah mengetahuinya sejak dulu
Karena tidak ada cara untuk menguji cabang kegagalan, ia biasa mengganti sebagian fungsi dengan kode sementara, tetapi dengan trik ini pendekatannya bisa jauh lebih ringkas
Ada pendapat bahwa cara ini tampak sangat berguna
Juga muncul rasa penasaran apakah ada fitur serupa di Windows
Untuk health check layanan, ada usulan bahwa cara terbaik adalah menetapkan baik waktu timeout maksimum maupun jumlah retry maksimum
Biasanya mencoba retry sampai X kali, lalu memutuskan gagal jika belum berhasil dalam maksimal Y waktu
Ditekankan perlunya memutuskan kegagalan secepat mungkin alih-alih menunggu terlalu lama
Pada layanan yang standar, health check baru dimulai setelah dependensi kontainer benar-benar terjamin dan siap beroperasi
Di Kubernetes lihat Init Container, di AWS ECS lihat
dependsOn, dan di Docker Compose lihat pengaturandepends_onDisertakan contoh skrip shell POSIX
Namun disebutkan bahwa
curlsendiri sudah memiliki fitur seperti ini, jadi bisa dipakai tanpa skrip tambahan seperti di bawahAda yang berbagi pengalaman mencoba berbagai cara untuk membuat timeout hanya dengan builtin bash karena perintah
timeouttidak tersedia secara bawaan di MacDijelaskan bahwa perintah
sleepadalah standar POSIX sehingga bisa digunakanDisertakan contoh implementasi fitur timeout seperti berikut
Timeout ditangani dengan fungsi bernama
times_upJuga diberikan contoh pengujian dengan timeout 10 detik dan perulangan
forsebanyak 20 kaliAda yang berbagi pengalaman pernah membuat cara serupa 12 tahun lalu mengikuti saran di Stack Overflow
Detailnya bisa dilihat di tautan referensi
Ditekankan bahwa hanya shell builtins dan
sleepyang digunakan, dan kode tersebut wajib kompatibel dengan POSIXDisebutkan bahwa sintaks bash
{1..20}pada contoh bukan bagian dari POSIX sehingga perlu diperhatikanPerbaikan yang ia buat adalah mengembalikan
truejika timeout tidak terjadi, danfalsejika timeout terjadi, sehingga penanganan error dalam skrip menjadi lebih sederhanaDibagikan juga cara yang sangat sederhana seperti di bawah, yaitu menjalankan perintah dan
sleepsecara paralel lalu menghentikan perintah dengan sinyal setelah waktu yang ditentukanAda yang membagikan contoh skrip dari 13 tahun lalu yang mengimplementasikan timeout menggunakan
read -tTautan
Dijelaskan bahwa
curlsudah memiliki flag--retry-connrefused, sehingga fungsi ini bisa langsung dimanfaatkan tanpa loop shellJika perlu meneruskan variabel saat menggunakan
bash -c, disarankan menambahkan argumen seperti berikutDijelaskan alasan penggunaan
"--"dan peranargv[0]Disebutkan juga bahwa
printf %qbisa dipakai, tetapi pendekatan yang kompatibel dengan Bourne lebih disukaiDijelaskan bahwa
"--"memiliki makna yang sangat jelas sebagai penanda akhir opsi di bash dan sebagian besar CLI Unix/LinuxReferensi terkait
Dibagikan bahwa Busybox menentukan program yang akan dijalankan berdasarkan nilai
argv[0], sehingga bisa diisi dengan perintah yang diinginkan sepertils,mv, ataucpSaat membutuhkan logika retry, cara yang paling sering dipakai adalah seperti di bawah ini
Memang tidak terlalu elegan, tetapi umumnya akurat, dan pada tahap yang lebih lanjut bisa diterapkan exponential backoff
Disebutkan juga ada keuntungan dari sisi skalabilitas
shellcheckmerekomendasikan penanganan kasus ini dengan menggunakan variabel_Tautan referensi
Ditekankan bahwa fungsi
eventually_succeedsmungkin tetap memerlukan timeout atau defensive coding tambahan tergantung situasinyaIni sekaligus mengingatkan pentingnya selalu menulis kode yang defensif dalam konteks POSIX/proses/IO
Ada yang berbagi pengalaman bahwa saat anak-anaknya masih kecil, ia pernah memakai perintah berikut sebagai semacam parental control agar mereka hanya bisa menonton satu program selama 30 menit
Ide tersebut dinilai sangat berguna dalam praktik
Ada yang menyebut dirinya kurang menyukai penggunaan perintah inline atau file skrip sementara ketika harus mengirim sinyal ke subproses
Cara yang lebih disukai adalah membuat logika kompleks yang diinginkan sebagai fungsi, mengekspornya, lalu membungkusnya dengan
timeout bash -cIni terkait dengan cara aman meneruskan argumen yang disebutkan oleh aidenn0
"$@"wajib ditulis di bagian akhirJika tidak, argumen yang mengandung spasi tidak akan diteruskan dengan benar
Dibagikan juga contoh
long_fnyang bisa dipakai untuk memverifikasi hal iniAda yang mengingat kembali posting blog lama yang pernah membahas
timeoutJika ingin tahu lebih jauh tentang bahasa pemrograman umum atau cara kerja internalnya, bukan hanya shell, disarankan membaca blog terkait
Dibagikan pengalaman menambahkan command timeout dalam setup Kubernetes
Disebutkan bahwa skrip shell POSIX seperti
await-cmd.sh,await-http.sh, danawait-tcp.shsudah cukup matang dan bisa sangat berguna dalam situasi tertentuTautan proyek terkait