Saya gunakan startx
untuk memulai X yang akan mengevaluasi .xinitrc
. Di saya, .xinitrc
saya mulai menggunakan window manager saya /usr/bin/mywm
. Sekarang, jika saya membunuh WM saya (untuk menguji beberapa WM lainnya), X akan berakhir juga karena .xinitrc
script mencapai EOF. Jadi saya menambahkan ini di akhir .xinitrc
:
while true; do sleep 10000; done
Dengan cara ini X tidak akan berhenti jika saya membunuh WM saya. Sekarang pertanyaan saya: bagaimana saya bisa tidur nyenyak alih-alih tidur berulang? Apakah ada perintah yang agak suka membekukan skrip?
salam Hormat
sleep infinity
, meskipun itu hal yang keren untuk dipelajari tentang Linux. Namun,while true; do sleep 86400; done
harus menjadi pengganti yang memadai.infinity
dikonversi dalam C dari "string" ke adouble
. Kemudian itudouble
dipotong ke nilai maksimum yang diperbolehkantimespec
, yang berarti jumlah detik yang sangat besar (tergantung arsitektur) tetapi, secara teori, terbatas.tail
tidak menghalangiSeperti biasa: Untuk semuanya ada jawaban yang pendek, mudah dimengerti, mudah diikuti dan sepenuhnya salah. Di sini
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! Ini mungkin bahkan lebih buruk daripadasleep
solusi dalam pertanyaan, karena menggunakan sumber daya berharga (di Linux) sepertiinotify
sistem. Juga proses lain yang menulis untuk/dev/null
membuattail
lingkaran. (Pada Ubuntu64 16.10 saya, ini menambahkan beberapa 10 syscalls per detik pada sistem yang sudah sibuk.)Pertanyaannya adalah untuk perintah pemblokiran
Sayangnya, tidak ada yang namanya ..
Baca: Saya tidak tahu cara mengarsipkan ini dengan shell secara langsung.
Semuanya (datar
sleep infinity
) dapat terganggu oleh beberapa sinyal. Jadi jika Anda ingin benar-benar yakin itu tidak kembali, itu harus dijalankan dalam satu lingkaran, seperti yang sudah Anda lakukan untuk Andasleep
. Harap dicatat, bahwa (di Linux)/bin/sleep
tampaknya dibatasi dalam 24 hari (lihatlahstrace sleep infinity
), maka yang terbaik yang dapat Anda lakukan adalah:(Perhatikan bahwa saya percaya
sleep
loop internal untuk nilai yang lebih tinggi dari 24 hari, tetapi ini berarti: Ini tidak memblokir, looping sangat lambat. Jadi mengapa tidak memindahkan loop ini ke luar?).. tetapi Anda bisa datang cukup dekat dengan yang tidak disebutkan namanya
fifo
Anda dapat membuat sesuatu yang benar-benar menghalangi selama tidak ada sinyal yang dikirim ke proses. Penggunaan berikut
bash 4
, 2 PID dan 1fifo
:Anda dapat memeriksa apakah ini benar-benar diblokir
strace
jika Anda suka:Bagaimana ini dibangun
read
blok jika tidak ada data input (lihat beberapa jawaban lain). Namun,tty
(alias.stdin
) Biasanya bukan sumber yang baik, karena ditutup ketika pengguna logout. Juga mungkin mencuri beberapa masukan daritty
. Tidak baik.Untuk membuat
read
blok, kita perlu menunggu sesuatu sepertififo
yang tidak akan pernah mengembalikan apa pun. Dalambash 4
ada perintah yang tepat dapat memberikan kita dengan sepertififo
:coproc
. Jika kita juga menunggu pemblokiranread
(yang merupakan milik kitacoproc
), kita selesai. Sayangnya ini harus tetap membuka dua PID dan afifo
.Varian dengan nama
fifo
Jika Anda tidak ingin menggunakan nama
fifo
, Anda bisa melakukan ini sebagai berikut:Tidak menggunakan perulangan pada proses baca agak ceroboh, tetapi Anda dapat menggunakan kembali ini
fifo
sesering mungkin dan membuatread
terminat menggunakantouch "$HOME/.pause.fifo"
(jika ada lebih dari satu menunggu baca, semua diakhiri sekaligus).Atau gunakan
pause()
syscall LinuxUntuk pemblokiran tak terbatas ada panggilan kernel Linux, yang disebut
pause()
, yang melakukan apa yang kita inginkan: Tunggu selamanya (sampai sinyal tiba). Namun tidak ada program userspace untuk ini (belum).C
Membuat program seperti itu mudah. Berikut ini cuplikan untuk membuat program Linux yang sangat kecil yang disebut
pause
jeda tanpa batas waktu (kebutuhandiet
,gcc
dll.):python
Jika Anda tidak ingin mengkompilasi sesuatu sendiri, tetapi Anda telah
python
menginstalnya, Anda dapat menggunakan ini di Linux:(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. Ini terserah Anda.)Bagaimana ini bekerja (saya pikir):
ctypes.CDLL(None)
memuat perpustakaan C standar dan menjalankanpause()
fungsi di dalamnya dalam beberapa loop tambahan. Kurang efisien daripada versi C, tetapi berfungsi.Rekomendasi saya untuk Anda:
Menginap di tidur berulang. Sangat mudah dipahami, sangat portabel, dan hampir selalu memblokir.
sumber
trap
(yang mengubah perilaku shell ke sinyal) atau latar belakang (yang memungkinkan shell untuk mencegat sinyal dari terminal, seperti Strg + C). Jadisleep infinity
sudah cukup (berperilaku sepertiexec sleep infinity
jika itu adalah pernyataan terakhir. Untuk melihat perbedaan penggunaanstrace -ffDI4 bash -c 'YOURCODEHERE'
). Tidur berulang lebih baik, karenasleep
dapat kembali dalam keadaan tertentu. Misalnya, Anda tidak ingin X11 dimatikan secara tiba-tiba padakillall sleep
, hanya karena.xstartup
berakhirsleep infinity
sebagai ganti lingkaran tidur.s6-pause
merupakan perintah userland untuk dijalankanpause()
, opsional mengabaikan berbagai sinyal./bin/sleep
tidak dibatasi pada 24 hari seperti yang Anda katakan. Akan lebih baik jika Anda dapat memperbarui itu. Di Linux sekarang, kode ini aktif. Ini membatasinanosleep()
syscalls individu hingga 24 hari, tetapi menyebutnya dalam satu lingkaran. Jadisleep infinity
sebaiknya tidak keluar setelah 24 hari. Thedouble
infinity positif akan dikonversi kestruct timespec
. Melihatrpl_nanosleep
di GDB,infinity
akan dikonversi ke{ tv_sec = 9223372036854775807, tv_nsec = 999999999 }
di Ubuntu 16,04.strace
sendirian saya tidak dapat membuktikan fakta bahwa ada beberapa kode pengulangan yang dikompilasisleep
, dan saya tidak ingin menunggu 24 hari hanya untuk menguji ini (atau mendekompilasi/bin/sleep
). Itu selalu lebih baik untuk memprogram defensif, jika tidak ada bukti matematika yang keras, bahwa sesuatu benar-benar, seperti yang terlihat. Juga tidak pernah mempercayai apa pun:killall -9 sleep
Mungkin ini tampak jelek, tapi mengapa tidak jalankan saja
cat
dan biarkan menunggu input selamanya?sumber
cat
itu?mkfifo pipe && cat pipe
TL; DR:
sleep infinity
sebenarnya tidur waktu maksimum yang diizinkan, yang terbatas.Bertanya-tanya mengapa ini tidak didokumentasikan di mana pun, saya repot-repot membaca sumber - sumber dari GNU coreutils dan saya menemukan itu mengeksekusi kira-kira apa yang berikut:
strtod
dari C stdlib pada argumen pertama untuk mengubah 'infinity' menjadi presisi ganda. Jadi, dengan asumsi presisi ganda IEEE 754 nilai infinity positif 64-bit disimpan dalamseconds
variabel.xnanosleep(seconds)
( ditemukan di gnulib ), ini pada gilirannya memanggildtotimespec(seconds)
( juga di gnulib ) untuk mengkonversi daridouble
kestruct timespec
.struct timespec
hanya sepasang angka: bagian integer (dalam detik) dan bagian fraksional (dalam nanodetik). Konversi tak terhingga positif ke bilangan bulat akan menghasilkan perilaku yang tidak terdefinisi (lihat §6.3.1.4 dari standar C), jadi alih-alih terpotongTYPE_MAXIMUM (time_t)
.TYPE_MAXIMUM (time_t)
tidak diatur dalam standar (bahkansizeof(time_t)
tidak); jadi, sebagai contoh mari kita ambil x86-64 dari kernel Linux baru-baru ini.Ini ada
TIME_T_MAX
di kernel Linux, yang didefinisikan (time.h
) sebagai:Perhatikan bahwa
time_t
ini__kernel_time_t
dantime_t
itulong
; model data LP64 digunakan, demikiansizeof(long)
juga 8 (64 bit).Yang hasil dalam:
TIME_T_MAX = 9223372036854775807
.Yaitu:
sleep infinite
menghasilkan waktu tidur aktual 9223372036854775807 detik (10 ^ 11 tahun). Dan untuk sistem linux 32-bit (sizeof(long)
adalah 4 (32 bit)): 2147483647 detik (68 tahun; lihat juga tahun 2038 masalah ).Sunting : rupanya
nanoseconds
fungsi yang dipanggil bukan secara langsung syscall, tetapi pembungkus yang tergantung pada OS (juga didefinisikan dalam gnulib ).Ada langkah tambahan sebagai hasilnya: untuk beberapa sistem di mana
HAVE_BUG_BIG_NANOSLEEP
adalahtrue
tidur tersebut dipotong menjadi 24 hari dan kemudian disebut dalam satu lingkaran. Ini adalah kasus untuk beberapa (atau semua?) Distro Linux. Perhatikan bahwa pembungkus ini tidak dapat digunakan jika uji konfigurasi- waktu berhasil ( sumber ).Secara khusus, itu akan menjadi
24 * 24 * 60 * 60 = 2073600 seconds
(ditambah 999999999 nanodetik); tapi ini disebut dalam satu lingkaran untuk menghormati total waktu tidur yang ditentukan. Oleh karena itu kesimpulan sebelumnya tetap valid.Kesimpulannya, waktu tidur yang dihasilkan tidak terbatas tetapi cukup tinggi untuk semua tujuan praktis , bahkan jika selang waktu aktual yang dihasilkan tidak portabel; itu tergantung pada OS dan arsitekturnya.
Untuk menjawab pertanyaan awal, ini jelas cukup baik tetapi jika karena alasan tertentu (sistem yang sangat terbatas sumber daya) Anda benar-benar ingin menghindari penghitung waktu mundur tambahan yang tidak berguna, saya kira alternatif yang paling tepat adalah dengan menggunakan
cat
metode yang dijelaskan dalam jawaban lain. .sumber
sleep infinity
sekarang akan benar-benar tidur selamanya tanpa perulangan: lists.gnu.org/archive/html/bug-gnulib/2020-02/msg00081.htmlsleep infinity
terlihat paling elegan, tetapi kadang-kadang itu tidak berhasil karena suatu alasan. Dalam hal ini, Anda dapat mencoba perintah pemblokiran lain seperticat
,read
,tail -f /dev/null
,grep a
dllsumber
tail -f /dev/null
juga merupakan solusi yang berfungsi untuk saya pada platform SaaStail -f /dev/null
juga memiliki kelebihan yaitu tidak mengonsumsi stdin. Saya telah menggunakannya untuk alasan itu.Bagaimana dengan mengirim SIGSTOP ke dirinya sendiri?
Ini harus menghentikan proses sampai SIGCONT diterima. Yang ada dalam kasus Anda: tidak pernah.
sumber
Biarkan saya jelaskan mengapa
sleep infinity
bekerja meskipun tidak didokumentasikan. Jawaban jp48 juga berguna.Hal yang paling penting: Dengan menentukan
inf
atauinfinity
(keduanya tidak peka huruf besar-kecil), Anda dapat tidur untuk waktu terlama yang diizinkan oleh implementasi Anda (yaitu nilai lebih kecil dariHUGE_VAL
danTYPE_MAXIMUM(time_t)
).Sekarang mari kita gali detailnya. Kode sumber
sleep
perintah dapat dibaca dari coreutils / src / sleep.c . Pada dasarnya, fungsi melakukan ini:Pemahaman
xstrtod (argv[i], &p, &s, cl_strtod)
xstrtod()
Menurut gnulib / lib / xstrtod.c , panggilan
xstrtod()
string yang dikonversiargv[i]
ke nilai floating point dan menyimpannya*s
, menggunakan fungsi konversicl_strtod()
.cl_strtod()
Seperti dapat dilihat dari coreutils / lib / cl-strtod.c ,
cl_strtod()
mengonversi string ke nilai floating point, menggunakanstrtod()
.strtod()
Menurut
man 3 strtod
,strtod()
mengkonversi string ke nilai tipedouble
. Kata halaman buku itudan infinity didefinisikan sebagai
Meskipun dokumen itu memberitahu
, tidak jelas bagaimana infinity diperlakukan. Jadi mari kita lihat kode sumber gnulib / lib / strtod.c . Yang ingin kita baca adalah
Dengan demikian,
INF
danINFINITY
(keduanya case-insensitive) dianggap sebagaiHUGE_VAL
.HUGE_VAL
keluargaMari kita gunakan N1570 sebagai standar C.
HUGE_VAL
,HUGE_VALF
danHUGE_VALL
makro didefinisikan dalam §7.12-3dan di §7.12.1-5
Pemahaman
xnanosleep (s)
Sekarang kami mengerti semua esensi
xstrtod()
. Dari penjelasan di atas, sangat jelas bahwa yang pertamaxnanosleep(s)
kita lihat sebenarnya berartixnanosleep(HUGE_VALL)
.xnanosleep()
Menurut kode sumber gnulib / lib / xnanosleep.c ,
xnanosleep(s)
pada dasarnya melakukan ini:dtotimespec()
Fungsi ini mengonversi argumen tipe
double
ke objek tipestruct timespec
. Karena sangat sederhana, izinkan saya mengutip kode sumber gnulib / lib / dtotimespec.c . Semua komentar ditambahkan oleh saya.Karena
time_t
didefinisikan sebagai tipe integral (lihat §7.27.1-3), wajar saja kita mengasumsikan nilai maksimum tipetime_t
lebih kecil dariHUGE_VAL
(tipedouble
), yang berarti kita memasuki case overflow. (Sebenarnya asumsi ini tidak diperlukan karena, dalam semua kasus, prosedurnya pada dasarnya sama.)make_timespec()
Tembok terakhir yang harus kita panjat adalah
make_timespec()
. Sangat untungnya, mengutip kode sumber gnulib / lib / timespec.h sudah cukup sederhana.sumber
Baru-baru ini saya perlu melakukan ini. Saya datang dengan fungsi berikut yang akan memungkinkan bash tidur selamanya tanpa memanggil program eksternal apa pun:
CATATAN: Saya sebelumnya memposting versi ini yang akan membuka dan menutup deskriptor file setiap kali, tetapi saya menemukan bahwa pada beberapa sistem melakukan ini ratusan kali per detik pada akhirnya akan terkunci. Dengan demikian solusi baru membuat deskriptor file antara panggilan ke fungsi. Bash akan membersihkannya saat keluar.
Ini bisa disebut seperti / bin / sleep, dan itu akan tidur untuk waktu yang diminta. Disebut tanpa parameter, itu akan menggantung selamanya.
Ada langganan dengan rincian berlebihan di blog saya di sini
sumber
Pendekatan ini tidak akan menghabiskan sumber daya apa pun untuk menjaga proses tetap hidup.
while :; do sleep 1; done & kill -STOP $! && wait $!
Kerusakan
while :; do sleep 1; done &
Membuat proses dummy di latar belakangkill -STOP $!
Menghentikan proses latar belakangwait $!
Tunggu proses latar belakang, ini akan memblokir selamanya, karena proses latar belakang dihentikan sebelumnyasumber
Alih-alih membunuh pengelola jendela, coba jalankan yang baru dengan
--replace
atau-replace
jika tersedia.sumber
--replace
saya selalu mendapat peringatan sepertianother window manager is already running
. Bagi saya itu tidak masuk akal.tidak perlu menunggu proses tidur anak.
sumber
stdin
jika ini masih terhubung ke Internettty
. Jika Anda menjalankannya dengan< /dev/null
sibuk-loop. Mungkin bermanfaat dalam situasi tertentu, jadi saya tidak downvote.