Chuyển hướng đầu ra của một lệnh trong `lệnh thời gian`


11

Tôi đang cố gắng để thời gian một cái gì đó bằng cách sử dụng:

/usr/bin/time myCommand

Tuy nhiên, kể từ khi /usr/bin/timeghi vào stderr, nếu myCommand cũng ghi vào stderr, tôi sẽ nhận được nhiều hơn chỉ là thời gian đầu ra trên luồng. Những gì tôi muốn làm là, chuyển hướng tất cả đầu ra của myCommand sang /dev/null, nhưng vẫn ghi đầu ra của thời gian vào stderr. Sử dụng một ví dụ myCommand ghi vào stderr ls /nofile, chúng ta thấy rằng (rõ ràng) không có đầu ra nào cả với những điều sau đây:

$ /usr/bin/time ls /nofile 2> /dev/null
$

Không có bất kỳ sự chuyển hướng nào, chúng ta sẽ thấy cả đầu ra từ ls(đến stderr) và đầu ra theo thời gian (cũng đến stderr):

$ /usr/bin/time ls /nofile
ls: cannot access /nofile: No such file or directory
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3776maxresident)k
0inputs+0outputs (0major+278minor)pagefaults 0swaps

Những gì tôi muốn là một cái gì đó chỉ đơn giản là sản xuất:

$ /usr/bin/time ls /nofile > RedirectThatImAskingFor
0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 3776maxresident)k
0inputs+0outputs (0major+278minor)pagefaults 0swaps

Có ý kiến ​​gì không?


Tôi đang sử dụng lệnh thời gian trong tập tin kịch bản. tôi muốn đầu ra thời gian trong thiết bị xuất chuẩn thay vì thiết bị xuất chuẩn. Làm thế nào tôi có thể nhận được điều này?

Câu trả lời:


20

Trong ksh, bash và zsh, timelà một từ khóa, không phải là nội dung. Các chuyển hướng trên cùng một dòng chỉ áp dụng cho lệnh được định thời gian, không áp dụng cho đầu ra của timechính nó.

$ time ls -d / /nofile >/dev/null 2>/dev/null

real    0m0.003s
user    0m0.000s
sys     0m0.000s

Để chuyển hướng đầu ra từ timechính nó trong các shell này, bạn cần sử dụng một cấp độ nhóm bổ sung.

{ time mycommand 2>&3; } 3>&2 2>mycommand.time

Nếu bạn sử dụng phiên bản GNU của timetiện ích độc lập , nó có -otùy chọn để ghi đầu ra của timenơi khác ngoài stderr. Bạn có thể timeghi vào thiết bị đầu cuối:

/usr/bin/time -o /dev/tty mycommand >/dev/null 2>/dev/null

Nếu bạn muốn giữ đầu ra từ timelỗi tiêu chuẩn của nó, bạn cần thêm một mức độ xáo trộn mô tả tệp.

/usr/bin/time -o /dev/fd/3 mycommand 3>&2 >/dev/null 2>/dev/null

Với bất kỳ timetiện ích nào , bạn có thể gọi một trình bao trung gian để thực hiện các chuyển hướng mong muốn. Gọi một lớp vỏ trung gian để thực hiện các hành động bổ sung như cdchuyển hướng, v.v. là khá phổ biến - đó là loại việc nhỏ mà vỏ được thiết kế để thực hiện.

/usr/bin/time sh -c 'exec mycommand >/dev/null 2>/dev/null'

Một vài lần theo dõi: 1) 'Người thực hiện' trong đề xuất cuối cùng của bạn làm gì? Nó dường như hoạt động mà không có nó: / usr / bin / time sh -c 'exec ls / nofile &> ./ output.dat' 2) Là một "lớp vỏ trung gian" giống như một "lớp con" (mà bạn sẽ nhận được nghĩ sử dụng dấu ngoặc đơn?). Tôi đã thử những thứ như / usr / bin / time (ls / nofile &> ./ output.dat) nhưng không có kết quả. 3) / dev / tty là gì? Tôi biết tty0 là stdin, tty1 = stdout, tty2 = stderr, nhưng còn 'tty' thì sao?
David Doria

4) Với tùy chọn / dev / fd3, có vẻ như bạn đang nói viết đầu ra -o thành 3, sau đó chuyển hướng 3 đến 2, 1 thành null và 2 thành null. Không nên gửi 3 đến null vì các chuyển hướng xảy ra từ trái sang phải?
David Doria

1
@DavidDoria execthay thế shell bằng chương trình đã chỉ định thay vì chạy chương trình đó dưới dạng quy trình con. Một số shell thực hiện tối ưu hóa này tự động khi một lệnh là lệnh cuối cùng trong tập lệnh. Vỏ trung gian của Nhật Bản có nghĩa là: vỏ nằm giữa timemycommand; nó không liên quan đến subshells. /dev/ttylà thiết bị đầu cuối mà lệnh đang chạy (nó không liên quan đến /dev/ttyNUMcác bảng điều khiển vật lý; bạn đang nhầm lẫn với các mô tả tệp: stdin là /dev/fd/0, v.v.).
Gilles 'SO- ngừng trở nên xấu xa'

@DavidDoria Thay đổi những gì một bộ mô tả tập tin được kết nối xảy ra từ trái sang phải, điều này có tác dụng ngược lại. Xem unix.stackexchange.com/questions/23964/... hoặc unix.stackexchange.com/questions/37660/order-of-redirections
Gilles 'Somali dừng tà ác'

0
[artur@asus-ux21e ~]$ find /etc/pki/CA/private/
/etc/pki/CA/private/
find: ‘/etc/pki/CA/private/’: Permission denied
[artur@asus-ux21e ~]$ time (find /etc/pki/CA/private/ &> /dev/null)

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

Đó không phải là 'thời gian' giống nhau (đó là bí danh bash tôi tin). Lưu ý rằng nó không tuân theo bất kỳ quy tắc chuyển hướng hợp lý nào? $ time &> / dev / null thực 0m0.000s người dùng 0m0.000s sys 0m0.000s
David Doria

1
Làm thế nào về điều này: / usr / bin / time -o time / usr / bin / find / etc / pki / CA / private / &> / dev / null; thời gian mèo
Artur Szymczak

Phải, tôi đã thấy điều đó, nhưng tôi chỉ tò mò hơn về cách thực hiện mà không cần sử dụng một cơ chế nội bộ như -o.
David Doria

@DavidDoria Điều gì mang lại cho bạn ấn tượng đó timelà bí danh bash? which timehiển thị /usr/bin/timetrong CentOS 5.7.
Timothy Martin

type timesẽ cho bạn thấy:time is a shell keyword
Artur Szymczak
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.