Có cách nào để chuyển hướng đầu ra thành một tệp mà không cần đệm trên unix / linux không?


49

Tôi có một quy trình xử lý hàng loạt chạy dài, đưa ra một số gỡ lỗi và xử lý thông tin cho thiết bị xuất chuẩn. Nếu tôi chỉ chạy từ một thiết bị đầu cuối, tôi có thể theo dõi "nó ở đâu" nhưng sau đó dữ liệu sẽ bị quá nhiều và cuộn khỏi màn hình.

Nếu tôi chuyển hướng đến đầu ra thành một tệp '> out.txt' thì cuối cùng tôi cũng nhận được toàn bộ đầu ra nhưng nó được đệm để tôi không còn có thể thấy những gì nó đang làm ngay bây giờ.

Có cách nào để chuyển hướng đầu ra nhưng làm cho nó không đệm ghi?


1
Bạn có thể vui lòng xem "cuộc tranh luận" của tôi (và @cnst) bên dưới không, tôi đoán điều duy nhất bạn muốn là xem đầu ra cùng lúc với việc ghi nó vào một tệp. Nếu bạn tìm thấy một giải pháp, hãy cho chúng tôi biết về nó;)!
Benj

2
câu hỏi nâng
Trevor Boyd Smith

Câu trả lời:


52

Bạn có thể đặt rõ ràng các tùy chọn đệm của các luồng tiêu chuẩn bằng cách sử dụng setvbufcuộc gọi trong C (xem liên kết này ), nhưng nếu bạn đang cố gắng sửa đổi hành vi của một chương trình thử stdbuf( coreutilsrõ ràng là bắt đầu với phiên bản 7.5).

Bộ đệm này stdoutlên đến một dòng:

stdbuf -oL command > output

Điều này vô hiệu hóa stdoutbộ đệm hoàn toàn:

stdbuf -o0 command > output

aaarghhh ... Ubuntu của tôi chỉ có 7,4
lõi

@Calmarius: biên dịch coreutils nên khá dễ dàng. Chỉ cần lấy một phiên bản mới từ ftp.gnu.org/gnu/coreutils và thử nó. Đó là ./configure && makegiá vé tiêu chuẩn . Bạn thậm chí không phải cài đặt nó sau đó, bạn chỉ có thể sử dụng stdbuftắt nhị phân src/.
Eduardo Ivanec

đôi argh. Tôi cần điều này trên một bản phân phối centos cũ VÀ OSX cũng như Ubuntu.
edk750

câu trả lời nâng
Trevor Boyd Smith

Có cách nào để buộc bộ đệm ống / printf ra bên ngoài cho quá trình đã chạy với PID đã biết không?
Mvorisek

9

Bạn có thể đạt được đầu ra được đệm vào một tệp bằng cách sử dụng scriptlệnh như vậy:

stty -echo -onlcr   # avoid added \r in output
script -q /dev/null batch_process | tee output.log        # Mac OS X, FreeBSD
script -q -c "batch_process" /dev/null | tee output.log   # Linux
stty echo onlcr

-1 vì: a) không giống như câu trả lời được chấp nhận, điều này không hoạt động nếu bạn muốn chạy lệnh ở chế độ nền (lệnh ngay lập tức chấm dứt mà không kết thúc batch_processnếu bạn nối &vào lệnh trên, ít nhất là trên hộp Linux của tôi), có vẻ như giống như một trường hợp sử dụng cực kỳ phổ biến và b) không có lời giải thích nào ở đây về cách thức hoạt động của câu thần chú này.
Đánh dấu Amery

8

Trên Ubuntu, gói unbufferchương trình (từ expect-dev) đã thực hiện thủ thuật cho tôi. Chỉ cần chạy:

unbuffer your_command

và nó sẽ không đệm nó.


6

Giải pháp đơn giản nhất mà tôi tìm thấy (không cần bất kỳ gói bên thứ ba nào được cài đặt) đã được đề cập trong một chủ đề tương tự trên trang web Unix & Linux : sử dụng scriptlệnh. Nó đã cũ và có khả năng đã được cài đặt.

$ script -q /dev/null long_running_command | print_progress       # FreeBSD, Mac OS X
$ script -q -c "long_running_command" /dev/null | print_progress  # Linux

