Canalice stderr y stdout a diferentes comandos (no solo a archivos)


11

Estoy haciendo un script de respaldo para ldap. Quiero que los errores vayan a un archivo en / var / log y que la salida vaya a otro archivo en la carpeta de copia de seguridad. Actualmente estoy redirigiendo a un archivo temporal y luego envío el archivo temporal al registro. Sin embargo, prefiero hacer esto como 1 liner ...

/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

¿Alguna idea sobre cómo redirigir stderr y stdout a diferentes tuberías para condensar este comando en 1 línea? ¿O hay un mejor camino?


1
Eche un vistazo a esta demostración: stackoverflow.com/a/16283739/1765658 o esta otra muestra de significado: unix.stackexchange.com/a/84012/27653
F. Hauri

Respuestas:


10

Como lo indica esta respuesta en Unix SE:

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

Rendimientos corrientes:

  • stderr.log 6

  • stdout.log 1


24

En Bash, puede usar la sustitución de procesos para administrar los descriptores de archivo adicionales por usted. Puede encontrar esto un poco más ordenado que el método de intercambio de descriptor de archivo.

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

Su comando podría verse más o menos así:

/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
Esta es la respuesta correcta.
Michael Martinez

Es posible que desee redirigir la salida de nuevo a stderr si desea mantener la cadena en lugar de redirigir a un archivo, algo como esto: sh f>> (sed -e "s / ^ / stdout: /") 2>> ( sed -e "s / ^ / stderr: /"> & 2)
James Moore el

¿Cuál es el nombre técnico de la >(process)notación?
jchook

1
@jchook Utilizo el término en la primera oración: "sustitución de proceso".
Pausado hasta nuevo aviso.

1

Así es como imprimo stdout y stderr para separar archivos con marcas de tiempo (canalización a ts desde el paquete Debian moreutils):

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

PD: si no tienes ts, crea tu propio alias:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.