2012-01-12 14 views
6

Eventuali duplicati:
Capturing multiple line output to a bash variableShell scripting, negozio di uscita comando nella variabile e mantenere la formattazione

ho quello che è probabilmente una domanda di base di scripting, ma non sono stato in grado di trova una risposta ovunque io abbia guardato.

Ho uno script awk che elabora un file e sputa un elenco di sistemi disabilitati. Uscita Quando chiamo manualmente dalla riga di comando, vengo formattato indietro:

$awk -f awkscript datafile 

The following notifications are currently disabled: 

host: bar 
host: foo 

Sto scrivendo uno script wrapper per chiamare dal mio crontab, che si svolgerà lo script awk, determinare se non v'è alcun output, e scrivimi se c'è. Sembra (semplificato):

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

Quando eseguito in questo modo, e confermato con l'aggiunta di un echo $BODY nella sceneggiatura, l'uscita è spogliato della formattazione (a capo sono principalmente quello che mi riguarda con), così ho ottenere l'output che assomiglia:

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

sto cercando di capire come mantenere la formattazione che è presente, se faccio funzionare l'ordine manualmente.

Le cose che ho provato finora:

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

Ho provato questo perché sul mio sistema (Solaris 5.10), utilizzando eco senza il -e ignora sequenze di escape standard come \ n. Non ha funzionato Ho controllato il file tmp e non ha alcuna formattazione, quindi il problema si verifica quando si memorizza l'output, non quando lo si stampa.

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

Ho provato questo perché tutto quello che ho trovato, tra cui alcune altre domande qui su StackOverflow ha detto che il problema era che il guscio avrebbe sostituito i codici di spaziatura con spazi se non è stato citato. Non ha funzionato

Ho provato a usare printf invece di echo, usando $ (comando) invece di `command`, e usando un tempfile invece di una variabile per memorizzare l'output, ma nulla sembra mantenere la formattazione.

Cosa mi manca, o c'è un altro modo per fare ciò che evita questo problema tutti insieme?

+0

Non è possibile utilizzare un file di output? – fge

+0

Vuoi dire che lo script awk genera un file di output, invece di stampare l'output su stdout? Stavo solo indagando su cosa sarebbe implicato in questo. So che posso reindirizzare le azioni di stampa in awk su un file, devo solo controllare che si aggiungano invece di clobber. – Madasi

+0

Puoi accodare a un file usando '>>' dalla shell invece di '>'. '>' effettivamente clobbers, ma '>>' aggiunge. – fge

risposta

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

Notare le doppie virgolette nello echo.

È possibile semplificare questa versione, anche:

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 

backquote sono utili (ma meglio scritto come $(cmd args)), ma non devono essere utilizzati in tutto il mondo.

+0

Il primo esempio non funziona, poiché la perdita di formattazione si verifica quando si memorizza il valore in $ BODY. Ho provato questo usando 'echo -e" $ BODY "ad un certo punto. Tuttavia, il secondo e il terzo esempio funzionano perfettamente. Ho commesso un errore durante il test del reindirizzamento su un file temporaneo (il mio codice di debug ha stampato il valore della variabile errata), quindi mi sono perso il risultato. Questa è la correzione che probabilmente implementerò. – Madasi

+0

Non utilizzare 'echo -e'; usa 'echo'! –

+0

Ho provato anche quello, lo stesso risultato. Stavo usando -e di default perché sul mio sistema, usando echo senza -e fa in modo che ignori le sequenze di escape come \ n e le stampi invece. Probabilmente un artefatto di correre sulla versione di Solaris su cui sto lavorando. Tuttavia, per test ho incluso le righe 'echo $ BODY' e' echo -e $ BODY' per vedere il valore, e ho ottenuto lo stesso risultato non formattato da entrambi. – Madasi

3

citazioni Utilizzando dovrebbero lavorare, e lo fa per me:

$ 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 
$ 

E questo mi manda un'email formattato correttamente.

+0

L'ho provato sul mio sistema, e tu hai ragione, questo ti dà un'e-mail formattata correttamente. – Madasi

+0

Sembra che un file intermedio, sia esso un file temporaneo per l'output o il test formattato. Qui mantiene la formattazione quando viene inserito nel valore di una variabile, ma l'output formattato su stdout non mantiene la formattazione quando viene inserito direttamente in una variabile. – Madasi

Problemi correlati