ไปป์ stderr และ stdout ไปยังคำสั่งต่าง ๆ (ไม่ใช่เฉพาะกับไฟล์)


11

ฉันกำลังสร้างสคริปต์สำรองสำหรับ ldap ฉันต้องการข้อผิดพลาดในการไปยังไฟล์ใน / var / log และเอาต์พุตเพื่อไปยังไฟล์อื่นในโฟลเดอร์สำรอง ขณะนี้ฉันกำลังเปลี่ยนเส้นทางไปยังไฟล์ชั่วคราวแล้วส่งไฟล์ชั่วคราวไปที่บันทึก ฉันอยากทำสิ่งนี้เป็น 1 ซับแม้ว่า ...

/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

มีแนวคิดใดเกี่ยวกับวิธีเปลี่ยนเส้นทาง stderr และ stdout ไปยังท่อที่แตกต่างกันเพื่อรวมคำสั่งนี้ไว้ใน 1 บรรทัด? หรือมีวิธีที่ดีกว่า


1
ลองดูการสาธิตนี้: stackoverflow.com/a/16283739/1765658หรือตัวอย่างความหมายอื่น ๆ : unix.stackexchange.com/a/84012/27653
F. Hauri

คำตอบ:



24

ใน Bash คุณสามารถใช้การทดแทนกระบวนการเพื่อจัดการ descriptor ไฟล์พิเศษสำหรับคุณ คุณอาจพบว่าคนดูน้อยกว่าวิธีการสลับไฟล์ descriptor

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

คำสั่งของคุณอาจมีลักษณะเช่นนี้:

/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
นี่คือคำตอบที่ถูกต้อง
Michael Martinez

คุณอาจต้องการเปลี่ยนเส้นทางผลลัพธ์กลับไปที่ stderr หากคุณต้องการเก็บสายโซ่แทนที่จะเปลี่ยนเส้นทางไปยังไฟล์บางสิ่งเช่นนี้: sh f>> (sed -e "s / ^ / stdout: /") 2>> ( sed -e "s / ^ / stderr: /"> & 2)
James Moore

ชื่อทางเทคนิคสำหรับ>(process)สัญกรณ์คืออะไร
jchook

1
@ jchook ฉันใช้คำในประโยคแรก: "การทดแทนกระบวนการ"
หยุดชั่วคราวจนกว่าจะมีการแจ้งให้ทราบต่อไป

1

นี่คือวิธีที่ฉันพิมพ์ stdout และ stderr เพื่อแยกไฟล์ด้วย timestamps (pip ไปยัง ts จากแพ็คเกจ Deutututils more):

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

ป.ล. ถ้าคุณไม่มีทีให้ทำนามแฝงของคุณเอง:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.