Làm cách nào để chuyển hướng đầu ra của lệnh thời gian sang một tệp trong Linux?


202

Chỉ cần một câu hỏi nhỏ về các chương trình thời gian trên Linux: lệnh thời gian cho phép đo thời gian thực hiện của chương trình:

[ed@lbox200 ~]$ time sleep 1

real    0m1.004s
user    0m0.000s
sys     0m0.004s

Mà hoạt động tốt. Nhưng nếu tôi cố chuyển hướng đầu ra thành một tập tin, nó sẽ thất bại.

[ed@lbox200 ~]$ time sleep 1 > time.txt

real    0m1.004s
user    0m0.001s
sys     0m0.004s

[ed@lbox200 ~]$ cat time.txt 
[ed@lbox200 ~]$ 

Tôi biết có các triển khai thời gian khác với tùy chọn -o để viết một tệp nhưng câu hỏi của tôi là về lệnh mà không có các tùy chọn đó.

Bất kỳ đề xuất ?


3
Có thể trùng lặp thời gian thực thi ghi bash script trong một tệp và tôi không tin chắc rằng đây là câu hỏi đầu tiên như vậy.
Jonathan Leffler

1
Đây là bản sao của stackoverflow.com/questions/2408981/
Ấn

Câu trả lời:


266

Thử

{ time sleep 1 ; } 2> time.txt

kết hợp STDERR của "thời gian" và lệnh của bạn vào time.txt

Hoặc dùng

{ time sleep 1 2> sleep.stderr ; } 2> time.txt

trong đó đặt STDERR từ "ngủ" vào tệp "ngủ.stderr" và chỉ STDERR từ "thời gian" đi vào "time.txt"


2
Cảm ơn, câu trả lời chính xác câu hỏi của tôi. Nếu tôi hiểu chính xác, kết quả của lệnh thời gian có thể được lấy từ stderr?
ed82

7
Có, nhưng bạn phải đặt nó trong dấu ngoặc nhọn, nếu không, chuyển hướng sẽ là một phần của lệnh timeđánh giá.
tháng 1

5
@Daniel Bạn luôn có thể chuyển hướng đầu ra lệnh nội bộ một cách riêng biệt (ví dụ {thời gian ngủ 1 2> ngủStdErr.txt;} 2> time.txt) và điều đó sẽ giúp bạn chỉ có đầu ra thời gian. Tôi không chắc có cách nào để có được nó một cách độc lập hay không.
gms7777

10
Nếu bạn muốn sử dụng thời gian với một cái gì đó như grep mà đọc hết stdout hãy thử { time sleep 1; } 2>&1 | grep real. Điều này sẽ gửi stderr đến thiết bị xuất chuẩn mà grep sau đó có thể đọc.
clayzermk1

9
KHÔNG quên ';' ký tự trước khi đóng '}', nó sẽ KHÔNG hoạt động mà không có (tôi đã làm và ... tự hỏi tại sao không hoạt động :))
THESorcerer

38

Gói timevà lệnh bạn đang định thời trong một bộ dấu ngoặc.

Ví dụ: các lần sau lsvà ghi kết quả lsvà kết quả của thời gian vào outfile:

$ (time ls) > outfile 2>&1

Hoặc, nếu bạn muốn tách đầu ra của lệnh khỏi đầu ra đã chụp từ time:

$ (time ls) > ls_results 2> time_results

12
Nó là không cần thiết để giới thiệu một subshell ở đây.
tháng 1

1
@ sampson-chen Điều đó chỉ hoạt động vì ls không viết bất cứ điều gì cho stderr phải không? Làm thế nào bạn "tách" đầu ra của 'thời gian' khỏi lệnh được chạy nếu lệnh ghi vào cả thiết bị xuất chuẩn và thiết bị xuất chuẩn?
David Doria

36

Đơn giản. timeTiện ích GNU có một tùy chọn cho điều đó.

Nhưng bạn phải đảm bảo rằng bạn không sử dụng timelệnh dựng sẵn của shell , ít nhất là bashnội trang không cung cấp tùy chọn đó! Đó là lý do tại sao bạn cần đưa ra đường dẫn đầy đủ của timetiện ích:

/usr/bin/time -o time.txt sleep 1

Bạn cũng có thể sử dụng tính năng không tích hợp mà không chỉ định đường dẫn đầy đủ: stackoverflow.com/questions/29540540/
Kẻ

