GNU/Linux >> Belajar Linux >  >> Linux

Bash:tidur tak terbatas (pemblokiran tak terbatas)

tail tidak memblokir

Seperti biasa:Untuk segala sesuatu ada jawaban yang singkat, mudah dimengerti, mudah diikuti dan benar-benar salah. Ini tail -f /dev/null termasuk dalam kategori ini;)

Jika Anda melihatnya dengan strace tail -f /dev/null Anda akan melihat, bahwa solusi ini jauh dari pemblokiran! Mungkin bahkan lebih buruk daripada sleep solusi dalam pertanyaan, karena menggunakan (di Linux) sumber daya berharga seperti inotify sistem. Juga proses lain yang menulis ke /dev/null buat tail lingkaran. (Di Ubuntu64 16.10 saya ini menambahkan beberapa 10 syscalls per detik pada sistem yang sudah sibuk.)

Pertanyaannya adalah untuk perintah pemblokiran

Sayangnya, tidak ada hal seperti itu ..

Baca:Saya tidak tahu cara untuk mengarsipkan ini dengan shell secara langsung.

Semuanya (bahkan sleep infinity ) dapat terganggu oleh beberapa sinyal. Jadi jika Anda ingin benar-benar yakin itu tidak kembali secara luar biasa, itu harus berjalan dalam satu lingkaran, seperti yang sudah Anda lakukan untuk sleep Anda . Perlu diketahui, bahwa (di Linux) /bin/sleep tampaknya dibatasi selama 24 hari (lihat strace sleep infinity ), maka hal terbaik yang dapat Anda lakukan mungkin adalah:

while :; do sleep 2073600; done

(Perhatikan bahwa saya percaya sleep loop secara internal untuk nilai yang lebih tinggi dari 24 hari, tetapi ini berarti:Ini tidak memblokir, ini sangat lambat. Jadi mengapa tidak memindahkan lingkaran ini ke luar?)

.. tetapi Anda bisa datang cukup dekat dengan fifo yang tidak disebutkan namanya

Anda dapat membuat sesuatu yang benar-benar memblokir selama tidak ada sinyal yang dikirimkan ke proses. Mengikuti menggunakan bash 4 , 2 PID dan 1 fifo :

bash -c 'coproc { exec >&-; read; }; eval exec "${COPROC[0]}<&-"; wait'

Anda dapat memeriksa apakah ini benar-benar memblokir dengan strace jika Anda suka:

strace -ff bash -c '..see above..'

Bagaimana ini dibuat

read blok jika tidak ada data input (lihat beberapa jawaban lain). Namun, tty (alias. stdin ) biasanya bukan sumber yang baik, karena ditutup saat pengguna logout. Juga mungkin mencuri beberapa input dari tty . Tidak bagus.

Untuk membuat read blok, kita perlu menunggu sesuatu seperti fifo yang tidak akan pernah mengembalikan apapun. Di bash 4 ada perintah yang bisa memberi kita fifo seperti itu :coproc . Jika kita juga menunggu pemblokiran read (yaitu coproc kita ), kita selesai. Sayangnya ini harus tetap membuka dua PID dan fifo .

Varian dengan nama fifo

Kalau tidak repot gunakan yang bernama fifo , Anda dapat melakukannya sebagai berikut:

mkfifo "$HOME/.pause.fifo" 2>/dev/null; read <"$HOME/.pause.fifo"

Tidak menggunakan loop pada pembacaan agak ceroboh, tetapi Anda dapat menggunakan kembali fifo ini sesering yang Anda suka dan buatlah read s terminasi menggunakan touch "$HOME/.pause.fifo" (jika ada lebih dari satu pembacaan yang menunggu, semuanya dihentikan sekaligus).

Atau gunakan pause() Linux syscall

Untuk pemblokiran tak terbatas ada panggilan kernel Linux, yang disebut pause() , yang melakukan apa yang kita inginkan:Tunggu selamanya (hingga sinyal tiba). Namun belum ada program userspace untuk ini (belum).

C

Membuat program seperti itu mudah. Berikut cuplikan untuk membuat program Linux yang sangat kecil bernama pause yang berhenti tanpa batas waktu (memerlukan diet , gcc dll.):

printf '#include <unistd.h>\nint main(){for(;;)pause();}' > pause.c;
diet -Os cc pause.c -o pause;
strip -s pause;
ls -al pause

python

Jika Anda tidak ingin mengkompilasi sesuatu sendiri, tetapi Anda memiliki python diinstal, Anda dapat menggunakan ini di Linux:

python -c 'while 1: import ctypes; ctypes.CDLL(None).pause()'

(Catatan:Gunakan exec python -c ... untuk mengganti shell saat ini, ini membebaskan satu PID. Solusinya dapat ditingkatkan dengan beberapa pengalihan IO juga, membebaskan FD yang tidak terpakai. Terserah Anda.)

Cara kerjanya (menurut saya):ctypes.CDLL(None) memuat pustaka C standar dan menjalankan pause() berfungsi di dalamnya dalam beberapa loop tambahan. Kurang efisien dibandingkan versi C, tetapi berfungsi.

Rekomendasi saya untuk Anda:

Tetap di tidur perulangan. Mudah dipahami, sangat portabel, dan sering diblokir.


sleep infinity melakukan apa yang disarankan dan bekerja tanpa penyalahgunaan kucing.


Linux
  1. Menyortir dalam bash

  2. Bagaimana cara menjalankan beberapa perintah latar belakang di bash dalam satu baris?

  3. Jalankan perintah bash pada pipa jenkins

  1. Skrip bash(I)

  2. Menggunakan Perintah Tidur Linux di Skrip Bash

  3. perintah ekspor bash

  1. Variabel Ekspor Bash

  2. Perintah tunggu bash

  3. Bagaimana cara saya tidur selama satu milidetik di bash atau ksh