Câu hỏi Cách chuyển hướng stderr vào một tệp [trùng lặp]


Câu hỏi này đã có câu trả lời ở đây:

Trong khi sử dụng nohup để đặt lệnh chạy trong nền, một số nội dung xuất hiện trong terminal.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

Tôi muốn lưu nội dung đó vào một tệp.


163
2018-05-18 12:31


gốc




Các câu trả lời:


Có hai luồng đầu ra chính trong Linux (và các hệ điều hành khác), đầu ra tiêu chuẩn (stdout) và lỗi chuẩn (stderr). Thông báo lỗi, giống như những thông báo bạn hiển thị, được in ra lỗi chuẩn. Toán tử chuyển hướng cổ điển (command > file) chỉ chuyển hướng đầu ra tiêu chuẩn, do đó lỗi chuẩn vẫn được hiển thị trên thiết bị đầu cuối. Để chuyển hướng stderr, bạn có một vài lựa chọn:

  1. Chuyển hướng stdout sang một tệp và stderr sang một tệp khác:

    command > out 2>error
    
  2. Chuyển hướng stderr sang stdout (&1), và sau đó chuyển hướng stdout vào một tệp:

    command >out 2>&1
    
  3. Chuyển hướng cả hai vào một tệp:

    command &> out
    

Để biết thêm thông tin về các toán tử điều khiển và chuyển hướng khác nhau, hãy xem đây.


265
2018-05-18 12:50



Vì thế hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2> error_hashdeep.txt & hoặc là hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ >> result_hashdeep.txt 2>&1 hoặc là hashdeep -rXvvl -j 30 -k checksums.txt /mnt/app/ &> result_mixed.txt - André M. Faria
@ AndréM.Faria yes. Nhưng hai lệnh cuối cùng là tương đương, chúng sẽ gửi cả lỗi và đầu ra cho cùng một tệp. - terdon♦
Như trong liên kết bạn cung cấp, tôi có thể sử dụng | & thay vì 2> & 1 chúng tương đương, cảm ơn bạn đã dành thời gian. - André M. Faria
Xin chào, tôi đã có thể đơn giản hóa việc này thành: command 2> out. - Surya Teja Karra
@SuryaTejaKarra mà chỉ chuyển hướng stderr, nhưng không stdout. - terdon♦


Điều đầu tiên cần lưu ý là có vài cách tùy thuộc vào mục đích và trình bao của bạn, do đó điều này đòi hỏi sự hiểu biết nhỏ về nhiều khía cạnh. Thông thường, thông qua 2> trong Vỏ giống Bourne, nhu la dash (được liên kết với /bin/sh) và bash; đầu tiên là shell mặc định và tuân thủ POSIX và phần còn lại là phần lớn người dùng sử dụng cho phiên tương tác. Chúng khác nhau về cú pháp và các tính năng, nhưng may mắn cho chúng tôi chuyển hướng luồng lỗi hoạt động giống nhau (ngoại trừ &> không chuẩn). Trong trường hợp của csh và các dẫn xuất của nó, sự chuyển hướng stderr không làm việc ở đó.

Hãy quay lại 2> phần. Hai điều quan trọng cần lưu ý: > có nghĩa là nhà điều hành chuyển hướng, nơi chúng tôi mở một tệp và 2 số nguyên là viết tắt của bộ mô tả tệp stderr; trên thực tế, đây chính xác là cách chuẩn POSIX cho ngôn ngữ shell xác định chuyển hướng trong phần 2.7:

[n]redir-op word

Để đơn giản > chuyển hướng, 1 số nguyên được ngụ ý cho stdout, I E. echo Hello World > /dev/null cũng giống như echo Hello World 1>/dev/null. Lưu ý, rằng toán tử số nguyên hoặc chuyển hướng không thể được trích dẫn, nếu không shell không nhận ra chúng như vậy, và thay vào đó xử lý như chuỗi văn bản. Đối với khoảng trắng, điều quan trọng là số nguyên nằm ngay bên cạnh toán tử chuyển hướng, nhưng tệp có thể nằm bên cạnh toán tử chuyển hướng hoặc không, tức là command 2>/dev/null và command 2> /dev/null sẽ hoạt động tốt.

Cú pháp hơi đơn giản cho lệnh điển hình trong shell sẽ là

 command [arg1] [arg2]  2> /dev/null

Bí quyết ở đây là chuyển hướng có thể xuất hiện ở mọi nơi. Đó là cả hai 2> command [arg1] và command 2> [arg1] có giá trị. Lưu ý rằng đối với bash vỏ, có tồn tại &> cách để chuyển hướng cả hai dòng stdout và stderr cùng một lúc, nhưng một lần nữa - nó bash cụ thể và nếu bạn đang phấn đấu cho tính di động của các kịch bản, nó có thể không hoạt động. Xem thêm Ubuntu Wiki và Sự khác nhau giữa &> và 2> & 1.

Chú thích: Các > -toán tử chuyển hướng cắt ngắnmột tệp và ghi đè tệp đó nếu tệp tồn tại. Các 2>> có thể được sử dụng để thêm vào stderr nộp.

Nếu bạn có thể nhận thấy, > có nghĩa là cho một lệnh duy nhất. Đối với tập lệnh, chúng tôi có thể chuyển hướng luồng stderr của toàn bộ tập lệnh từ bên ngoài như trong myscript.sh 2> /dev/null hoặc chúng ta có thể tận dụng exec được xây dựng trong. Exec được xây dựng trong có sức mạnh để rewire dòng cho toàn bộ phiên shell, do đó, để nói chuyện, cho dù tương tác hoặc thông qua kịch bản. Cái gì đó như

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

Trong ví dụ này, tệp nhật ký sẽ hiển thị stat: cannot stat '/etc/non_existing_file': No such file or directory.

Tuy nhiên, một cách khác là thông qua các chức năng. Như kopciuszek lưu ý trong câu trả lời của mình, chúng ta có thể viết khai báo hàm với chuyển hướng đã được đính kèm, đó là

some_function(){
    command1
    command2
} 2> my_log_file.txt

5
2018-05-03 07:48