Трубопроводити 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 або цей інший змістовий
Ф. Хаурі

Відповіді:



24

У Bash ви можете використовувати підстановку процесу для управління додатковими дескрипторами файлів для вас. Ви можете виявити це трохи акуратніше, ніж метод підкачки дескриптора файлів.

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
Це правильна відповідь.
Майкл Мартінес

Ви можете перенаправити висновок назад на stderr, якщо ви хочете зберегти ланцюг замість того, щоб перенаправляти на файл, приблизно так: sh f>> (sed -e "s / ^ / stdout: /") 2>> ( sed -e "s / ^ / stderr: /"> & 2)
Джеймс Мур

Яка технічна назва для >(process)позначення?
jchook

1
@jchook Я використовую термін у першому реченні: "процес заміщення".
Призупинено до подальшого повідомлення.

1

Ось так я друкую stdout та stderr для розділення файлів із часовими позначками (пересилання на ts з пакета morebian утиліти Debian):

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

PS, якщо у вас немає ts, зробіть власний псевдонім:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.