Stderr ống và thiết bị xuất chuẩn cho các lệnh khác nhau (không chỉ với các tệp)


11

Tôi đang tạo một kịch bản sao lưu cho ldap. Tôi muốn các lỗi đi đến một tệp trong / var / log và đầu ra để đi đến một tệp khác trong thư mục sao lưu. Hiện tại tôi đang chuyển hướng đến một tệp tạm thời và sau đó gửi tệp tạm thời đến nhật ký. Tôi muốn làm điều này như là một lớp lót mặc dù ...

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v 2>>/tmp/ldaptmp.err |
  gzip -c > /mnt/backups/ldap/`date +\%Y\%m\%d`.ldif.gz || 
  logger -t ldapbackup -p local6.err error exit $?

cat /tmp/ldaptmp.err | grep -v "ldap_initialize( ldap://ldap.server )" | 
  grep -v "filter: (objectclass=\*)" |
  grep -v "requesting: All userApplication attributes" >$ERR_LOG
rm -f /tmp/ldaptmp.err

Bất kỳ ý tưởng về cách chuyển hướng stderr và stdout đến các đường ống khác nhau để ngưng tụ lệnh này thành 1 dòng? đây có phải là cách tốt hơn không?


1
Hãy xem bản trình diễn này: stackoverflow.com/a/16283739/1765658 hoặc mẫu ý nghĩa khác này: unix.stackexchange.com/a/84012/27653
F. Hauri

Câu trả lời:


10

Như được chỉ ra bởi câu trả lời này tại Unix SE:

My WeirdCommand.sh

#!/bin/bash
echo "1 2   3"
echo "4 5   6" >&2

testRedirection.sh:

#!/bin/bash
(./MyWeirdCommand.sh | cut -f1 >stdout.log) 3>&1 1>&2 2>&3 | cut -f3 >stderr.log

Năng suất hoạt động:

  • stderr.log 6

  • stdout.log 1


24

Trong Bash, bạn có thể sử dụng thay thế quy trình để quản lý các mô tả tệp bổ sung cho bạn. Bạn có thể thấy điều này gọn gàng hơn so với phương pháp hoán đổi mô tả tập tin.

command > >(process_stdout) 2> >(process_stderr)

Lệnh của bạn có thể trông giống như thế này:

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v \
  > >( \
    gzip -c > /mnt/backups/ldap/$(date '+%Y%m%d').ldif.gz || 
    logger -t ldapbackup -p local6.err error exit $?
  ) \
  2> >( \
    grep -Ev "ldap_initialize( ldap://ldap.server )|filter: (objectclass=\*)|requesting: All userApplication attributes" > "$err_log" \
  )

1
Đây là câu trả lời chính xác.
Michael Martinez

Bạn có thể muốn chuyển hướng đầu ra trở lại stderr nếu bạn muốn giữ chuỗi thay vì chuyển hướng đến một tệp, đại loại như thế này: sh f >> (sed -e "s / ^ / stdout: /") 2 >> ( sed -e "s / ^ / stderr: /"> & 2)
James Moore

Tên kỹ thuật của >(process)ký hiệu là gì?
jchook

1
@jchook Tôi sử dụng thuật ngữ trong câu đầu tiên: "thay thế quá trình".
Tạm dừng cho đến khi có thông báo mới.

1

Đây là cách tôi in thiết bị xuất chuẩn và thiết bị xuất chuẩn để phân tách các tệp bằng dấu thời gian (chuyển sang ts từ gói Debian moreutils):

(./my_little_script.pl | ts %F\ %T > out.log) 2>&1 | ts > err.log

PS nếu bạn không có ts, hãy tạo bí danh của riêng bạn:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
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.