Ich ändere bei der Arbeit Skripte, die Protokolldateien überwachen, um bestimmte Elemente herauszuheben und farblich hervorzuheben. Die endgültige Ausgabe ist eine Liste mit 6-stelligen Zahlen in mehreren Spalten. Ich konnte ~
am Anfang der Zahl ein hinzufügen, und es macht in der endgültigen Ausgabe nichts kaputt, aber es ist ziemlich hässlich und schwer zu lesen. Wenn ich jedoch versuche, die Zahl einzufärben, entweder in vorhergehenden Bash-Skripten oder bei der endgültigen Verarbeitung der Daten in einem Perl-Skript, wird der farbige Text überschrieben.
Beispielsweise die Originalnummer, die ich hier einsetzen werde $num
:
123456
Ich gebe dies in Perl ein (oder fast dasselbe in Bash):
"\e[1;34m" . $num . "\e[0m"
Und das bekomme ich:
[1;34m123456[0m
Ich habe auch dies hier probiert, eine Escape-Version, aber das Ergebnis ist dasselbe:
"\x1B[1;34m" . $num . "\x1B[0m"
Falls das einen Unterschied macht, hier ist der tatsächliche Stapel an Skripten (es ist ein Durcheinander):
- Perl wird innerhalb eines Shell-Skripts aufgerufen, das dann eine Weiterleitung an
grep
/cut
/etc. durchführt. - Shell-Skript mit mehr
cut
/etc., leitet dann an .pl weiter - Shell-Skript überwacht diese Ausgabe
Vielleicht watch
mag er dann keine Farbe?
Ich weiß es nicht perl
so genau, also würde es wohl nicht schaden, zu zeigen, was ich um die Drucklinien herum sehe:
my $format = ("%-8s") x scalar(@{$a[0]});
printf("$format\n", @$_)
Antwort1
Ich hatte Probleme mit dem „Farbdiebstahl“ beibetrachten, das liegt daran, dass watch einen einfachen /bin/sh-Ausgabestil verwendet, der alle Farben, Aliase, Verknüpfungen … das ganze Drum und Dran überschreibt!
Also habe ich das hier zusammengeschustert, in meine.bashrc, ermöglicht mir die Verwendung aller meiner eigenen Aliase, Verknüpfungen usw.:
Usage:
watcher 20 'somecommand | apipe | grep'
Die Zahl gibt die Verzögerung zwischen den Aktualisierungen in Sekunden an. Der Befehl kann alles enthalten, was Sie angeben können.
###### 'watch' workalike, lets me use my aliases and such
function watcher() { WATCHERTIME=$1 ; WATCHERFILE=/tmp/watcher$$ ; shift ; while true ; do WATCHERHEIGHT=$(($LINES - 5)) ; ( eval $* ) | tail -n ${WATCHERHEIGHT} > ${WATCHERFILE} 2>/dev/null; clear ; /bin/echo -n "Every ${WATCHERTIME} seconds - " ; date ; /bin/echo ; cat ${WATCHERFILE} ; \rm -f ${WATCHERFILE} ; /bin/echo ; /bin/echo "==" ; sleep ${WATCHERTIME} ; done ; }
Um es aufzuschlüsseln:
function watcher()
{
WATCHERTIME=$1
WATCHERFILE=/tmp/watcher$$
shift
while true; do
WATCHERHEIGHT=$(($LINES - 5))
( eval $* ) | tail -n ${WATCHERHEIGHT} > ${WATCHERFILE} 2>/dev/null
clear
/bin/echo -n "Every ${WATCHERTIME} seconds - "
date
/bin/echo
cat ${WATCHERFILE}
\rm -f ${WATCHERFILE}
/bin/echo
/bin/echo "=="
sleep ${WATCHERTIME}
done
}
Es ermittelt die aktuelle Bildschirmhöhe in Zeilen, subtrahiert genug davon für seine eigene Ausgabe, führt dann den angegebenen Befehl wiederholt aus, löscht dann den Bildschirm, zeigt die Ausgabe an und wartet auf die nächste Schleife. Es zeigt unten ein kurzes „==“ an, um anzuzeigen, dass die Ausgabe dort geendet hat. Manchmal ist es hilfreich, dies zu wissen.
Ich habe es auf diese Weise gemacht, damit die Verzögerung bei der Anzeige so gering wie möglich bleibt. Wenn Sie die Ausgabe nicht erfassen und dann anzeigen, tritt eine lange Pause auf und dann die Ausgabe ... eklig.
Da die Farben nicht überlagert werden, erhalten Sie alles, was Sie gewohnt sind. Viel Spaß!
Antwort2
Das Problem besteht darin, dass watch
Curses verwendet wird und die curses
String-Ausgabefunktionen auf einem virtuellen Framebuffer mit separaten Ebenen für Zeichen und ihre Attribute/Farben arbeiten. Strings werden unverändert an den Framebuffer gesendet, ohne Interpretation der Terminaldirektive. Um zu verhindern, dass der Terminalstatus überschrieben wird, ignoriert Curses ESC
(unter anderem) und watch
führt daher standardmäßig keine Farbausgabe aus.
Sie können das Problem beheben, indem Sie den weisen Rat befolgen:jw013oderAbonnieren: Verwenden Sie watch --color
Ihr Skript oder packen Sie es in eine Art while true; do clear; $SCRIPT; sleep 2; done
Schleife.
Antwort3
Sie benötigen wahrscheinlich die --color
Option zum watch
.