ubuntuusers.de

Zeilenumbrüche aus Befehlen werden in Dateien entfernt

Status: Gelöst | Ubuntu-Version: Server 11.10 (Oneiric Ocelot)
Antworten |

Titzi266

Anmeldungsdatum:
11. November 2008

Beiträge: 338

Hallo,

ich versuche automatisiert E-Mails zu versenden. Funktioniert auch prima. Leider werden bei meinen Skripten die Zeilenumbrüche aus den Mails entfernt:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh

to="root"
subject="Available Updates"

mfile=mail_upgrades

ctime=$(date +%Y-%m-%d_%H-%M-%S)

apt-get update

echo `apt-get dist-upgrade -s` > $mfile
echo "" >> $mfile
echo "Hostname: "`hostname` >> $mfile
echo "" >> $mfile
echo "Time: "$ctime >> $mfile
echo "" >> $mfile

mail -s "$subject" $to < $mfile
rm $mfile

Diese Mail kommt raus:

Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Hostname: uranus

Time: 2012-02-26_00-02-45

Aus dieser Datei deren Inhalt als Mailtext versendet wird sieht so aus:

Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Hostname: uranus

Time: 2012-02-26_00-10-29

Jemand eine Idee wie ich es hinbekomme, dass aus der Ausgabe von 'apt-get dist-upgrade -s' die Zeilenumbrüche nicht entfernt werden?

Danke Titzi266

jakon Team-Icon

Lokalisierungsteam

Anmeldungsdatum:
16. November 2009

Beiträge: 419

Ich nehme an, dass mail die Unix-Zeilenenden nicht mit einem bei E-Mails nötigen CR (Carriage-Return) ergänzen.

Dafür kannst du das Programm unix2dos aus dem Paket dos2unix verwenden:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh

to=root
subject=Available Updates

mfile=mail_upgrades

ctime=$(date +%Y-%m-%d_%H-%M-%S)

apt-get update

echo $(apt-get dist-upgrade -s) > "$mfile"
echo >> "$mfile"
echo Hostname: $(hostname) >> "$mfile"
echo >> "$mfile"
echo Time: $ctime >> "$mfile"
echo >> "$mfile"

unix2dos < "$mfile" | mail -s "$subject" "$to"
rm "$mfile"

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

jakon schrieb:

Ich nehme an, dass mail die Unix-Zeilenenden nicht mit einem bei E-Mails nötigen CR (Carriage-Return) ergänzen.

Nein, das Problem ist diese Zeile:

1
echo $(apt-get dist-upgrade -s) > "$mfile"

Beispiel gefällig?

1
2
3
4
5
6
7
8
9
$ ls -1
a
b
c
d
e

$ echo $(ls -1)
a b c d e

Dafür kannst du das Programm unix2dos aus dem Paket dos2unix verwenden:

Das brauchen wir hier nicht. Und man kann noch weiter vereinfachen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/sh

to='root'
subject='Available Updates'

ctime=$(date '+%Y-%m-%d_%H-%M-%S')

apt-get update

{ apt-get dist-upgrade -s; cat <<MAIL; } | mail -s "$subject" "$to"

Hostname: $(hostname)

Time: $ctime

MAIL

Ciao

robert

TraumFlug

Avatar von TraumFlug

Anmeldungsdatum:
16. Juli 2009

Beiträge: 999

Wohnort: zwischen den ohren

Nicht doch so umständlich! Vergleich' mal die Ausgaben von:

echo $(ls -l)

...mit...

echo "$(ls -l)"

...ich denke du kapierst schon...

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

TraumFlug schrieb:

Nicht doch so umständlich!

Was heißt "umständlich"? Das überflüssige echo drin zu lassen ist doch wohl umständlich - auch wenn man es mit den Quotes retten kann.

Ciao

robert

Titzi266

(Themenstarter)

Anmeldungsdatum:
11. November 2008

Beiträge: 338

Danke euch allen! ☺

Die Variante von TraumFlug löst das Problem.

Hier der fertige Code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#!/bin/sh

to="root"
subject="Available Updates"

mfile=mail_upgrades

ctime=$(date +%Y-%m-%d_%H-%M-%S)

apt-get update

echo "$(apt-get dist-upgrade -s)" > $mfile
echo "" >> $mfile
echo "Hostname: "`hostname` >> $mfile
echo "" >> $mfile
echo "Time: "$ctime >> $mfile
echo "" >> $mfile

