Tengo un archivo bash que necesito para redirigir toda la salida a un archivo, el registro de depuración y el terminal. Necesito redirigir stdout y stderr a la depuración y registrarlo para todos los comandos en el script.
No quiero agregar 2>&1 | tee -a $DEBUG
para cada comando en el archivo. Yo podría vivir con | tee -a $DEBUG
.
Recuerdo que había una manera de hacerlo con algo así exec 2>&1
.
Actualmente estoy usando algo como lo siguiente:
#!/bin/bash
DEBUGLOG=/tmp/debug
exec 2>&1
somecommand | tee -a $DEBUGLOG
somecommand2 | tee -a $DEBUGLOG
somecommand3 | tee -a $DEBUGLOG
Pero no funciona. ¿Alguien tiene una solución / puede explicar la causa?
bash
io-redirection
Avi
fuente
fuente
|&
funciona como un atajo para2>&1 |
, es al menos un poco más conveniente.Respuestas:
En cuanto a una solución para redirigir muchos comandos a la vez:
Por qué su solución original no funciona: exec 2> & 1 redirigirá la salida de error estándar a la salida estándar de su shell, que, si ejecuta su script desde la consola, será su consola. la redirección de la tubería en los comandos solo redirigirá la salida estándar del comando.
Desde el punto de vista de
somecommand
, su salida estándar entra en una tubería conectadatee
y el error estándar entra en el mismo archivo / pseudofile que el error estándar del shell, que redirige a la salida estándar del shell, que será el consola si ejecuta su programa desde la consola.La única forma verdadera de explicarlo es ver lo que realmente sucede:
El entorno original de su shell podría verse así si lo ejecuta desde la terminal:
Después de redirigir el error estándar a la salida estándar (
exec 2>&1
), usted ... básicamente no cambia nada. Pero si redirige la salida estándar del script a un archivo, terminaría con un entorno como este:Luego, redirigir el error estándar del shell a la salida estándar terminaría así:
Ejecutar un comando heredará este entorno. Si ejecuta un comando y lo canaliza al tee, el entorno del comando sería:
Por lo tanto, el error estándar de su comando todavía entra en lo que el shell usa como error estándar.
En realidad, puede ver el entorno de un comando mirando
/proc/[pid]/fd
: usels -l
también para enumerar el contenido del enlace simbólico. El0
archivo aquí es entrada estándar,1
salida estándar y2
error estándar. Si el comando abre más archivos (y la mayoría de los programas lo hacen), también los verá. Un programa también puede elegir redirigir o cerrar su entrada / salida estándar y reutilizar0
,1
y2
.fuente
Puede usar exec como este en la parte superior de su script:
Por ejemplo:
Me da salida al archivo
$HOME/somefile.log
y al terminal de esta manera:fuente
/bin/sh
scripts (muchas personas usan erróneamente la sintaxis bash en los/bin/sh
scripts)./dev/fd/62: Operation not supported
alguna pista?myscript
y ejecuto./myscript > /dev/null
, aún debería ver debye
dónde provieneecho bye >&2
.Escriba stderr y stdout en un archivo, muestre stderr en la pantalla (en stdout)
Útil para crons, por lo que puede recibir errores (y solo errores) por correo
fuente