Lưu ý rằng tham số tên tệp đầu tiên cho scriptlệnh là tệp nhật ký được ghi . Nếu bạn chỉ đơn giản chạy script -q your_command, bạn sẽ ghi đè lệnh bạn đã thụt lề để chạy với tệp nhật ký. Kiểm tra man script, để được an toàn, trước khi thử nó.


4

thử scriptlệnh; nếu hệ thống của bạn có nó, nó sẽ lấy một tên tệp làm đối số, tất cả văn bản được đổ vào thiết bị xuất chuẩn sẽ được sao chép vào tệp. Nó rất hữu ích khi một chương trình thiết lập yêu cầu tương tác.


Tôi biết thủ thuật 'script -a out.txt'. Tôi đã tự hỏi nếu có bất kỳ cách nào khác để làm cho quá trình viết không đệm.
James Dean

3

Cá nhân tôi thích đầu ra đường ống của một lệnh tôi muốn kiểm tra thông qua tee.

scriptghi lại quá nhiều thông tin, bao gồm cả thời gian nhấn phím và rất nhiều ký tự không in được. Những gì teetiết kiệm được nhiều người có thể đọc được cho tôi.


Tôi cũng sẽ thêm "| less" vào dòng lệnh.
HUB

4
Tôi khá chắc chắn rằng teecũng bị ảnh hưởng bởi bộ đệm. Tôi thường xuyên vẫn nhận được một phần dòng được hiển thị bởi tee khi tách đầu ra từ findcác lệnh.
Magellan

2

Chuyển hướng đầu ra thành một tệp và làm theo tệp bằng tail -flệnh.

Biên tập

Nếu điều này vẫn bị đệm, thì hãy sử dụng tiện ích nhật ký hệ thống (thường không có bộ đệm). Nếu quá trình bó chạy như một kịch bản shell, bạn có thể sử dụng lệnh logger để làm điều này. Nếu công việc hàng loạt chạy bằng ngôn ngữ kịch bản, dù sao cũng nên có một cơ sở ghi nhật ký.


3
Đây là những gì tôi làm ngay bây giờ nhưng quá trình đệm ghi vào tệp và đó chỉ là những gì tôi muốn tránh.
James Dean

Xem chỉnh sửa của tôi cho một đề xuất cập nhật.
wolfgangsz

1
Điều này không hoạt động vì lý do rõ ràng. Ai là địa ngục đưa ra This answer is usefulcâu trả lời không hoạt động, và không thể làm việc?
cnst

1

Bạn có thể sử dụng teelệnh, chỉ cần phép thuật!

someCommand | tee logFile.logcả hai sẽ hiển thị trong bàn điều khiển và ghi vào tệp nhật ký.


Không hoạt động. teesẽ không ngăn chặn bất kỳ bộ đệm nào diễn ra.
cnst

1
@cnst Hiệu quả, teesẽ không tránh được một số bộ đệm mà sẽ chỉ cho phép bạn xem đầu ra là gì. Đây là những gì @JamesDean muốn (vì tôi đánh giá thấp câu hỏi của anh ấy), nhưng tôi nghĩ rằng bộ đệm không thực sự là vấn đề ở đây. Nếu bạn có thêm chi tiết, hãy cho tôi biết.
Benj

Anh ta muốn xem đầu ra, và anh ta không nhận được bất kỳ đầu ra nào (theo cách không có bộ đệm), nhưng bạn có đề nghị sử dụng teeđể có cái nhìn rõ hơn về đầu ra mà người ta không nhận được không?
cnst

1
Làm thế nào tôi đỏ câu hỏi @JamesDean: "Tôi chuyển hướng đến đầu ra cho một tệp '> out.txt'" có nghĩa là đối với tôi không có đầu ra giao diện điều khiển, hãy đợi quá trình hoàn tất trong khi toàn bộ đầu ra được chuyển hướng. Khi bạn đang sử dụng, >bạn không thấy bất cứ điều gì trên bảng điều khiển. Tôi đoán @JamesDean đang sử dụng từ "đệm" để mô tả điều đó. Tôi sẽ đăng một bình luận về câu hỏi của anh ấy để anh ấy nói thêm về những gì anh ấy muốn.
2013
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.