Wie Sie wissen, wenn der Ausgang der last
hat ein !
, die Skript würde die Eingabezeilen für dieses Zeichen aufteilen.
Das Ausgabeformat last
ist nicht standardisiert (z. B. nicht in POSIX), aber Sie werden wahrscheinlich kein System finden, bei dem die erste Spalte etwas anderes als den Namen einer Aktion enthält. Zum Beispiel sehe ich:
tom pts/8 Wed Apr 27 04:25 still logged in michener.jexium-island.net
tom pts/0 Wed Apr 27 04:15 still logged in michener.jexium-island.net
reboot system boot Wed Apr 27 04:02 - 04:35 (00:33) 3.2.0-4-amd64
tom pts/0 Tue Apr 26 16:23 - down (04:56) michener.jexium-island.net
weiterhin
reboot system boot Fri Apr 1 15:54 - 19:03 (03:09) 3.2.0-4-amd64
tom pts/0 Fri Apr 1 04:34 - down (00:54) michener.jexium-island.net
wtmp begins Fri Apr 1 04:34:26 2016
mit Linux und verschiedenen Datumsformaten, Origination, usw., auf anderen Maschinen.
Durch IFS=!
Einstellung setzt das Skript die Feldtrennzeichen auf einen Wert, die unwahrscheinlich ist in der Ausgabe von last
auftreten, so dass jede Zeile gelesen wird, in LINE
ohne es zu spalten. Normalerweise sind Linien auf Leerzeichen aufgeteilt.
Doch wie Sie die Ausgabe von last
normalerweise sehen, nutzt Räume für Spalten zu trennen, und es wird in awk
zugeführt, die die Linie ohnehin — mit Leerzeichen teilen. Das Skript kann auf verschiedene Weise vereinfacht werden, z.,:
#!/bin/sh
for LINE in $(last -a | sed -e '$ d' -e 's/ .*//')
do
echo $LINE
done
welche ausreichend (aus dem Beispiel in der Frage ausgehend), wenn die Zahl der Anmeldungen nicht groß genug ist, Ihre Befehlszeile zu überschreiten. Bei der Überprüfung auf Variationen in last
Ausgabe, bemerkte ich eine Maschine mit etwa 9800 Zeilen aus mehreren Jahren. (Die anderen üblichen Gründe dafür, keine For-Schleifen zu verwenden, sind in diesem Fall nicht plausibel). Als Rohr:
#!/bin/sh
last -a | sed -e 's/ .*//' -e '/^$/d' | while IFS= read LINE
do
echo $LINE
done
änderte ich den sed Ausdruck (die OP wahrscheinlich von einem Ort kopiert wie Bash - remove the last line from a file), weil es nicht funktioniert.
Schließlich ist die Verwendung der Option -a
last
unnötig, da alle zusätzlichen Informationen verworfen werden.
Sie können den gesamten Code wahrscheinlich durch 'last -a | ersetzen awk 'NF> 8 {print $ 1}' ' – John1024