ฉันจะนอนเป็นมิลลิวินาทีใน bash หรือ ksh ได้อย่างไร


128

sleep เป็นคำสั่งที่นิยมมากและเราสามารถเริ่ม sleep จาก 1 วินาที:

# wait one second please 
sleep 1

แต่จะเป็นทางเลือกอะไรถ้าฉันต้องรอเพียง 0.1 วินาทีหรือระหว่าง 0.1 ถึง 1 วินาที

  • หมายเหตุ: บน linux หรือ OS X sleep 0.XXXทำงานได้ดี แต่บน Solaris sleep 0.1หรือsleep 0.01- ไวยากรณ์ผิดกฎหมาย

2
ฉันขอถามได้ไหมว่าทำไมคุณถึงอยากนอน 1 มิลลิวินาที?
Tom O'Connor

1
ใช่แน่นอนในสคริปต์ทุบตีของฉันฉันเพิ่ม "sleep 1" ในบางบรรทัด แต่สคริปต์รันช้ามากดังนั้นหลังจากสรุปแล้วฉันคำนวณว่า sleep 0.1 ยังให้ผลลัพธ์ที่ดีและเร็วขึ้นเกี่ยวกับความล่าช้าฉันต้องการความล่าช้าตามลำดับ ในการแก้ปัญหา SSH ในสคริปต์ทุบตีฉันฉันดำเนินการเข้าสู่ระบบ SSH ขนานเครื่องโดยคาดหวังและโดยไม่ชักช้ามันจะไม่ทำงานในขณะที่คุณรู้จากคำถามของฉันล่าช้าควรจะพอดีกับทั้ง Linux และ Solaris
Yael

3
วิธีใดก็ตามที่คุณเลือกโปรดจำไว้ว่าเชลล์สคริปต์จะไม่แม่นยำมากในแง่ของเวลา
scai

วิธีการเกี่ยวกับการทำสิ่งที่ใช้เวลาสั้น ๆ ในการดำเนินการ แต่ไม่ทำอะไรเลย .. เช่นecho "" >/dev/null
Tom O'Connor

เป็นแนวคิดที่ดี แต่คำสั่ง msec นี้ใช้อย่างไร ฉันต้องการ 0.1 มิลลิวินาทีไม่น้อยกว่านั้น - :)
yael

คำตอบ:


68

Bash มีโหมด "loadable" ซึ่งรองรับเสี้ยววินาทีและกำจัดค่าโสหุ้ยของคำสั่งภายนอก:

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

แล้ว:

$ 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

ข้อเสียคือโหลดอาจจะไม่ได้รับกับbashไบนารีของคุณดังนั้นคุณจะต้องรวบรวมพวกเขาด้วยตัวเองดังที่แสดง (แม้ว่าใน Solaris มันไม่จำเป็นต้องง่ายเหมือนข้างต้น)

ณ วันที่bash-4.4 (กันยายน 2016) โหลดทั้งหมดจะถูกสร้างและติดตั้งตามค่าเริ่มต้นบนแพลตฟอร์มที่รองรับแม้ว่าจะถูกสร้างเป็นไฟล์วัตถุที่แชร์ที่แยกกันและไม่มี.soคำต่อท้าย ยกเว้นว่า distro / OS ของคุณทำอะไรที่สร้างสรรค์แล้วคุณควรจะทำได้:

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

(หน้า man หมายถึงการBASH_LOADABLES_PATHตั้งค่าโดยอัตโนมัติฉันคิดว่านี่ไม่ใช่กรณีในการจัดจำหน่ายอย่างเป็นทางการ ณ วันที่ 4.4.12 ถ้าและเมื่อมันถูกตั้งค่าอย่างถูกต้องคุณต้องenable -f filename commandnameเท่าที่จำเป็น)

หากไม่เหมาะสมสิ่งที่ง่ายที่สุดที่จะทำต่อไปคือสร้างหรือรับsleepจากแกนกลาง GNU สิ่งนี้จะสนับสนุนคุณสมบัติที่ต้องการ sleepคำสั่งPOSIX มีน้อยที่สุดรุ่น Solaris ที่เก่ากว่าจะมีการใช้งานเพียงอย่างเดียว Solaris 11 sleep ไม่สนับสนุนวินาทีเศษส่วน

เป็นทางเลือกสุดท้ายที่คุณสามารถใช้perl(หรือสคริปต์อื่น ๆ ที่คุณต้องทำ) กับข้อแม้ที่การเริ่มต้นล่ามอาจเทียบเคียงได้กับเวลาพักเครื่อง:

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

2
อาเนื่องจากคุณใช้expectคุณอาจจะสามารถใช้ " after N" โดยที่ N คือมิลลิวินาทีในสคริปต์ของคุณโดยตรง
mr.spuratic

ใช้usleeplike @Luis Vazquez และ @sebix เขียน
Ilan.K

Apple MacOS มีการนอนหลับ BSD ซึ่งรองรับวินาทีเศษส่วน
roblogic

125

เอกสารสำหรับsleepคำสั่งจากcoreutilsพูดว่า:

การประยุกต์ใช้ในอดีตของการนอนหลับจำเป็นต้องมีหมายเลขนั้นเป็นจำนวนเต็มและยอมรับเฉพาะอาร์กิวเมนต์เดี่ยวที่ไม่มีคำต่อท้าย อย่างไรก็ตาม GNU sleep สามารถรับหมายเลขทศนิยมได้ตามต้องการ ดู จุดลอย

