ฉันต้องการtime
คำสั่งที่ประกอบด้วยคำสั่งสองคำสั่งแยกกันโดยมีหนึ่ง piping output ไปยังอีกคำสั่งหนึ่ง ตัวอย่างเช่นพิจารณาสองสคริปต์ด้านล่าง:
$ cat foo.sh
#!/bin/sh
sleep 4
$ cat bar.sh
#!/bin/sh
sleep 2
ตอนนี้ฉันtime
จะรายงานเวลาที่ใช้ไปได้อย่างไรfoo.sh | bar.sh
(และใช่ฉันรู้แล้วว่าไพพ์ไม่มีความหมายที่นี่ แต่นี่เป็นเพียงตัวอย่าง) มันทำงานได้อย่างที่คาดไว้ถ้าฉันใช้มันต่อเนื่องใน subshell โดยไม่ต้อง piping:
$ time ( foo.sh; bar.sh )
real 0m6.020s
user 0m0.010s
sys 0m0.003s
แต่ฉันไม่สามารถทำให้มันทำงานได้เมื่อ piping:
$ time ( foo.sh | bar.sh )
real 0m4.009s
user 0m0.007s
sys 0m0.003s
$ time ( { foo.sh | bar.sh; } )
real 0m4.008s
user 0m0.007s
sys 0m0.000s
$ time sh -c "foo.sh | bar.sh "
real 0m4.006s
user 0m0.000s
sys 0m0.000s
ฉันได้อ่านคำถามที่คล้ายกัน ( วิธีใช้เวลาในหลายคำสั่งและเขียนเวลาออกเป็นไฟล์? ) และยังพยายามtime
ปฏิบัติการแบบสแตนด์อโลน:
$ /usr/bin/time -p sh -c "foo.sh | bar.sh"
real 4.01
user 0.00
sys 0.00
มันไม่ทำงานเลยถ้าฉันสร้างสคริปต์ที่สามซึ่งรันไปป์เท่านั้น:
$ cat baz.sh
#!/bin/sh
foo.sh | bar.sh
แล้วเวลาที่:
$ time baz.sh
real 0m4.009s
user 0m0.003s
sys 0m0.000s
ที่น่าสนใจมันไม่ปรากฏว่าtime
ออกจากทันทีที่คำสั่งแรกเสร็จสิ้น ถ้าฉันเปลี่ยนbar.sh
เป็น:
#!/bin/sh
sleep 2
seq 1 5
จากนั้นtime
อีกครั้งฉันคาดหวังว่าtime
จะพิมพ์ออกมาก่อนหน้านี้seq
แต่ไม่ใช่:
$ time ( { foo.sh | bar.sh; } )
1
2
3
4
5
real 0m4.005s
user 0m0.003s
sys 0m0.000s
ดูเหมือนtime
จะไม่นับรวมระยะเวลาที่ใช้ในการดำเนินการbar.sh
แม้จะรอให้เสร็จสิ้นก่อนที่จะพิมพ์รายงาน1
การทดสอบทั้งหมดถูกเรียกใช้บนระบบ Arch และใช้ bash 4.4.12 (1) -release ฉันสามารถใช้ bash สำหรับโปรเจ็กต์นี้ได้เพียงบางส่วนเท่านั้นแม้ว่าzsh
บางอันที่ทรงพลังเชลล์สามารถไปถึงที่ ๆ มันจะไม่เป็นทางออกสำหรับฉัน
ดังนั้นฉันจะได้รับเวลาที่คำสั่ง piped ใช้เพื่อให้ทำงานได้อย่างไร และในขณะที่เราอยู่ที่นี่ทำไมมันไม่ทำงาน ดูเหมือนว่าtime
จะจบการทำงานทันทีที่คำสั่งแรกเสร็จสิ้น ทำไม?
ฉันรู้ว่าฉันสามารถทำให้แต่ละครั้งด้วยสิ่งนี้:
( time foo.sh ) 2>foo.time | ( time bar.sh ) 2> bar.time
แต่ฉันก็ยังอยากจะรู้ว่ามันเป็นไปได้ที่จะใช้เวลาทั้งหมดในการทำงานครั้งเดียว
1 สิ่งนี้ดูเหมือนจะไม่เป็นปัญหาของบัฟเฟอร์ฉันพยายามเรียกใช้สคริปต์ด้วยunbuffered
และstdbuf -i0 -o0 -e0
ตัวเลขยังคงถูกพิมพ์ก่อนที่จะtime
ส่งออก