Stderr ve stdout'u farklı komutlara bağlayın (sadece dosyalara değil)


11

Ldap için bir yedek betik yapıyorum. Hataların / var / log içindeki bir dosyaya ve çıktının yedekleme klasöründeki başka bir dosyaya gitmesini istiyorum. Şu anda bir geçici dosyaya yönlendiriyorum ve sonra geçici dosyayı günlüğe gönderiyorum. Bunu 1 astar olarak yapmayı tercih ederim ...

/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

Bu komutu 1 satıra yoğunlaştırmak için stderr ve stdout'un farklı borulara nasıl yönlendirileceği hakkında bir fikriniz var mı? Yoksa daha iyi bir yol var mı?


1
Bu gösteriye bir göz atın: stackoverflow.com/a/16283739/1765658 veya başka bir anlam örneği: unix.stackexchange.com/a/84012/27653
F. Hauri

Yanıtlar:


10

Bu cevapta Unix SE'de belirtildiği gibi:

MyWeirdCommand.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

Koşu verimi:

  • stderr.log 6

  • stdout.log 1


24

Bash'te, sizin için fazladan dosya tanımlayıcılarını yönetmek için işlem ikamesini kullanabilirsiniz. Bunu dosya tanımlayıcı takas yönteminden daha küçük bir daha temiz bulabilirsiniz.

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

Komutunuz şöyle görünebilir:

/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
Bu doğru cevap.
Michael Martinez

Zinciri bir dosyaya yeniden yönlendirmek yerine korumak isterseniz çıktıyı tekrar stderr'e yönlendirmek isteyebilirsiniz: sh f>> (sed -e "s / ^ / stdout: /") 2>> ( sed -e "s / ^ / stderr: /"> & 2)
James Moore

>(process)Gösterimin teknik adı nedir ?
jchook

1
@jchook Bu terimi ilk cümlede kullanıyorum: "süreç ikamesi".
sonraki duyuruya kadar duraklatıldı.

1

Bu nasıl zaman damgaları (Debian moreutils paketinden ts boru) ile dosyaları ayırmak için stdout ve stderr yazdırmak:

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

Not ts yoksa kendi takma adınızı yapın:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.