2012-01-12 11 views
6

Powiel możliwe:
Capturing multiple line output to a bash variableShell skryptów, przechowywać dane wyjściowe polecenia w zmiennej i zachować formatowanie

mam co jest chyba podstawowe pytanie skryptów, ale nie udało się znajdź odpowiedź gdziekolwiek spojrzę.

Mam skrypt awk, który przetwarza plik i wypluwa listę wyłączonych systemów. Gdy zgłoszę go ręcznie z poziomu wiersza poleceń, mam sformatowane wyjście z powrotem:

$awk -f awkscript datafile 

The following notifications are currently disabled: 

host: bar 
host: foo 

Piszę skrypt otoki, aby zadzwonić z mojego crontab, który będzie realizowany scenariusz awk, ustalić, czy istnieją jakiekolwiek wyjście, a napisz do mnie, jeśli jest. To wygląda jak (uproszczony):

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

Uruchomiony w ten sposób, i potwierdzona przez dodanie echo $BODY do skryptu, wyjście jest pozbawiony formatowania (nowe linie są głównie co Martwię się), więc Uzyskaj dane wyjściowe, które wyglądają następująco:

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

Próbuję dowiedzieć się, jak zachować formatowanie, które jest obecne, jeśli uruchomię polecenie ręcznie.

Czego próbowałem dotąd:

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

Próbowałem to, bo w moim systemie (Solaris 5.10), używając echo bez -e ignoruje standardowe sekwencje jak \ n. Nie działa. Sprawdziłem plik tmp i nie ma on w nim żadnego formatowania, więc problem występuje podczas zapisywania danych wyjściowych, a nie podczas drukowania.

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

Próbowałem to, bo wszystko udało mi się znaleźć, w tym niektóre inne pytania tutaj na stackoverflow powiedział, że problemem było to, że powłoka będzie zastąpić kody białych znaków ze spacjami, jeżeli nie zostało podane. Nie działa.

Próbowałem użyć printf zamiast echa, używając $ (polecenie) zamiast `command`, i używając tempfile zamiast zmiennej do przechowywania danych wyjściowych, ale nic nie zachowuje formatowania.

Czego mi brakuje lub czy istnieje inny sposób, aby to zrobić, aby uniknąć tego problemu?

+0

Nie używa pliku wyjściowego opcja? – fge

+0

Masz na myśli to, że skrypt awk generuje plik wyjściowy, zamiast drukowania wyjściowego na standardowe wyjście? Właśnie sprawdzałem, co by się w to wplątało. Wiem, że mogę przekierować akcje drukowania w awk do pliku, po prostu muszę sprawdzić, czy dołączają zamiast clobbera. – Madasi

+0

Możesz dołączyć do pliku używając '>>' z powłoki zamiast '>'. '>' rzeczywiście clobbers, ale '>>' dołącza. – fge

Odpowiedz

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

Uwaga na podwójne cytaty z echo.

Można uprościć tę wersję również:

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

tylko:

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

małe cudzysłowy są przydatne (ale lepiej napisany jako $(cmd args)), ale nie muszą być stosowane wszędzie.

+0

Pierwszy przykład nie działa, ponieważ utrata formatowania występuje podczas zapisywania wartości w $ BODY. Przetestowałem to, używając 'echo -e" $ BODY "w jednym punkcie. Jednak drugi i trzeci przykład działają doskonale. Popełniłem błąd podczas testowania przekierowania do pliku tymczasowego (mój kod debugowania wydrukował wartość niewłaściwej zmiennej), więc przegapiłem, że to działa. To jest poprawka, którą prawdopodobnie zaimplementuję. – Madasi

+0

Nie używaj "echo -e"; użyj 'echo'! –

+0

Próbowałem również, ten sam wynik. Używałem domyślnie opcji -e, ponieważ w moim systemie użycie echa bez znaku -e powoduje, że ignoruje sekwencje specjalne, takie jak \ n, i wyświetla je zamiast tego. Prawdopodobnie artefakt działa na wersji Solaris, na której jestem. Jednak do przetestowania zawarłem linie 'echo $ BODY' oraz' echo -e $ BODY', aby zobaczyć wartość i otrzymałem ten sam niesformatowany wynik z obu. – Madasi

3

Korzystanie cytaty powinny działać, a nie dla mnie:

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

I to wysyła mi prawidłowo sformatowany e-mail.

+0

Przetestowałem to na moim systemie i masz rację, to daje poprawnie sformatowaną wiadomość e-mail. – Madasi

+0

Wygląda na to, że plik pośredni, czy to plik tymczasowy dla pliku wyjściowego, czy sformatowany test.in tutaj nie ma formatowania, gdy jest przekierowany na wartość zmiennej, ale sformatowane wyjście na standardowe wyjście nie ma formatowania po umieszczeniu bezpośrednio w zmiennej. – Madasi

Powiązane problemy