salida - Script Bash-almacena stderr en una variable
redirect stderr to stdout (4)
Esta pregunta ya tiene una respuesta aquí:
Estoy escribiendo una secuencia de comandos para hacer una copia de seguridad de una base de datos. Tengo la siguiente línea:
mysqldump --user=$dbuser --password=$dbpswd /
--host=$host $mysqldb | gzip > $filename
Quiero asignar el stderr a una variable, de modo que me envíe un correo electrónico para informarme de lo que sucedió si algo sale mal. He encontrado soluciones para redirigir stderr a stdout, pero no puedo hacer eso ya que el stdout ya se está enviando (a través de gzip) a un archivo. ¿Cómo puedo almacenar Stderr por separado en un $ resultado variable?
Intente redirigir stderr a stdout y use $()
para capturar eso. En otras palabras:
VAR=$((your-command-including-redirect) 2>&1)
Como su comando redirige a stdout a alguna parte, no debería interferir con stderr. Puede haber una manera más limpia de escribirlo, pero eso debería funcionar.
Editar:
Esto realmente funciona Lo he probado
#!/bin/bash
BLAH=$((
(
echo out >&1
echo err >&2
) 1>log
) 2>&1)
echo "BLAH=$BLAH"
imprimirá BLAH=err
y el archivo de log
contiene.
Para cualquier comando genérico en Bash, puedes hacer algo como esto:
{ error=$(command 2>&1 1>&$out); } {out}>&1
La salida normal aparece normalmente, cualquier cosa para stderr se captura en $ error (cúmplalo como "$ error" cuando lo use para preservar las nuevas líneas). Para capturar stdout en un archivo, simplemente agregue una redirección al final, por ejemplo:
{ error=$(ls /etc/passwd /etc/bad 2>&1 1>&$out); } {out}>&1 >output
Rompiéndolo, leyendo desde afuera, en él:
- crea una descripción de archivo $ out para todo el bloque, duplicando stdout
- captura el stdout de todo el comando en $ error (pero mira a continuación)
- el comando mismo redirige stderr a stdout (que se captura arriba) luego stdout a la stdout original desde fuera del bloque, por lo que solo stderr se captura
Puede guardar la referencia de stdout antes de que se redirija a otro número de archivo (por ejemplo, 3) y luego redirigir stderr a eso:
result=$(mysqldump --user=$dbuser --password=$dbpswd /
--host=$host $mysqldb 3>&1 2>&3 | gzip > $filename)
Entonces 3>&1
redirigirán el archivo número 3 a stdout (observe esto antes de que stdout sea redirigido con el conducto). Luego 2>&3
redireccionan stderr al archivo número 3, que ahora es el mismo que stdout. Finalmente, stdout se redirige al alimentarlo a un conducto, pero esto no afecta a los números de archivo 2 y 3 (observe que redireccionar el stdout de gzip no está relacionado con las salidas del comando mysqldump).
Editar: mysqldump
el comando para redirigir stderr desde el comando mysqldump
y no gzip
, fui demasiado rápido en mi primera respuesta.
dd
escribe stdout y stderr:
$ dd if=/dev/zero count=50 > /dev/null
50+0 records in
50+0 records out
las dos corrientes son independientes y redirigibles por separado:
$ dd if=/dev/zero count=50 2> countfile | wc -c
25600
$ cat countfile
50+0 records in
50+0 records out
$ mail -s "countfile for you" thornate < countfile
si realmente necesitabas una variable:
$ variable=`cat countfile`