mail -s "$subject" $to < $mfile
rm $mfile

Danke! ☺

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

Titzi266 schrieb:

Danke euch allen! ☺

Die Variante von TraumFlug löst das Problem.

Meine Variante löst das Problem auch. Aber wenn Du schon nahe bei Deiner ursprünglichen Lösung bleiben willst, dann nimm wenigstens das überflüssige echo raus:

1
apt-get dist-upgrade -s >"$mfile"

Es ist übrigens auch effizienter, wenn Du alle Kommandos, die in die temporäre Datei schreiben sollen, mit { ... } >"$mfile" zusammenfasst, so dass die Datei nur einmal geöffnet werden muss.

Ciao

robert

Kinch

Anmeldungsdatum:
6. Oktober 2007

Beiträge: 1261

rklm

Es ist übrigens auch effizienter, wenn Du alle Kommandos, die in die temporäre Datei schreiben sollen, mit { ... } >"$mfile" zusammenfasst, so dass die Datei nur einmal geöffnet werden muss.

Oder direkt nach Mail zu pipen. Aber um Effizienz und Eleganz gehts hier wohl nicht^^

(Finde 'echo $(...)' immer gruselig und warte schon auf ein 'echo $(echo $(...))'.)

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

Kinch schrieb:

Oder direkt nach Mail zu pipen.

Ja, das hatte ich ja auch schon vorgeschlagen.

Aber um Effizienz und Eleganz gehts hier wohl nicht^^

Ich vermute, dass meine Optimierung mit dem Heredoc vielleicht etwas zu heftig war...

(Finde 'echo $(...)' immer gruselig und warte schon auf ein 'echo $(echo $(...))'.)

Völlig überflüssig vor allem.

Ciao

robert

TraumFlug

Avatar von TraumFlug

Anmeldungsdatum:
16. Juli 2009

Beiträge: 999

Wohnort: zwischen den ohren

Mir ging's ja auch nur um einfache Lesbarkeit und dergleichen, vor allem da der Fragesteller ja nicht so der absolute Shellguru ist. Bin ich auch nicht, und bevorzuge selbst in kleine Einzelschritte und nicht zu kryptisch aufgebaute und damit leichter Lesbare/Wartbare Skripte.

Aber um nochmal was anzumerken: Ist es sicher, dass das Skript nur einmal mit genug Zeitfenster läuft? Sonst könnten komische sachen in "mfile" passieren (wenn durch argen Zufall 2 Instanzen gleichzeitig laufen - Vor allem das "rm" sollte gemein sein...). Das löst man dann besser mit einer lokalen Variable, oder einer eindeutigen (einmaligen) temporären Datei (mit "mktemp" z.B.).

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13204

TraumFlug schrieb:

Mir ging's ja auch nur um einfache Lesbarkeit und dergleichen, vor allem da der Fragesteller ja nicht so der absolute Shellguru ist. Bin ich auch nicht, und bevorzuge selbst in kleine Einzelschritte und nicht zu kryptisch aufgebaute und damit leichter Lesbare/Wartbare Skripte.

Ich bin auch immer für Lesbarkeit und Wartbarkeit. Das bedeutet aber oft auch, dass man Redundanz loswird und Skripte vereinfacht.

Aber um nochmal was anzumerken: Ist es sicher, dass das Skript nur einmal mit genug Zeitfenster läuft? Sonst könnten komische sachen in "mfile" passieren (wenn durch argen Zufall 2 Instanzen gleichzeitig laufen - Vor allem das "rm" sollte gemein sein...). Das löst man dann besser mit einer lokalen Variable, oder einer eindeutigen (einmaligen) temporären Datei (mit "mktemp" z.B.).

Auch dafür ist eine bessere Lösung m.E., die Ausgaben direkt per Pipe nach mail zu schreiben besser, weil Du dann gar nicht erst eine temporäre Datei benötigst. Man kann das ja auch so machen, wenn die Sache mit dem Heredoc zu heiß ist:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/bin/sh

to='root'
subject='Available Updates'

ctime=$(date '+%Y-%m-%d_%H-%M-%S')

apt-get update

{ 
  apt-get dist-upgrade -s
  echo
  echo "Hostname: $(hostname)"
  echo
  echo "Time: $ctime"
  echo
} | mail -s "$subject" "$to"

Immer noch besser als mit einer temporären Datei zu arbeiten.

Ciao

robert

Antworten |