2010-03-26 32 views
5

Im viết một bash-script để thực hiện sao lưu ngoại vi, sử dụng rsync qua SSH. Tôi có thể gửi STDOUT để logger, cho các bản ghi thông quaGửi STDERR đến logger

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ [email protected]:backup | logger -i 

Nhưng tôi muốn gửi STDERR thay vào đó, vì vậy nếu có một vấn đề, chẳng hạn như offsite không có sẵn, đầu ra phải được gửi đến logger và đăng nhập.

+0

Có thể bạn có nghĩa là “cả stdout và stderr” chứ không phải “STDERR thay thế”. –

+0

thực sự tôi chỉ sau stderr, vì nó không nên tạo ra bất kỳ đầu ra nào khác. – Gnutt

Trả lời

5

Nếu bạn muốn stderr thay vì stdout (chứ không phải stderr và stdout), bạn có thể làm như sau:

  1. mở thêm mô tả tập tin (9)
  2. chuyển hướng stdout (1) để mô tả tập tin mới (9)
  3. chuyển hướng stderr (2) để stdo ut (1)

nào trông như thế này:

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ [email protected]:backup 9> /dev/null 1>&9 2>&1 | logger -i 

Cách khác, bạn có thể sử dụng thay thế tiến trình:

logger -i <(rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ [email protected]:backup > /dev/null) 
6

Bạn có thể chuyển hướng mô tả thiết bị lỗi chuẩn (2) để STDOUT (1) bằng cách thêm 2>&1, ví dụ:

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ [email protected]:backup 2>&1 | logger -i 
+0

Đó là 2> & 1 sẽ thực hiện điều đó. –

+0

@James right; chỉnh sửa để làm rõ rằng điểm –

2

Một cách khác đảm bảo lỗi kịch bản của bạn đang bị bắt cũng như lỗi rsync, là thực hiện một việc như sau:

#!/bin/bash 

set -eu 
set -o pipefail 

exec 1>/dev/null 2> >(logger -t "stderr-from-my-script") 

: do some interesting things 

rsync --del -az -e 'ssh -i mycrt.crt' /home/gnutt/backup/ [email protected]:backup 

: do some other interesting things 

Bây giờ, tất cả dữ liệu được viết cho stderr sẽ được ghi lại, không chỉ từ rsync. Tuy nhiên, bỏ qua stdout thường là một ý tưởng tồi khi nói đến gỡ lỗi, vì thông tin hữu ích có thể làm nổi bật nguyên nhân gây ra lỗi có thể được ghi lại ở đó. Nếu bạn muốn phân biệt giữa stderr và stdout, chỉ không qua suối:

exec 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script") 

Để đóng một cách rõ ràng xử lý hoặc khôi phục chúng, hãy xem xét những điều sau đây:

exec {OLD_STDOUT}>&1 {OLD_STDERR}>&2 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script") 

: Do some interesting things 

eval exec 1>&${OLD_STDOUT} 2>&${OLD_STDERR} ${OLD_STDOUT}>&- ${OLD_STDERR}>&- 

Đối với các phiên bản cũ của bash, bạn có thể phải hơi cùn hơn một chút:

exec 3>&1 4>&2 1> >(logger -t "stdout-from-my-script") 2> >(logger -t "stderr-from-my-script") 

: Do some interesting things 

exec 1>&3 2>&4 3>&- 4>&- 
+0

Cảm ơn đã cho tôi thấy n>> (dothis ...) xây dựng. – fbicknel