2011-01-13 10 views
5

Ich möchte eine Datei in fortlaufenden Intervallen für Inhalte überprüfen, die sich ändern. "tail -f" reicht nicht aus, da die Datei nicht größer wird."tail -f" Alternative, die das Terminal-Fenster nicht scrollt

konnte ich eine einfache Verwendung while-Schleife in bash auf den gleichen Effekt:

while [ 1 ]; do cat /proc/acpi/battery/BAT1/state ; sleep 10; done 

Es funktioniert, obwohl es den unerwünschten Effekt des Rollens mein Terminalfenster hat.

So, ich frage mich, gibt es einen Linux/Shell-Befehl, der die Ausgabe dieser Datei anzeigen würde, ohne das Terminal zu scrollen?

+0

haben Sie versucht zu sehen? – Rozuur

+0

Ich hatte das vorher nicht als Anregung bekommen. –

+0

Es gab viele richtige Antworten darauf. Danke an gabuzo, SiegeX, Jander und Omnifarious. Aber derjenige, der am ehesten meinem Wunsch entsprach, stammte von Dennis Williamson. Vielen Dank, dass Sie sich die Zeit genommen haben! –

Antwort

6

Kombiniert mehrere Ideen aus anderen Antworten plus ein paar andere Tricks, wird dies die Datei ohne den Bildschirm zu löschen oder scrollen (mit Ausnahme des ersten Zyklus, wenn die Eingabeaufforderung am unteren Rand des Bildschirms ist). die Anzahl der Sekunden zwischen Aktualisierungen, Startlinie und der Anzahl der Zeilen als Argumente

up=$(tput cuu1)$(tput el); while true; do (IFS=$'\n'; a=($(</proc/acpi/battery/BAT1/state)); echo "${a[*]}"; sleep 1; printf "%.0s$up" ${a[@]}); done 

Es ist natürlich etwas, was man nicht von Hand eingeben würde, so können Sie es mit einer Funktion machen, die die Dateinamen führen.