ดังนั้นคุณสามารถใช้sleep 0.1, sleep 1.0e-1และข้อโต้แย้งที่คล้ายกัน


1
ดูคำพูดของฉันเกี่ยวกับ SOLARIS OS
yael

คุณไม่ได้ผสมขึ้นเป็นและไม่ได้ ?
SCAI

ดูการอัปเดตของฉันในการสอบถามของฉัน
yael

1
Yael ฉันคิดว่าคุณมีคำถามเชิงลบมากเกินไปในคำถามของคุณ คุณแน่ใจหรือว่าคุณหมายถึง "ไม่ใช่ไวยากรณ์ที่ผิดกฎหมาย"?
MadHatter

ตัวอย่างเช่น - ฉันทำงานบน solaris 10 สิ่งนี้: # sleep 0.1 sleep: ตัวละครที่ไม่ดีในการโต้แย้งเกี่ยวกับ linux sleep 0.1 ทำงานได้ดี
yael

58

Sleep ยอมรับตัวเลขทศนิยมเพื่อให้คุณแยกย่อยดังนี้:

1/2 ของวินาที

 sleep 0.5

1/100 วินาที

sleep 0.01

ดังนั้นสำหรับมิลลิวินาทีคุณจะต้องการ

sleep 0.001

4
นอกจากนี้คุณยังสามารถวางศูนย์นำหน้าก่อนจุดทศนิยม เช่น. sleep .5
Mike Causer


พูดคุยเกี่ยวกับคนอื่น overcomplicating มัน ...
Martin

1
@MikeCauser เลขศูนย์นำหน้าอ่านได้มากขึ้นและตั้งใจส่งสัญญาณให้ผู้อ่านของรหัสในภายหลัง ยังดีกว่าเมื่อคุณทำคณิตศาสตร์จริง
Alexander Mills

11

ลองใช้วิธีนี้เพื่อพิจารณาความถูกต้อง:

    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)

การรวมกันของการแก้ปัญหาของ mr.spuraticและวิธีการแก้ปัญหาของโคลส์


8

usleepคุณก็อาจจะใช้ ใช้เวลา microseconds (= 1e-6 วินาที) เป็นพารามิเตอร์ดังนั้นในการพัก 1 มิลลิวินาทีคุณจะต้องป้อน:

usleep 1000

1
$ usleep No command 'usleep' found, did you mean: Command 'sleep' from package 'coreutils' (main) usleep: command not found
Bulletmagnet

ไม่ฉันหมายถึงusleepส่วนหนึ่งของinitscriptsแพ็คเกจซึ่งเป็นมาตรฐานอย่างน้อยในการแจกแจง Red Hat ทั้งหมด รวมถึงอย่างน้อย RHEL, CentOS, Fedora, Mageia / Mandriva และ SuSE นี่เป็นตัวอย่าง: `` ``
Luis Vazquez

1
นี่คือตัวอย่างความไม่แน่นอนที่ทำงานใน CentOS 7: `` `$ ซึ่ง usleep / usr / bin / usleep $ rpm -qf / usr / bin / usleep initscripts-9.49.37-1.el7_3.1.x86_64` '' เพื่อสรุป : - sleep(จากcoreutils ) ทำงานร่วมกับวินาที - usleep(จากinitscripts ) ทำงานร่วมกับไมโครวินาที
Luis Vazquez

4

ฉันมีปัญหาเดียวกัน (ไม่มีเชลล์ใช้บน Solaris) ดังนั้นฉันจึงเขียนของตัวเองดังนี้:

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

ไม่ตรวจสอบการขัดแย้ง - ฉันแนะนำให้เขียนอย่างถูกต้องหากคุณต้องการเก็บไว้ แต่ที่ (gcc usleep.c -o usleep) จะพาคุณออกจากหลุม


1
อย่างน้อยคุณสามารถเปลี่ยนการusleep()โทรที่เปลือยเปล่าif(argc == 1) { usleep(atoi(argv[1])); }เพื่อหลีกเลี่ยงการสร้างดัชนีนอกขอบเขตของอาร์เรย์ซึ่งอาจนำไปสู่พฤติกรรมที่ไม่คาดคิดจำนวนมาก
CVn

@aCVn เป็นจริงif (argc == 2) { usleep(atoi(argv[1])); }...
แหวนØ

โปรดทราบว่าusleepหน่วยเป็นμsดังนั้นเพื่อรอ 1 วินาทีคุณต้องระบุอาร์กิวเมนต์ 1000000
แหวนØ

@ RingØถูกต้อง ความผิดพลาดโง่จับดี
CVn

atoi()intเป็นทางเลือกที่น่ากลัวในการแปลงสตริงไปยัง อะไรatoi( "STRING" )กลับมา? atoi()ไม่มีวิธีในการส่งคืนข้อผิดพลาดใด ๆ
Andrew Henle

0

ฉันชอบความคิดที่เป็นประโยชน์ แต่ฉันไม่สามารถแสดงความคิดเห็นได้ ตั้งแต่นี้ช่วยฉันออกไปฉันหวังว่าข้อเสนอแนะของฉันสามารถปรับปรุงแนวคิดการนอนหลับได้

https://github.com/fedora-sysv/initscripts/blob/3c3fe4a4d1b2a1113ed302df3ac9866ded51b01b/src/usleep.cเป็นซอร์สโค้ดที่แท้จริงสำหรับ usleep.c บนระบบนิเวศ redhat

พยายามรวบรวมสิ่งนั้นในโซลาริสของคุณ คุณอาจจะต้องhttps://www.opencsw.org/packages/libpopt0/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.