Cách chạy lệnh trong nền không có đầu ra trừ khi có lỗi


14

Làm cách nào để chặn đầu ra của lệnh nhưng hiển thị nếu lệnh thoát mã bị lỗi?

Câu trả lời:


17

Thật không may, giả định stderrchỉ được sử dụng cho đầu ra lỗi không phải lúc nào cũng đúng. Thay vào đó, stderrthường được sử dụng cho bất kỳ và tất cả các đầu ra và chẩn đoán tương tác , tức là đầu ra dành cho người dùng đọc trong lời nhắc tương tác 1 . wgetddlà những ví dụ nổi tiếng.

Một số lệnh sẽ cung cấp một cờ (ví dụ -quiethoặc -silent) để chặn đầu ra không lỗi - đọc các trang man của chúng để xem có tồn tại không.


Một quy ước khác giữ thường xuyên hơn là mã thoát : chương trình trả về mã thoát khi thoát. Thông thường là 2 , mã thoát 0cho biết thành công và bất kỳ mã thoát nào khác chỉ ra lỗi.

Với bash, bạn có thể lấy mã thoát của lệnh cuối cùng từ $?biến. Trong fish, sử dụng $statusbiến. Bạn có thể stderrchuyển sang một tệp tạm thời và chỉ in nó nếu xảy ra lỗi. Ví dụ fish:):

command 2>/tmp/outputbuffer
if $status
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

Bạn cũng có thể sử dụng một số phím tắt, nếu bạn không xâu chuỗi các lệnh:

if command 2>/tmp/outputbuffer
    cat /tmp/outputbuffer
rm /tmp/outputbuffer

Hoặc là:

command 2>/tmp/outputbuffer; or cat /tmp/outputbuffer; rm /tmp/outputbuffer;

Bạn cũng có thể dẫn stdoutđến cùng một bộ đệm bằng cách sử dụng 2>&1 >/tmp/outputbuffer.

(Lưu ý: Tôi thực sự không biết fish, vì vậy tôi đang điều chỉnh khái niệm này với những gì tôi có thể tìm thấy trong tài liệu của nó. Cú pháp có thể hơi sai. Ngoài ra, bạn có thể sử dụng mktempđể tạo một tệp tạm thời duy nhất - chạy nó và ghi lại tên tệp trong một biến.)

Nếu bạn cần chạy toàn bộ nền trong trình bao, bạn cũng đang sử dụng tương tác cùng một lúc, thì tốt hơn hết bạn nên viết một tập lệnh để xử lý ẩn tập tin đầu ra và chạy tập lệnh đó trong nền bằng các kỹ thuật tiêu chuẩn ( fish). Heck, bạn có thể đặt một cái gì đó giống như chức năng sau đây ~/.config/fish/config.fish:

function run-silent
    set temp (mktemp)
    if $argv 2>&1 >$temp
        cat $temp
    rm $temp
end

Gọi với run-silent somecommand &(nơi dấu vết &làm cho nó chạy trong nền)

Lưu ý rằng điều này sẽ nuốt mã thoát gốc và sẽ kết xuất cả stdoutstderrtrong trường hợp xảy ra lỗi. Bạn có thể tùy chỉnh nó khi cần thiết.


1 Thậm chí không có gì đảm bảo rằng đầu ra lỗi sẽ không xuất hiện stdout- một số chương trình sẽ kết xuất tất cả đầu ra ở đó!

2 Thật không may, đây vẫn không phải là luôn luôn như vậy - mã thoát được điều khiển hoàn toàn bằng chương trình, và một số sẽ chỉ ra một số điều kiện thành công với phi zero-thoát. Một lần nữa, kiểm tra hướng dẫn.


tinh chỉnh cá nhẹ, có một vị trí đặc biệt để đặt các chức năng trong ~ / .config / fish / chức năng /
Xster

12

Các tiện ích Unix gửi thông báo chung đến stdoutvà thông báo lỗi tới stderr, vì vậy nếu chúng ta chỉ muốn xem thông báo lỗi thì sẽ đủ để ngăn chặn stdoutđể chỉ stderrnhận được đầu ra cho bàn điều khiển.

Cách để làm điều này (trong cả hai bashfish) là nối thêm >/dev/nullvào lệnh. Điều này dẫn đến sự hư vô, nhưng stderr (với thông báo lỗi của bạn) vẫn đi qua bàn điều khiển.

Ví dụ:

Lệnh echo 1 >/dev/nullkhông in gì cả, vì stdoutđầu ra bình thường bị triệt tiêu và không có gì được ghi vào stderr.

Lệnh man doesnotexist >/dev/nullin một thông báo lỗi, bởi vì manviết thông báo lỗi của nó vào stderr.


2

Điều này sẽ chạy lệnh trong nền và ghi lỗi vào tệp nhật ký mà bỏ qua đầu ra bình thường

    command > /dev/null 2> /tmp/example_error.log &
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.