Pertanyaan Bagaimana saya tidur selama milidetik di bash atau ksh


tidur adalah perintah yang sangat populer dan kita bisa mulai tidur dari 1 detik:

# wait one second please 
sleep 1

tetapi apa alternatifnya jika saya hanya perlu menunggu 0,1 detik atau antara 0,1 hingga 1 detik?

  • komentar: di linux atau OS X sleep 0.XXX berfungsi dengan baik, tetapi pada solaris sleep 0.1 atau sleep 0.01 - sintaks ilegal

105
2018-01-15 13:19




Bolehkah saya bertanya mengapa Anda ingin tidur selama 1ms? - Tom O'Connor
Ya tentu saja, dalam skrip bash saya, saya menambahkan "sleep 1", dalam beberapa baris, tetapi skrip berjalan sangat lambat, jadi setelah beberapa kesimpulan saya menghitung bahwa sleep 0.1 juga membawa hasil yang baik dan lebih cepat Tentang penundaan, saya perlu penundaan dalam rangka untuk memecahkan masalah ssh di skrip bash saya, saya melakukan login ssh paralel ke beberapa komputer dengan mengharapkan dan tanpa penundaan tidak akan berfungsi, Seperti yang Anda ketahui dari pertanyaan saya, penundaan harus sesuai dengan Linux dan Solaris - yael
Apapun solusi yang Anda pilih, perlu diingat bahwa skrip shell tidak akan sangat akurat dalam hal pengaturan waktu. - scai
Bagaimana kalau melakukan sesuatu yang membutuhkan waktu yang sangat singkat untuk dieksekusi, tetapi tidak melakukan apa-apa .. suka echo "" >/dev/null - Tom O'Connor
Ide bagus tapi bagaimana msec perintah ini? , Saya perlu 0,1 msec, tidak kurang dari itu - :) - yael


Jawaban:


Bash memiliki "loadable" sleep yang mendukung detik-detik pecahan, dan menghilangkan overhead dari perintah eksternal:

$ cd bash-3.2.48/examples/loadables
$ make sleep && mv sleep sleep.so
$ enable -f sleep.so sleep

Kemudian:

$ which sleep
/usr/bin/sleep
$ builtin sleep
sleep: usage: sleep seconds[.fraction]
$ time (for f in `seq 1 10`; do builtin sleep 0.1; done)
real    0m1.000s
user    0m0.004s
sys     0m0.004s

Kekurangannya adalah bahwa loadables mungkin tidak disediakan dengan Anda bash biner, jadi Anda perlu mengkompilasi mereka sendiri seperti yang ditunjukkan (meskipun pada Solaris itu tidak harus sesederhana seperti di atas).

Seperti bash-4.4 (September 2016) semua loadable sekarang dibangun dan diinstal secara default pada platform yang mendukungnya, meskipun mereka dibangun sebagai file objek bersama yang terpisah, dan tanpa .so akhiran. Kecuali distro / OS Anda telah melakukan sesuatu yang kreatif, Anda seharusnya dapat melakukannya:

[ -z "$BASH_LOADABLES_PATH" ] &&
  BASH_LOADABLES_PATH=$(pkg-config bash --variable=loadablesdir 2>/dev/null)  
enable -f sleep sleep

(Halaman manual menyiratkan BASH_LOADABLES_PATH diatur secara otomatis, saya menemukan ini tidak terjadi dalam distribusi resmi pada 4.4.12. Jika dan ketika sudah diatur dengan benar, Anda hanya perlu enable -f filename commandname seperti yang dipersyaratkan.)

Jika itu tidak cocok, hal termudah berikutnya yang harus dilakukan adalah membangun atau memperoleh sleep dari GNU coreutils, ini mendukung fitur yang diperlukan. The POSIX sleep perintah minimal, versi Solaris yang lebih tua hanya menerapkan itu. Solaris 11 sleep  tidak mendukung detik-detik pecahan.

Sebagai usaha terakhir yang bisa Anda gunakan perl (atau scripting lain yang harus Anda tangani) dengan peringatan yang memulai penerjemah mungkin sebanding dengan waktu tidur yang dimaksudkan:

$ perl -e "select(undef,undef,undef,0.1);"
$ echo "after 100" | tclsh

59
2018-01-15 13:52



Ah, karena kamu menggunakan expect Anda mungkin bisa menggunakan "after N", di mana N adalah milidetik, langsung di skrip Anda. - mr.spuratic
menggunakan usleep seperti @Luis Vazquez dan @sebix menulis - Ilan.K


Dokumentasi untuk sleep perintah dari coreutils mengatakan:

Implementasi historis dari tidur telah mengharuskan nomor itu menjadi   integer, dan hanya menerima satu argumen tanpa akhiran.   Namun, GNU sleep menerima nomor floating point yang arbitrer. Lihat    Titik mengambang.

Maka Anda bisa menggunakan sleep 0.1, sleep 1.0e-1 dan argumen serupa.


103
2018-01-15 13:22



lihat komentar saya tentang SOLARIS OS - yael
Apakah kamu bercampur aku s dan tidak? - scai
lihat pembaruan saya di quastion saya - yael
Yael, saya pikir masih ada satu terlalu banyak negatif dalam pertanyaan Anda; apakah kamu yakin maksudmu "sintaks tidak ilegal"? - MadHatter
misalnya - Saya menjalankan pada solaris 10 ini: # tidur 0,1 tidur: karakter buruk dalam argumen, tentang linux sleep 0.1 berfungsi dengan baik - yael


Tidur menerima angka desimal sehingga Anda dapat memecahnya seperti ini:

1/2 detik

 sleep 0.5

1/100 detik

sleep 0.01

Jadi, untuk milidetik yang Anda inginkan

sleep 0.001

46
2018-01-15 13:24



Anda juga dapat menjatuhkan nol di depan sebelum titik desimal. misalnya. sleep .5 - Mike Causer
Kecuali untuk mathforum.org/library/drmath/view/52352.html - stark
Bicara tentang orang lain yang terlalu rumit ... - Martin


Coba ini untuk menentukan akurasi:

    time sleep 0.5      # 500 milliseconds (1/2 of a second)
    time sleep 0.001    # 1 millisecond (1/1000 of a second)
    time sleep 1.0      # 1 second (1000 milliseconds)

Kombinasi dari solusi mr.spuratic dan solusi coles.


11
2018-06-22 19:52





Anda cukup menggunakan usleep. Diperlukan microsecond (= 1e-6 detik) sebagai parameter, jadi untuk tidur 1 milidetik Anda akan masuk:

usleep 1000

6
2017-07-08 13:55



$ usleep  No command 'usleep' found, did you mean:  Command 'sleep' from package 'coreutils' (main)  usleep: command not found - Bulletmagnet
Tidak, maksudku usleep bagian dari initscripts paket yang standar setidaknya di semua distribusi tur Red Hat; termasuk setidaknya RHEL, CentOS, Fedora, Mageia / Mandriva dan SuSE. Berikut contohnya: `` `` - Luis Vazquez
Berikut ini contoh ilustrasi yang berjalan di CentOS 7: `` `$ yang menggunakan usleep / usr / bin / usleep $ rpm -qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64` `` Untuk meringkas : - sleep (dari coreutils) berfungsi dengan detik - usleep (dari skrip init) bekerja dengan mikro-detik - Luis Vazquez


Saya memiliki masalah yang sama (tidak ada shell tidur di Solaris) jadi saya menulis sendiri demikian:

  #include "stdio.h"
  int main(int argc, char **argv) {
     if(argc == 1) { usleep(atoi(argv[1])); }
     return 0;
}

Tidak memeriksa argumen - Saya akan merekomendasikan yang ditulis dengan benar jika Anda ingin menyimpannya tetapi itu (gcc usleep.c -o usleep) akan membuat Anda keluar dari lubang.


3
2018-05-24 15:12



Anda bisa setidaknya ubah itu telanjang usleep() panggilan ke if(argc == 1) { usleep(atoi(argv[1])); } untuk menghindari pengindeksan di luar batas-batas array, yang dapat menyebabkan sejumlah perilaku tak terduga. - α CVn