Chuyển hướng đầu ra của lệnh thời gian trong unix thành một biến trong bash?


13

Tôi chỉ muốn nắm bắt đầu ra của một lệnh thời gian tức là:

X=$(time ls)

hoặc là

$(time ls) | grep real

Các chức năng thời gian nhổ nó vào giao diện điều khiển mặc dù. Làm thế nào để tôi làm điều này?

Câu trả lời:


12

X = `(thời gian ls) 2> & 1 | grep thật`


Bạn không cần một subshell chỉ cho time; Câu trả lời của Dennis Williamson là tốt hơn trong vấn đề đó.
musiphil

11

Xem 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>&-

Thời gian sẽ giống như "0,000" sử dụng TIMEFORMAT="%R"sẽ là thời gian "thực".


bạn có thể giải thích một chút làm thế nào điều này làm việc? Tôi đã sử dụng một đoạn như kiểu sùng bái hàng hóa này trong nhiều năm. Dòng 3 và 4 là gì? và '-' ?
Sirex

1
@Sirex: Luồng 3 và 4 là các luồng được tạo bởi execlệnh trong câu trả lời của tôi bằng cách sử dụng các mô tả tệp có sẵn. Bất kỳ mô tả tập tin có sẵn có thể được sử dụng. Luồng 3 và 4 lần lượt là các bản sao của 1 ( stdout) và 2 ( stderr). Điều này cho phép đầu ra của lschuyển qua bình thường đến stdoutstderrqua 3 và 4 trong khi đầu ra của time(thường đi đến stderr) được chuyển hướng đến gốc stdout(1) và sau đó được bắt trong biến bằng cách sử dụng thay thế lệnh. Như bạn có thể thấy trong ví dụ của tôi, tên tệp barbazlà đầu ra cho thiết bị đầu cuối. ...
Tạm dừng cho đến khi có thông báo mới.

1
... Sau khi kết thúc, các luồng bổ sung được đóng lại bằng cách sử dụng dấu -.
Tạm dừng cho đến khi có thông báo mới.

4

Thời gian ghi đầu ra của nó vào STDERR chứ không phải STDOUT. Làm cho vấn đề tồi tệ hơn, theo mặc định 'thời gian' là lệnh dựng sẵn shell, vì vậy nếu bạn cố gắng 'thời gian ls 2> & 1' thì '2> & 1' chỉ áp dụng cho 'ls'.

Giải pháp có thể là một cái gì đó như:

/usr/bin/time -f 'real %e' -o OUTPUT_FILE ls > /dev/null 2>&1<br>
REALTIME=$(cat OUTPUT_FILE | cut -f 2 -d ' ')

Có nhiều cách lạ mắt hơn để làm điều đó, nhưng đó là cách rõ ràng / đơn giản.


Tôi thích làm điều này mà không -o. Bạn có thể đăng một trong những phương pháp ưa thích mà bạn đã nghĩ đến :)?
David Doria

0

Câu trả lời của @Dennis Williamson rất hay, nhưng nó không giúp bạn lưu trữ đầu ra của lệnh trong một biến và đầu ra của timemột biến khác. Điều này thực sự là không thể sử dụng mô tả tập tin.

Nếu bạn muốn ghi lại thời gian một chương trình chạy, bạn có thể làm điều này bằng cách trừ thời gian bắt đầu từ thời gian kết thúc. Dưới đây là một ví dụ đơn giản cho thấy chương trình đã chạy bao nhiêu mili giây:

START_TIME=$(date +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(date +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"

Điều này không hoàn toàn chính xác như timelệnh, nhưng nó sẽ hoạt động hoàn toàn tốt đối với hầu hết các tập lệnh bash.

Thật không may, datelệnh của Mac không hỗ trợ %Nđịnh dạng, nhưng bạn có thể cài đặt coreutils( brew install coreutils) và sử dụng gdate:

START_TIME=$(gdate +%s%3N)
OUTPUT=$(ls -l)
ELAPSED_TIME=$(expr $(gdate +%s%3N) - $START_TIME)
echo "Command finished in $ELAPSED_TIME milliseconds"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.