ฉันแค่อยากจะจับเอาท์พุทของคำสั่งเวลาเช่น:
X=$(time ls)
หรือ
$(time ls) | grep real
ฟังก์ชั่นเวลาถ่มน้ำลายไปที่คอนโซลแม้ว่า ฉันจะทำสิ่งนี้ได้อย่างไร
ฉันแค่อยากจะจับเอาท์พุทของคำสั่งเวลาเช่น:
X=$(time ls)
หรือ
$(time ls) | grep real
ฟังก์ชั่นเวลาถ่มน้ำลายไปที่คอนโซลแม้ว่า ฉันจะทำสิ่งนี้ได้อย่างไร
คำตอบ:
ดูBashFAQ / 032
$ # captures output of command and time
$ time=$( TIMEFORMAT="%R"; { time ls; } 2>&1 ) # note the curly braces
$ # captures the time only, passes stdout through
$ exec 3>&1 4>&2
$ time=$(TIMEFORMAT="%R"; { time ls 1>&3 2>&4; } 2>&1)
bar baz
$ exec 3>&- 4>&-
เวลาจะมีลักษณะเหมือน "0.000" TIMEFORMAT="%R"
ซึ่งใช้เป็นเวลา "ของจริง"
exec
คำสั่งในคำตอบของฉันโดยใช้ตัวอธิบายไฟล์ที่มีอยู่ ตัวอธิบายไฟล์ใด ๆ ที่มีอยู่สามารถใช้ได้ สตรีม 3 และ 4 เป็นสำเนา 1 ( stdout
) และ 2 ( stderr
) ตามลำดับ สิ่งนี้อนุญาตให้เอาต์พุตของls
การส่งผ่านเป็นปกติไปยังstdout
และstderr
ผ่าน 3 และ 4 ในขณะที่เอาต์พุตของtime
(ซึ่งไปตามปกติstderr
) ถูกเปลี่ยนเส้นทางไปยังต้นฉบับstdout
(1) จากนั้นถูกดักจับในตัวแปรโดยใช้การแทนที่คำสั่ง อย่างที่คุณเห็นในตัวอย่างของฉันชื่อไฟล์bar
และbaz
เอาต์พุตไปยังเทอร์มินัล ...
-
เมื่อเสร็จแล้วลำธารพิเศษถูกปิดใช้ต่อท้าย
เวลาเขียนเอาต์พุตไปยัง STDERR มากกว่า STDOUT การทำให้เรื่องแย่ลงโดยค่าเริ่มต้น 'time' เป็นคำสั่ง shell builtin ดังนั้นหากคุณลอง 'time ls 2> & 1' the '2> & 1' จะใช้กับ 'ls' เท่านั้น
วิธีแก้ปัญหาอาจเป็นดังนี้:
/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')
มีวิธีแฟนซีมากกว่าที่จะทำ แต่นั่นเป็นวิธีที่ชัดเจน / ง่าย
@Dennis Williamson คำตอบนั้นยอดเยี่ยม แต่ก็ไม่ได้ช่วยให้คุณเก็บผลลัพธ์ของคำสั่งไว้ในตัวแปรเดียวและเอาท์พุทของtime
ตัวแปรอื่น สิ่งนี้ไม่สามารถทำได้โดยใช้ file descriptors
หากคุณต้องการบันทึกระยะเวลาที่โปรแกรมใช้ในการทำงานคุณสามารถทำได้โดยเพียงแค่ลบเวลาเริ่มต้นจากเวลาสิ้นสุด นี่คือตัวอย่างง่ายๆที่แสดงจำนวนมิลลิวินาทีที่โปรแกรมใช้ในการทำงาน:
START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
นี่ไม่ค่อยแม่นยำเท่าtime
คำสั่ง แต่ควรทำงานได้อย่างสมบูรณ์แบบสำหรับสคริปต์ทุบตีส่วนใหญ่
น่าเสียดายที่date
คำสั่งของ Mac ไม่รองรับ%N
รูปแบบ แต่คุณสามารถติดตั้งcoreutils
( brew install coreutils
) และใช้งานได้gdate
:
START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
time
; คำตอบของเดนนิสวิลเลียมสันนั้นดีกว่าในเรื่องนั้น