Wie kann die Anzahl der Zeilen begrenzt werden, die die Ausgabe eines Befehls in bash verfügbar hat?

11

Ich habe angefangen, eine große Datei im Hintergrund mit herunterzuladen

$ nohup wget http://example.tld/big.iso &

Das gibt mir auch eine nohup.outDatei, die die Ausgabe von enthält wget.

Wenn ich später den Download-Vorgang sehen möchte, könnte ich ihn verwenden, $ tail -f nohup.outaber das füllt mein Terminalfenster schneller aus, als ich es mir gewünscht hätte. Was ich sehen möchte, ist die letzte Zeile, die ständig aktualisiert wird (genau wie bei wgetalleiniger Verwendung ).

Ich habe es versucht, $ tail -n 1 -f nohup.outaber es scheint nur das anfängliche Tailing zu beeinflussen.

Im Allgemeinen würde dieses Problem gelöst, wenn es möglich ist, die Anzahl der verfügbaren / sichtbaren Zeilen der Ausgabe eines Befehls zu begrenzen (in diesem Fall auf 1). Sozusagen die Ausgabe in einem Kreispuffer - denken Sie nur an den normalen Fortschrittsbalken, $ wget example.tld/big.isoder gedruckt wird.

Gibt es eine solche Lösung?

Oder klettere ich falsch auf den Baum? (Das heißt, wäre es einfacher, die nohupAusgabe zu begrenzen oder etwas anderes zu tun?)

Jari Keinänen
quelle

Antworten:

10

Wenn Sie den Bildlaufbereich nicht einschränken möchten (siehe meine andere Antwort), können Sie auch den Wagenrücklauf verwenden, um zum Zeilenanfang zurückzukehren, bevor Sie die nächste Zeile drucken. Es gibt eine Escape-Sequenz, die den Rest der Zeile löscht. Dies ist erforderlich, wenn die aktuelle Zeile kürzer als die vorherige Zeile ist.

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
el="$(tput el)"; # Clear to the end of the line
tail -n 1 -f nohup.out | while read -r line; do echo -n $'\r'"$el$line"; done;
janmoesen
quelle
6

Sie können watchhier verwenden:

watch -n 0.5 -e "tail -n 1 nohup.out"

Bearbeiten : Die Option -e(Alias --exec) sieht hier geeignet aus. Insbesondere wenn Sie watchmit sehr kleinen Intervallen laufen möchten, reduziert dies den Overhead, der durch das sh -cinterne Laufen watchin jedem Zyklus verursacht wird.

rozcietrzewiacz
quelle
2
Beachten Sie, dass dies tailjede Sekunde einen neuen Prozess auslöst, der Sie möglicherweise interessiert oder nicht. Stellen Sie außerdem sicher, dass Sie ein Intervall von weniger als einer Sekunde angeben (z. B. watch -n 0.1), um den Teil "ständig aktualisiert" zu simulieren. (Dies erhöht natürlich auch die Anzahl der Prozesse und offenen Dateiaufrufe.) Wenn Sie OS X verwenden, können Sie watchMacPorts verwenden, da es standardmäßig nicht verfügbar ist.
Janmoesen
Dies ist ein bisschen umgehend, aber als solches großartig. Ich hatte eine Nicht-Vollbild-Antwort erwartet, damit ich frühere Ausgaben sehen konnte - aber ich konnte sie wirklichwatch in einem neuen Terminalfenster verwenden. Ich fand auch heraus, dass die Verwendung tail -n 2nützlicher ist als -n 1mit wget, zumindest mit einem watchIntervall von 1 Sekunde, da sonst der letzte Prozentsatz möglicherweise nicht angezeigt wird. Dies ist kein Fehler in Ihrer Antwort, aber ich habe es erwähnt, wenn jemand anderes beschließt, die Nohup-Ausgabe von Wgets zu verfolgen.
Jari Keinänen
@janmoesen Für dieses spezielle Szenario ist ein neuer tailProzess wahrscheinlich nicht zu viel Overkill. aber als allgemeine Antwort ist dies gut zu berücksichtigen. Ich habe auch festgestellt, dass watch -n 0.1dies nicht funktioniert hat, aber watch -n 0,1funktioniert hat - möglicherweise werden Gebietsschemas angewendet, obwohl ich noch keine Gebietsschemas gesehen habe, die auf Terminalbefehlsoptionen angewendet wurden. Als Randnotiz: brew install watchhat auch super funktioniert :-)
Jari Keinänen
Eine Randnotiz: Ob watchmit Ihren Gebietsschemaeinstellungen funktioniert 0,1oder 0.1davon abhängt (es wird das für Ihr Gebietsschema definierte Dezimalsymbol verwendet). Überprüfen Sie LC_ALL=C watch -n 0.1 "date +%S.%N".
Rozcietrzewiacz
3

Es gibt bestimmte Xterm-Steuersequenzen, mit denen Sie die Zeilen Ihres Terminals begrenzen können, die gescrollt werden. Suchen Sie nach "Bildlaufbereich festlegen". Es ist allerdings ein bisschen kludge. Stellen Sie sicher, dass Sie Ihr Terminal anschließend zurücksetzen:

nohup wget http://cdimage.debian.org/debian-cd/6.0.3/amd64/iso-dvd/debian-6.0.3-amd64-DVD-1.iso &
clear; echo -n $'\e[1;2r'; tail -f nohup.out | grep --line-buffered .
# The "grep" line is to ensure a single line; you can also use "awk 1" or "sed" etc.
janmoesen
quelle
<Fügen Sie hier den üblichen Hinweis zur Nicht-Portabilität ein>
janmoesen
Dies ist eine weitere großartige Alternative, die jedoch auch am besten in dedizierten Fenstern verwendet wird, da tail -fder Puffer immer noch gefüllt wird und das Terminal danach ohnehin zurückgesetzt werden muss. Dies ist nicht so inline wie ich gehofft hatte, aber sonst könnte es das sein, wonach ich gesucht habe.
Jari Keinänen
0

Wenn Sie nicht möchten, dass der Ausgang das gesamte aktuelle Terminalfenster belegt, können Sie eine einfache whileSchleife verwenden:

while true; do 
  XXX=$( tail -n1 my.log )
  echo -en " \r$XXX\r"
  sleep 0.5
done; echo
rozcietrzewiacz
quelle
1
Beachten Sie, dass Sie die Terminalemulatoreinstellungen bearbeiten und die Option (oder eine ähnliche Option) deaktivieren müssen, um durch die Terminalausgabe scrollen zu können, während ein ausgabeerzeugender Befehl ausgeführt wird scrollTtyOutput.
Rozcietrzewiacz