Làm thế nào để chạy thời gian trên nhiều lệnh VÀ ghi đầu ra thời gian vào tệp?


66

Tôi muốn chạy timelệnh để đo thời gian của một số lệnh.

Điều tôi muốn làm là:

  • Đo thời gian chạy của tất cả chúng được thêm vào với nhau
  • Viết timeđầu ra vào một tập tin
  • Viết STDERRtừ lệnh tôi đang đo đếnSTDERR

Điều tôi KHÔNG muốn làm là

  • Viết một số lệnh thành một tập lệnh riêng biệt (tại sao? Bởi vì tất cả những điều này đã là một tập lệnh mà tôi đang tạo theo chương trình và việc tạo tập lệnh tạm thời KHÁC sẽ lộn xộn hơn tôi muốn)

Những gì tôi đã cố gắng cho đến nay:

/usr/bin/time --output=outtime -p echo "a"; echo "b";

Không hoạt động, timechỉ chạy trên cái đầu tiên.

/usr/bin/time --output=outtime -p ( echo "a"; echo "b"; )

Không hoạt động, (là mã thông báo bất ngờ.

/usr/bin/time --output=outtime -p { echo "a"; echo "b"; }

Không hoạt động, "không có tập tin hoặc thư mục như vậy".

/usr/bin/time --output=outtime -p ' echo "a"; echo "b";'

Không hoạt động, "không có tập tin hoặc thư mục như vậy".

time ( echo "a"; echo "b"; ) 2>outtime

Không hoạt động, vì nó chuyển hướng tất cả STDERRvào outtime; Tôi chỉ muốn timeđầu ra ở đó.

Và dĩ nhiên,

time --output=outime echo "a";

Không hoạt động, kể từ đó --output=outime: command not found.

Tôi làm nó như thế nào?

Câu trả lời:


90

Sử dụng sh -c 'commands'như lệnh, ví dụ:

/usr/bin/time --output=outtime -p sh -c 'echo "a"; echo "b"'

2
phiên bản ngắn hơn:time -p sh -c 'echo "a"; echo "b"'
Geo

8

Thử đi:

% (time ( { echas z; echo 2 } 2>&3 ) ) 3>&2 2>timeoutput
zsh: command not found: echas
2
% cat timeoutput                                
( { echas z; echo 2; } 2>&3; )  0.00s user 0.00s system 0% cpu 0.004 total

Giải trình:

Đầu tiên, chúng ta phải tìm cách chuyển hướng đầu ra time. Vì timelà shell dựng sẵn, nó lấy dòng lệnh đầy đủ làm lệnh cần đo, bao gồm cả chuyển hướng. Do vậy,

% time whatever 2>timeoutput
whatever 2> timeoutput  0.00s user 0.00s system 0% cpu 0.018 total
% cat timeoutput 
zsh: command not found: whatever

[Lưu ý: Nhận xét của janos ngụ ý đây không phải là trường hợp bash.] Chúng ta có thể đạt được sự chuyển hướng timeđầu ra của bằng cách chạy timetrong một khung con và sau đó chuyển hướng đầu ra của vỏ con đó.

% (time whatever) 2> timeoutput
% cat timeoutput 
zsh: command not found: whatever
whatever  0.00s user 0.00s system 0% cpu 0.018 total

Bây giờ chúng tôi đã chuyển hướng thành công đầu ra của time, nhưng đầu ra của nó được trộn lẫn với đầu ra lỗi của lệnh chúng tôi đang đo. Để tách hai, chúng tôi sử dụng một mô tả tập tin bổ sung.

Ở "bên ngoài" chúng ta có

% (time ... ) 3>&2 2>timeout

Điều này có nghĩa là: bất cứ điều gì được ghi vào bộ mô tả tệp 3, sẽ được xuất ra cùng một nơi mô tả tệp 2 (lỗi tiêu chuẩn) hiện đang xuất ra (thiết bị đầu cuối). Và sau đó chúng tôi chuyển hướng lỗi tiêu chuẩn đến tập tin timeout.

Vì vậy, bây giờ chúng ta có: mọi thứ được ghi vào thiết bị xuất chuẩn và fd 3 sẽ chuyển đến thiết bị đầu cuối và mọi thứ được viết cho thiết bị lỗi chuẩn sẽ chuyển đến tệp. Những gì còn lại là để chuyển hướng stderr của lệnh đo sang fd 3.

% (time whatever 2>&3) 3>&2 2>timeout

Bây giờ, để làm cho thời gian đo nhiều hơn một lệnh, chúng ta cần chạy chúng trong một lớp con (khác!) (Bên trong dấu ngoặc đơn). Và để chuyển hướng đầu ra lỗi của tất cả chúng sang fd 3, chúng ta cần nhóm chúng trong dấu ngoặc nhọn.

Vì vậy, cuối cùng, chúng tôi đến:

% (time ( { whatever; ls } 2>&3 ) ) 3>&2 2>timeoutput

Đó là nó.


Đây là một lỗi cú pháp trong trình bao POSIX. Có lẽ là một bashism?
josch

@josch cái vỏ dùng ở đây là zsh.
angus

6

Không phải câu trả lời đúng nhưng rất liên quan đến câu hỏi.
Nhận thống kê thời gian cho nhiều chương trình dấu ngoặc đơn kết hợp được yêu cầu. Các lệnh riêng biệt với dấu chấm phẩy.

time ( command1 ; command2 )

1
Cái này đẹp đấy. Tốt hơn hết, hãy sử dụng && giữa các lệnh - như vậy time ( command1 && command2 )để nếu lệnh đầu tiên thất bại; nó sẽ không tiến hành để thực hiện khác.
bikashg
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.