watchit() { 
    local up=$(tput cuu1)$(tput el) IFS=$'\n' lines 
    local start=${3:-0} end 
    while true 
    do 
     lines=($(<"$1")) 
     end=${4:-${#lines[@]}} 
     echo "${lines[*]:$start:$end}" 
     sleep ${2:-1} 
     # go up and clear each line 
     printf "%.0s$up" "${lines[@]:$start:$end}" 
    done 
} 

Run es:

watchit /proc/acpi/battery/BAT1/state .5 0 6 

Das zweite Argument (Sekunden zwischen Aktualisierungen) standardmäßig auf 1. Die dritte Argument (Ausgangsleitung) automatisch auf 0.Das vierte Argument (Anzahl der Zeilen) wird standardmäßig auf die gesamte Datei angewendet. Wenn Sie die Anzahl der Zeilen weglassen und die Datei wächst, kann es zu einem Scrolling kommen, um die neuen Zeilen aufzunehmen.

Bearbeiten: Ich habe ein Argument hinzugefügt, um die Häufigkeit von Updates zu steuern.

+0

Ich hatte ursprünglich eine Variation mit 'tput cup 0 0' gemacht, aber ich entfernte es, weil es ein' clear' erforderte und nicht die Möglichkeit hatte, mit der Ausgabe zu beginnen, wo der Cursor gerade ist. Dein Skript ist genau das, was mein Ziel sein wollte. Ich kannte diese beiden Parameter nicht. Ich werde mehr nach 'tput' für zukünftige Skripte suchen müssen. +1 – SiegeX

+0

P.S. Ich denke, Sie können einfach Ihr Skript nur ein bisschen mit lokalen Zeilen = ($ (<"$ 1")) IFS = $ '\ n'' anstelle von 'lesen' mit der hier-Zeichenfolge – SiegeX

+0

@SiegeX: Danke. Ich habe aus irgendeinem Grund, der zu der Zeit einen Sinn ergeben hat, einen Umweg mit dem 'Lesen' gemacht, dann bin ich nicht zurückgegangen, wenn es nicht gebraucht wurde. Ich werde meine Antwort bearbeiten. –

12
watch -n 10 cat /proc/acpi/battery/BAT1/state 

Sie können die -d Flag hinzufügen, wenn Sie es, die Unterschiede von einer Iteration zur nächsten markieren möchten.

+0

+1 für das Flag "-d" – gabuzo

+0

Beachten Sie, dass "Watch" standardmäßig in Debian, aber nicht in BSD installiert ist. –

+1

@jleedev: Beachten Sie, dass BSD nicht Linux ist. – slebetman

9

watch ist dein Freund. Es verwendet Flüche, so dass es nicht Ihr Terminal scrollt.

Usage: watch [-dhntv] [--differences[=cumulative]] [--help] [--interval=<n>] [--no-title] [--version] <command> 
    -d, --differences[=cumulative]  highlight changes between updates 
       (cumulative means highlighting is cumulative) 
    -h, --help       print a summary of the options 
    -n, --interval=<seconds>    seconds to wait between updates 
    -v, --version       print the version number 
    -t, --no-title      turns off showing the header 

Ihr Beispiel So nimmt es wird sein:

watch -n 10 cat /proc/acpi/battery/BAT1/state 
+0

Ich habe dir nicht die - 1, hat jemand anderes im Grunde genommen eine doppelte Antwort gegeben. – Omnifarious

+0

Wow, das ist hart, wir haben das zur gleichen Zeit gemacht. – gabuzo

+1

+1 zu counter dumm -1 – slebetman

3

Meine Lieblinge, die an Orten arbeiten, die nicht watch haben, ist dies:

while true; do clear ; cat /proc/acpi/battery/BAT1/state ; sleep 10; done 
+0

Interessante nehmen Sie das an. Vielen Dank! –

3

die kanonische (und am einfachsten und am flexibelsten) ist die Antwort watch, wie andere gesagt haben. Aber wenn Sie nur die erste Zeile einer Datei sehen wollen, hier ist eine Alternative, dass weder löscht noch scrollt das Terminal:

while line=`head -n 1 /proc/acpi/battery/BAT1/state` \ 
    && printf "%s\r" "$line" \ 
    && sleep 10 
do 
    printf "%s\r" "`echo -n "$line" | sed 's/./ /g'`" 
done 
echo 

Der Wagenrücklauf ist das Kernkonzept hier. Es weist den Cursor an, wie ein Zeilenvorschub an den Anfang der aktuellen Zeile zurückzukehren, ohne jedoch zur nächsten Zeile zu wechseln. Der Befehl printf wird hier verwendet, weil (1) er nicht automatisch einen Zeilenumbruch hinzufügt und (2) er \r in einen Wagenrücklauf übersetzt.

Die erste printf druckt Ihre Linie. Der zweite löscht es, indem es mit Leerzeichen überschrieben wird, so dass Sie keinen Müll sehen, wenn die nächste zu druckende Zeile kürzer ist.

Beachten Sie, dass, wenn die gedruckte Zeile länger als die Breite Ihres Terminals ist, das Terminal trotzdem scrollen wird.

+0

Ziemlich cool! Nun, wenn dies für 6 Zeilen statt einer funktionieren könnte, wäre es perfekt. –

+2

Dies kann etwas einfacher gemacht werden mit: 'while line = $ (head -n 1/proc/acpi/Batterie/BAT1/state); printf "% - * s \ r" $ COLUMNS "$ line"; Schlaf 10; done' – SiegeX

+0

@SiegeX: Nette printf Meisterschaft! Ich hatte nicht bemerkt, dass du das mit shell printf machen kannst. Außerdem hätte ich erwartet, dass der Cursor nach dem Ausdruck des $ COLUMNS'ten Zeichens umschlingt, aber das Testen sagt etwas anderes. – Jander

Verwandte Themen