![](https://seccdn.libravatar.org/avatar/46ac6fb70a9e42baa99fab9e8d80bfbf.jpg?s=120&d=mm&r=g)
Ich bau mir ein Script, das eine Mail verschickt, sobald eine Partition eine bestimmte freie Größe (zB 100MB) unterschreitet. Lässt sich das mit grep eventuell in einem Befehl fassen, wenn immer mit _einer_ bestimmten Größe verglichen wird? Ich denke, wenn man individuelle Größen je Partition haben will, kommt man um eine Schleife nicht herum und dabei ergibt sich u.a Problem. #!/bin/bash PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==2) print $1}'` echo $PARTITION # Partition wurde angezeigt i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt Warum funktioniert die 2. Syntax nicht? Wie frage ich die Anzahl _aller_ ausgegebener Zeilen von zB df ab? Al
![](https://seccdn.libravatar.org/avatar/9527e20ec10ee9eb8b28774c9b754862.jpg?s=120&d=mm&r=g)
Al Bogner wrote:
Ich bau mir ein Script, das eine Mail verschickt, sobald eine Partition eine bestimmte freie Größe (zB 100MB) unterschreitet.
Lässt sich das mit grep eventuell in einem Befehl fassen, wenn immer mit _einer_ bestimmten Größe verglichen wird?
Ich denke, wenn man individuelle Größen je Partition haben will, kommt man um eine Schleife nicht herum und dabei ergibt sich u.a Problem.
#!/bin/bash
PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==2) print $1}'` echo $PARTITION # Partition wurde angezeigt
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Warum funktioniert die 2. Syntax nicht?
Weil $i als awk-eigene Variable interpretiert wird.
Wie frage ich die Anzahl _aller_ ausgegebener Zeilen von zB df ab?
# df -P | gawk 'END{print NR}' Meinst Du das? -- Andreas
![](https://seccdn.libravatar.org/avatar/46ac6fb70a9e42baa99fab9e8d80bfbf.jpg?s=120&d=mm&r=g)
Am Montag, 29. September 2003 19:16 schrieb Andreas Winkelmann:
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Warum funktioniert die 2. Syntax nicht?
Weil $i als awk-eigene Variable interpretiert wird.
Wie löse ich das dann? Ich möchte die df-Ausgabe Zeile für Zeile in einer Schleife abarbeiten und bräuchte dort dann "$i", wobei sich i bei jeder Schleife um 1 erhöht. Al
![](https://seccdn.libravatar.org/avatar/9527e20ec10ee9eb8b28774c9b754862.jpg?s=120&d=mm&r=g)
Al Bogner wrote:
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Warum funktioniert die 2. Syntax nicht?
Weil $i als awk-eigene Variable interpretiert wird.
Wie löse ich das dann?
Ich möchte die df-Ausgabe Zeile für Zeile in einer Schleife abarbeiten und bräuchte dort dann "$i", wobei sich i bei jeder Schleife um 1 erhöht.
Hmm, weiss jetzt nicht ob es der Königsweg ist, aber müsste klappen: /bin/df -P|/usr/bin/gawk '{if (NR==LINE) print $1}' LINE=$i -- Andreas
![](https://seccdn.libravatar.org/avatar/46ac6fb70a9e42baa99fab9e8d80bfbf.jpg?s=120&d=mm&r=g)
Am Montag, 29. September 2003 20:13 schrieb Andreas Winkelmann:
Al Bogner wrote:
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Hmm, weiss jetzt nicht ob es der Königsweg ist, aber müsste klappen:
/bin/df -P|/usr/bin/gawk '{if (NR==LINE) print $1}' LINE=$i
Das klappt leider nicht: #!/bin/bash i=2 while [ $i -le 4 ] do echo $i PARTiTION=`/bin/df -P|/usr/bin/gawk '{if (NR==LINE) print $1}' \ LINE=$i` echo $PARTITION let i=$i+1 done Al
![](https://seccdn.libravatar.org/avatar/46ac6fb70a9e42baa99fab9e8d80bfbf.jpg?s=120&d=mm&r=g)
Am Montag, 29. September 2003 20:53 schrieb Al Bogner:
Das klappt leider nicht:
#!/bin/bash i=2 while [ $i -le 4 ] do echo $i PARTiTION=`/bin/df -P|/usr/bin/gawk '{if (NR==LINE) print $1}' \ LINE=$i` echo $PARTITION let i=$i+1 done
Al
Sorry, PARTiTION enthielt ein i statt I. Ist nun ok. Danke! Al
![](https://seccdn.libravatar.org/avatar/ebe9e7470f033d101415722d029f0b24.jpg?s=120&d=mm&r=g)
Al Bogner <suse-linux@ml03q3.pinguin.uni.cc>
Ich bau mir ein Script, das eine Mail verschickt, sobald eine Partition eine bestimmte freie Größe (zB 100MB) unterschreitet.
Lässt sich das mit grep eventuell in einem Befehl fassen, wenn immer mit _einer_ bestimmten Größe verglichen wird?
Ich denke, wenn man individuelle Größen je Partition haben will, kommt man um eine Schleife nicht herum und dabei ergibt sich u.a Problem.
#!/bin/bash
PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==2) print $1}'` echo $PARTITION # Partition wurde angezeigt
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Warum funktioniert die 2. Syntax nicht?
Da $i in einem String steht, mit ' (einfacher Apostroph) steht. Daher wird der Inhalt des Strings nicht ausgewertet. Will man Umgebungsvariablen an awk übergeben kann man das am einfachsten so machen: awk -v foo=$FOO ' BEGIN {printf "%s\n", foo} '
Wie frage ich die Anzahl _aller_ ausgegebener Zeilen von zB df ab? was soll das machen? Zählen wieviel Zeilen: df -P | wc -l ok da muß man dann wohl noch 1 abziehen, da die Ausgabe von df mit einem erklärenden Text versehen ist.
Jürgen -- Dr.rer.nat. Juergen Vollmer, Viktoriastrasse 15, D-76133 Karlsruhe Tel: +49(721) 9204871 Fax: +49(721) 24874 Juergen.Vollmer@[informatik-vollmer.de|alumni.uni-karlsruhe.de|acm.org] www.informatik-vollmer.de
![](https://seccdn.libravatar.org/avatar/7b33cb1e776e35b87edb8ef09f0c888f.jpg?s=120&d=mm&r=g)
Hallo, Am Mon, 29 Sep 2003, Al Bogner schrieb:
Ich bau mir ein Script, das eine Mail verschickt, sobald eine Partition eine bestimmte freie Größe (zB 100MB) unterschreitet.
Lässt sich das mit grep eventuell in einem Befehl fassen, wenn immer mit _einer_ bestimmten Größe verglichen wird?
Hae?
Ich denke, wenn man individuelle Größen je Partition haben will, kommt man um eine Schleife nicht herum und dabei ergibt sich u.a Problem.
#!/bin/bash
PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==2) print $1}'` echo $PARTITION # Partition wurde angezeigt
i=2 PARTITION=`/bin/df -P|/usr/bin/gawk '{if (NR==$i) print $1}'` echo $PARTITION # Partition wurde nicht angezeigt
Warum funktioniert die 2. Syntax nicht?
Weil awk das $i nicht kennt und die shell das in '' auch nicht expandiert, bevor gawk das zu sehen bekommt. | /usr/bin/gawk -v i=$i 'NR == i { print $1; }' ^ ohne '$'! | /usr/bin/gawk "NR == $i { print $1; }"
Wie frage ich die Anzahl _aller_ ausgegebener Zeilen von zB df ab?
Wie waere es, wenn du nur gawk verwendest ;) ==== #! /usr/bin/gawk -f BEGIN { DF="/bin/df -P"; MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root"; limit=102400; while( DF | getline p ) { if (p !~ /^Filesystem/) { split(p, a, "[\t ]*"); if (a[4] <= limit) { W = W"\n"p; } } } print W | MAIL; } ==== Nur so als Anregung ;) Wenn du noch Hilfe beim Ausfeilen brauchst, melde dich... -dnh PS: df wird nur einmal aufgerufen... -- Es gibt in C keine Strings. Wenn man das kapiert hat, kann man anfangen mit Strings in C zu arbeiten. [Christoph Berg]
![](https://seccdn.libravatar.org/avatar/735ea797d876adb026ae955e8adbf597.jpg?s=120&d=mm&r=g)
Am Montag, 29. September 2003 21:42 schrieb David Haller: [...]
Wie waere es, wenn du nur gawk verwendest ;)
David, so langsam fange ich an, mir Sorgen zu machen ;) Du leidest an einer BEGIN-Fixierung. Sowas macht man doch nicht *g*
==== #! /usr/bin/gawk -f
BEGIN { DF="/bin/df -P"; MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root"; limit=102400;
while( DF | getline p ) { if (p !~ /^Filesystem/) { split(p, a, "[\t ]*"); if (a[4] <= limit) { W = W"\n"p; } } } print W | MAIL; } ====
<schnipp> #! /bin/bash LIMIT=102400 /bin/df -P | /usr/bin/awk ' NR == 1 { next } $4 <= limit { print $0; } ' limit=$LIMIT | /usr/bin/mail -s "Warnung Platzverbrauch" root <schnapp> Natürlich kann man genausogut die awk-Variable limit im BEGIN-Block setzen, ich wollte nur mal etwas Abwechslung reinbringen ;) Jan
![](https://seccdn.libravatar.org/avatar/7b33cb1e776e35b87edb8ef09f0c888f.jpg?s=120&d=mm&r=g)
Hallo, Am Mon, 29 Sep 2003, Jan Trippler schrieb:
Am Montag, 29. September 2003 21:42 schrieb David Haller: [...]
Wie waere es, wenn du nur gawk verwendest ;)
David, so langsam fange ich an, mir Sorgen zu machen ;) Du leidest an einer BEGIN-Fixierung. Sowas macht man doch nicht *g*
*lol*
==== #! /usr/bin/gawk -f
BEGIN { DF="/bin/df -P"; MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root"; limit=102400;
while( DF | getline p ) { if (p !~ /^Filesystem/) { split(p, a, "[\t ]*"); if (a[4] <= limit) { W = W"\n"p; } } } print W | MAIL; } ====
<schnipp> #! /bin/bash LIMIT=102400 /bin/df -P | /usr/bin/awk ' NR == 1 { next } $4 <= limit { print $0; } ' limit=$LIMIT | /usr/bin/mail -s "Warnung Platzverbrauch" root <schnapp>
Passt auch.
Natürlich kann man genausogut die awk-Variable limit im BEGIN-Block setzen, ich wollte nur mal etwas Abwechslung reinbringen ;)
Die Motivation war, dass ich dann in gawk eben direkt noch mehr machen kann, z.B. irgendwelche Informationen summieren... Und eben ohne gleich perl zu nehmen... -dnh -- ? Wie, ich? Fehler zugeben? Das muß ein Mißverständnis sein ;) -- fefe in dasr
![](https://seccdn.libravatar.org/avatar/735ea797d876adb026ae955e8adbf597.jpg?s=120&d=mm&r=g)
Am Montag, 29. September 2003 23:50 schrieb David Haller: [alles im BEGIN-Block]
Die Motivation war, dass ich dann in gawk eben direkt noch mehr machen kann, z.B. irgendwelche Informationen summieren... Und eben ohne gleich perl zu nehmen...
Dafür gibt es einen END-Block ;) Jan
![](https://seccdn.libravatar.org/avatar/7b33cb1e776e35b87edb8ef09f0c888f.jpg?s=120&d=mm&r=g)
Hallo, Am Tue, 30 Sep 2003, Jan Trippler schrieb:
Am Montag, 29. September 2003 23:50 schrieb David Haller: [alles im BEGIN-Block]
Die Motivation war, dass ich dann in gawk eben direkt noch mehr machen kann, z.B. irgendwelche Informationen summieren... Und eben ohne gleich perl zu nehmen...
Dafür gibt es einen END-Block ;)
Nein, denn dann wartet awk auf ein EOF von /dev/stdin. -dnh -- Seit wann schaut hier noch irgendeiner aufs Subject? Das hab ich mir nur angesehen, als ich noch relativ neu war. Mittlerweile nehme ich es nur mehr wahr, wenn es mehr als den halben Bildschirm verdeckt. -- Adalbert Michelic in suse-talk
![](https://seccdn.libravatar.org/avatar/735ea797d876adb026ae955e8adbf597.jpg?s=120&d=mm&r=g)
Am Dienstag, 30. September 2003 22:29 schrieb David Haller:
Am Tue, 30 Sep 2003, Jan Trippler schrieb:
Am Montag, 29. September 2003 23:50 schrieb David Haller: [alles im BEGIN-Block]
Die Motivation war, dass ich dann in gawk eben direkt noch mehr machen kann, z.B. irgendwelche Informationen summieren... Und eben ohne gleich perl zu nehmen...
Dafür gibt es einen END-Block ;)
Nein, denn dann wartet awk auf ein EOF von /dev/stdin.
??? Selbstverständlich wird END _nach_ der Verarbeitung der Eingabedatei (in diesem Fall stdin) abgearbeitet - das bezweckt man doch im Allgemeinen mit Summierungen, oder? Wenn Du Gruppensummen meinst - auch dafür brauchst Du keine umständliche Verarbeitung im BEGIN. Das kannst Du viel einfacher in jeder Zeile machen: { summe += $3; } oder mit Bedingungen verknüpfen: $4 < limit { anzahl ++; } und dann ausgeben, wenn ein Gruppenwechsel stattfindet: $1 != prev { print summe, anzahl; } Worum es mir geht: awk verarbeitet wie grep, sed, ... Dateien zeilenweise. Der BEGIN-Block führt den awk ad absurdum, wenn er zum Verarbeiten der Eingabedatei missbraucht wird. Er ist für Initialisierungen, vielleicht mal ne Headerzeile oder Ähnliches gedacht, nicht für das Einlesen der Eingabedatei. Jan
![](https://seccdn.libravatar.org/avatar/7b33cb1e776e35b87edb8ef09f0c888f.jpg?s=120&d=mm&r=g)
Hallo Jan, Am Wed, 01 Oct 2003, Jan Trippler schrieb:
Am Dienstag, 30. September 2003 22:29 schrieb David Haller:
Am Tue, 30 Sep 2003, Jan Trippler schrieb:
Am Montag, 29. September 2003 23:50 schrieb David Haller: [alles im BEGIN-Block]
Die Motivation war, dass ich dann in gawk eben direkt noch mehr machen kann, z.B. irgendwelche Informationen summieren... Und eben ohne gleich perl zu nehmen...
Dafür gibt es einen END-Block ;)
Nein, denn dann wartet awk auf ein EOF von /dev/stdin.
??? Selbstverständlich wird END _nach_ der Verarbeitung der Eingabedatei (in diesem Fall stdin) abgearbeitet - das bezweckt man doch im Allgemeinen mit Summierungen, oder?
[ ] du hast verstanden, was ich im BEGIN mache Es gibt nix von stdin -- und es interessiert nix von stdin.
Wenn Du Gruppensummen meinst - auch dafür brauchst Du keine umständliche Verarbeitung im BEGIN.
s.o.
Worum es mir geht: awk verarbeitet wie grep, sed, ... Dateien zeilenweise. Der BEGIN-Block führt den awk ad absurdum, wenn er zum Verarbeiten der Eingabedatei missbraucht wird. Er ist für Initialisierungen, vielleicht mal ne Headerzeile oder Ähnliches gedacht, nicht für das Einlesen der Eingabedatei.
s.o. Es ist _keine_ Datei, sondern die Ausgabe einer Pipe, die _von gawk_ selbst angestossen/geoffnet wird. _gawk_ ruft das 'df -P' auf und liest dessen stdout. Okok... Per shell geht's natuerlich auch... ==== warn_fssize.sh ==== #! /bin/bash DF="df -P" MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root"; $DF | gawk -F"[\t ]*" \ ' BEGIN{ limit=1024000; } /^Filesystem/ { next; } $4 <= limit { print; } ' | $MAIL ==== Ich finde aber, mit "nur gawk" hat man's einfacher, v.a. wenn in der Ein- oder Ausgabe "'" vorkommen... Und das gawk-script zwischen den '' wird schnell sehr unuebersichtlich... Aber _wenn_ man es so wie ich, nur mit gawk macht, dann liest man eben _nicht_ von stdin (des gawk-scripts, da kommt ja nix), sondern man wirft das df selber an und liest dann dessen Ausgabe via getline ein. Ob man da die Ausgabe auch in's "if" reinlegen koennte? Ahja, geht (ich habe auch mal die Variablennamen "aufgebohrt"): ==== warn_fssize ==== #! /usr/bin/gawk -f BEGIN { DF="/bin/df -P"; MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root"; limit=1024000; while( DF | getline partition ) { if (partition !~ /^Filesystem/) { split(partition, array, "[\t ]*"); if (array[4] <= limit) { print partition | MAIL; } } } } ==== Hier wird eben _nicht_ (das) stdin (von gawk) gelesen! Es wird "selber" ein df geoffnet, eine Pipe zwischen dem stdout von df und gawk erstellt, und gawk liest dann diese pipe via getline zeilenweise in die Variable 'partition' ein. Das was du meinst, dass die Daten via stdin reinkommen, dazu waere eben ein "umgebendes" shell-script noetig, siehe oben, also mindestens folgendes: ==== #! /bin/sh df -P | warn_fssize.awk ==== Aber dann kann man das "MAIL" auch noch gleich rausverlagern (s.o.). Der Vorteil bei der "nur-gawk" Variante ist, dass eben ein Haufen Sachen mehr gemacht werden koennen, dass man sich uebersichtlich gawk-funktionen definieren kann, ohne dass das script unuebersichtlich wird oder "viele" andere Prozesse aufgerufen werden muessen. Dazu kommt: in der shell uebergibst du das "gawk-script" als Parameter, d.h. shell-expansionen und die maximale Laenge der Kommandozeile sind relevant, sobald das gawk-script etwas komplexer als oben wird. Also in einer Situation, wo du wohl schon zu perl greifen wuerdest *eg*. Fuer den einfachsten Fall, wie oben, sind beide Loesungen natuerlich aequivalent (schau dir z.B. mal ein strace -f -eprocess mit '/bin/cat' statt '/bin/mail' von beiden an). -dnh --
Wieso nicht? Hier in Eschede halten sogar ICEs. Bei der Einwohnerzahl nicht schlecht, oder? Das Problem liegt in der Frage, *wo* und *wie* sie halten... -- Stefan Dreyer und Martin Hermanowski in dasr
![](https://seccdn.libravatar.org/avatar/735ea797d876adb026ae955e8adbf597.jpg?s=120&d=mm&r=g)
Am Mittwoch, 1. Oktober 2003 04:10 schrieb David Haller:
Am Wed, 01 Oct 2003, Jan Trippler schrieb:
Am Dienstag, 30. September 2003 22:29 schrieb David Haller: [...] [ ] du hast verstanden, was ich im BEGIN mache
Doch, das habe ich schon - mir ist nur immer noch nicht der Vorteil klar. [...]
s.o. Es ist _keine_ Datei, sondern die Ausgabe einer Pipe, die _von gawk_ selbst angestossen/geoffnet wird. _gawk_ ruft das 'df -P' auf und liest dessen stdout.
Ja, das ist mir aufgefallen - und dafür hast Du die Pipe nun im awk - was bringt das in diesem Fall?
==== warn_fssize.sh ==== #! /bin/bash DF="df -P" MAIL="/bin/mail -s 'Warnung: Platzverbrauch' root";
$DF | gawk -F"[\t ]*" \ ' BEGIN{ limit=1024000; } /^Filesystem/ { next; } $4 <= limit { print; } ' | $MAIL ====
Ja, jetzt sieht Dein Script so ungefähr wie meins aus (allerdings habe ich einem so kleinen Script nicht extra noch Variablen gesetzt und BTW: Warum Du extra den Feldtrenner auf die Werte setzt, die der awk sowieso nutzt und die in diesem Fall auch exakt passen. ist mir auch zu hoch ;)
Ich finde aber, mit "nur gawk" hat man's einfacher, v.a. wenn in der Ein- oder Ausgabe "'" vorkommen... Und das gawk-script zwischen den '' wird schnell sehr unuebersichtlich...
Es geht hier um die Ausgabe von df - da ist das awk im BEGIN deutlich unübersichtlicher und aufwändiger als die Variante oben.
Aber _wenn_ man es so wie ich, nur mit gawk macht, dann liest man eben _nicht_ von stdin (des gawk-scripts, da kommt ja nix), sondern man wirft das df selber an und liest dann dessen Ausgabe via getline ein.
Eben: Du erkaufst Dir den Ersatz der Pipe _vor_ dem awk durch die Pipe _im_ awk mit einem deutlich größeren Aufwand- Wo liegt der Vorteil? Du hast ne Pipe, Du hast einen neuen Prozess (den df) - das nimmt sich doch nichts.
Das was du meinst, dass die Daten via stdin reinkommen, dazu waere eben ein "umgebendes" shell-script noetig, siehe oben, also mindestens folgendes:
==== #! /bin/sh df -P | warn_fssize.awk ====
Aber dann kann man das "MAIL" auch noch gleich rausverlagern (s.o.).
Richtig - deshalb habe ich das auch so vorgeschlagen. Was ist der Nachteil eines in einem Shell-Script eingebetteten awk gegenüber einem awk-Aufruf vom Prompt aus (mal abgesehen von einem Shell-Aufruf weniger - die Anzahl der Pipes + Kommandoaufrufe sonst ist ja gleich)?
Der Vorteil bei der "nur-gawk" Variante ist, dass eben ein Haufen Sachen mehr gemacht werden koennen, dass man sich uebersichtlich gawk-funktionen definieren kann, ohne dass das script unuebersichtlich wird oder "viele" andere Prozesse aufgerufen werden muessen. Dazu kommt: in der shell uebergibst du das "gawk-script" als Parameter, d.h. shell-expansionen und die maximale Laenge der Kommandozeile sind relevant, sobald das gawk-script etwas komplexer als oben wird. Also in einer Situation, wo du wohl schon zu perl greifen wuerdest *eg*.
Richtig - wenn es denn so komplex werden würde, dann würde ich perl nehmen (das ist deutlich schneller, vor allem wenn Du mit assoziativen Arrays anfängst) - aber so komplex war es ja nicht. Warum gleich ein Multifunktionsmonster bauen, wenn ich nur ein paar df-Ausgaben auswerten will?
Fuer den einfachsten Fall, wie oben, sind beide Loesungen natuerlich aequivalent (schau dir z.B. mal ein strace -f -eprocess mit '/bin/cat' statt '/bin/mail' von beiden an).
Das war aber nicht das Problem - es ging um einen df, eine Prüfung und eine Mail. _Dann_ ist awk Klasse, einfach und elegant - wenn ich z. B. mehrere Eingangsdateien mischen, sortieren, zerlegen und analysieren will, nehme ich was anderes, was zu der Aufgabe besser passt. Jan
participants (5)
-
Al Bogner
-
Andreas Winkelmann
-
David Haller
-
Dr. Jürgen Vollmer
-
Jan.Trippler@t-online.de