14

Nếu bạn quan tâm đến đầu ra lỗi của lệnh, bạn có thể tách chúng ra như thế này trong khi vẫn sử dụng lệnh thời gian tích hợp.

{ time your_command 2> command.err ; } 2> time.log

hoặc là

{ time your_command 2>1 ; } 2> time.log

Khi bạn thấy các lỗi của lệnh đi đến một tệp (vì stderrđược sử dụng cho time).

Thật không may, bạn không thể gửi nó đến một tay cầm khác (như 3>&2) vì điều đó sẽ không còn tồn tại bên ngoài{...}

Điều đó nói rằng, nếu bạn có thể sử dụng thời gian GNU, chỉ cần làm những gì @Tim Ludwinski nói.

\time -o time.log command

8

Vì đầu ra của lệnh 'time' là đầu ra lỗi, nên chuyển hướng nó thành đầu ra tiêu chuẩn sẽ trực quan hơn để xử lý thêm.

{ time sleep 1; } 2>&1 |  cat > time.txt

6

Nếu bạn đang sử dụng thời gian GNU thay vì bash tích hợp, hãy thử

time -o outfile command

(Lưu ý: Định dạng thời gian GNU khác một chút so với bash tích hợp).


1
Điều này, cảm ơn bạn. Và bạn có thể sử dụng \time -o outfile command(với ``) để sử dụng GNU thay vì tích hợp.
Đánh dấu

3
&>out time command >/dev/null

trong trường hợp của bạn

&>out time sleep 1 >/dev/null

sau đó

cat out

3
Ý tưởng thanh lịch, nhưng dẫn đến vỏ không sử dụng lệnh tích hợp của nó. Nếu bạn chưa timecài đặt nhị phân thực , outsẽ chứa thứ gì đó như bash: time: command not found.
Scy

Ngoài ra định dạng cho thời gian GNU không giống như nội dung bash, gây ra vấn đề cho việc phân tích cú pháp tự động.
Guss

3

Tôi đã kết thúc bằng cách sử dụng:

/usr/bin/time -ao output_file.txt -f "Operation took: %E" echo lol
  • Trong đó "a" được nối
  • Trong đó "o" được tiến hành bằng tên tệp để nối vào
  • Trong đó "f" là định dạng với cú pháp giống như printf
  • Trong đó "% E" tạo ra 0:00:00; giờ: phút: giây
  • Tôi đã phải gọi / usr / bin / time vì bash "time" đã chà đạp nó và không có cùng tùy chọn
  • Tôi chỉ cố gắng để có được đầu ra cho tập tin, không giống như OP

2
#!/bin/bash

set -e

_onexit() {
    [[ $TMPD ]] && rm -rf "$TMPD"
}

TMPD="$(mktemp -d)"
trap _onexit EXIT

_time_2() {
    "$@" 2>&3
}

_time_1() {
    time _time_2 "$@"
}

_time() {
    declare time_label="$1"
    shift
    exec 3>&2
    _time_1 "$@" 2>"$TMPD/timing.$time_label"
    echo "time[$time_label]"
    cat "$TMPD/timing.$time_label"
}

_time a _do_something
_time b _do_another_thing
_time c _finish_up

Điều này có lợi ích của việc không sinh ra các lớp vỏ phụ, và đường ống cuối cùng đã được stderr khôi phục lại thành stderr thực sự.


0

Nếu bạn không muốn chạm vào thiết bị xuất chuẩn và thiết bị xuất chuẩn ban đầu, bạn có thể chuyển hướng stderr sang mô tả tệp 3 và quay lại:

$ { time { perl -le "print 'foo'; warn 'bar';" 2>&3; }; } 3>&2 2> time.out
foo
bar at -e line 1.
$ cat time.out

real    0m0.009s
user    0m0.004s
sys     0m0.000s

Bạn có thể sử dụng nó cho trình bao bọc (ví dụ: đối với cronjobs) để theo dõi thời gian chạy:

#!/bin/bash

echo "[$(date)]" "$@" >> /my/runtime.log

{ time { "$@" 2>&3; }; } 3>&2 2>> /my/runtime.log

0

Nếu bạn đang sử dụng, cshbạn có thể sử dụng:

/usr/bin/time --output=outfile -p $SHELL  -c 'your command'

Ví dụ:

/usr/bin/time --output=outtime.txt -p csh -c 'cat file'
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.