2012-01-12 16 views
6

Duplicar posibles:
Capturing multiple line output to a bash variableShell scripting, tienda de salida del comando en la variable y conservar el formato

tengo lo que es probablemente una cuestión básica de secuencias de comandos, pero no he podido encontrar una respuesta en cualquier lugar que he buscado.

Tengo un script awk que procesa un archivo, y escupe una lista de sistemas deshabilitados. salida cuando llamo manualmente desde la línea de comandos, consigo formateado posterior:

$awk -f awkscript datafile 

The following notifications are currently disabled: 

host: bar 
host: foo 

Estoy escribiendo un guión envoltorio para llamar desde mi crontab, que se desarrollará el guión awk, determinar si hay alguna salida, y envíeme un correo electrónico si hay. Parece que (simplificado):

BODY=`awk -f awkscript datafile` 
if [ -n "$BODY" ] 
then 
echo $BODY | mailx -s "Disabled notifications" [email protected] 
else 
echo "Nothing is disabled" 
fi 

Cuando se realiza de esta manera, y se confirma mediante la adición de un echo $BODY en el guión, la salida es despojado del formato (saltos de línea son principalmente lo que me preocupa), por lo que obtener una salida que se parece a:

The following notitifications are currently disabled: host: bar host: foo 

estoy tratando de encontrar la manera de conservar el formato que está presente si funciono con el comando manualmente.

Cosas que he probado hasta ahora:

echo -e `cat datafile | awkscript` > /tmp/tmpfile 
echo -e /tmp/tmpfile 

He intentado esto porque en mi sistema (Solaris 5.10), utilizando eco sin el -e hace caso omiso de las secuencias de escape estándar como \ n. No funcionó Revisé el archivo tmp y no tiene ningún formato, por lo que el problema está sucediendo al almacenar la salida, no al imprimirla.

BODY="$(awk -f awkscript datafile)" 
echo -e "$BODY" 

yo probamos este, porque todo lo que pude encontrar, incluyendo algunas otras preguntas aquí en stackoverflow dijo que el problema era que la cáscara reemplazaría códigos de espacio en blanco con espacios si no fue citado. No funcionó

He intentado usar printf en lugar de echo, usando $ (comando) en vez de `comando`, y usando un archivo de temp en lugar de una variable para almacenar el resultado, pero nada parece retener el formato.

¿Qué me estoy perdiendo, o hay otra forma de hacerlo que evite este problema?

+0

¿No está utilizando un archivo de salida una opción? – fge

+0

¿Quiere decir que el script awk genera un archivo de salida, en lugar de imprimir el resultado a stdout? Solo estaba investigando qué implicaría eso. Sé que puedo redirigir las acciones de impresión en awk a un archivo, solo tengo que verificar que se agreguen en lugar de clobber. – Madasi

+0

Puede adjuntar a un archivo usando '>>' del shell en lugar de '>'. '>' ciertamente clobbers, pero '>>' se agrega. – fge

Respuesta

8
BODY=`awk -f awkscript datafile` 
if [ -n "$BODY" ] 
then echo "$BODY" | mailx -s "Disabled notifications" [email protected] 
else echo "Nothing is disabled" 
fi 

Tenga en cuenta las comillas dobles en el echo.

Se puede simplificar esta versión, también:

echo -e `cat datafile | awkscript` > /tmp/tmpfile 
echo -e /tmp/tmpfile 

a poco:

tmpfile=/tmp/tmpfile.$$ 
awkscript > $tmpfile 
if [ -s $tmpfile ] 
then mailx -s "Disabled notifications" [email protected] < $tmpfile 
else echo "Nothing is disabled" 
fi 

comillas inversas son útiles (pero mejor escrito como $(cmd args)), pero no tiene que ser utilizado en todas partes.

+0

El primer ejemplo no funciona, ya que la pérdida de formato ocurre al almacenar el valor en $ BODY. Probé esto usando 'echo -e" $ BODY "en un punto. Sin embargo, el segundo y el tercer ejemplo funcionan perfectamente. Cometí un error al probar la redirección a un archivo temporal (mi código de depuración imprimió el valor de la variable incorrecta), así que me perdí de que esto estaba funcionando. Esta es la solución que probablemente implementaré. – Madasi

+0

No use 'echo -e'; ¡usa 'echo'! –

+0

Lo intenté también, el mismo resultado. Estaba usando -e de forma predeterminada porque en mi sistema, al usar echo sin the -e, hace que ignore secuencias de escape como \ n e imprima en su lugar. Probablemente un artefacto de ejecución en la versión de Solaris en la que estoy. Sin embargo, para probar, incluí las líneas 'echo $ BODY' y' echo -e $ BODY' para ver el valor, y obtuve el mismo resultado no formateado de ambos. – Madasi

3

el uso de citas deben trabajar, y lo hace para mí:

$ cat test.sh 
#!/bin/bash -e 

BODY=`cat test.in` 
if [ -n "$BODY" ]; then 
     echo "$BODY" | mailx -s "test" username 
else 
     echo "Nothing" 
fi 

$ cat test.in 

The following notifications are currently disabled: 

host: bar 
host: foo 

$ ./test.sh 
$ 

Y esto me envía un correo electrónico con el formato adecuado.

+0

Probé esto en mi sistema, y ​​está en lo correcto, esto da un correo electrónico con el formato correcto. – Madasi

+0

Parece que un archivo intermedio, ya sea un archivo temporal para la salida o la prueba formateada.in embargo, mantiene el formato cuando se agrega al valor de una variable, pero la salida formateada en stdout no mantiene el formato cuando se coloca directamente en una variable. – Madasi

Cuestiones relacionadas