So bereinigen Sie die Ausgabe des Linux-Befehls 'script'


35

Ich verwende den Linux-Befehl 'script' http://www.linuxcommand.org/man_pages/script1.html , um einige interaktive Sitzungen zu verfolgen. Die Ausgabedateien davon enthalten nicht druckbare Zeichen, einschließlich meiner Rücktastenanschläge.

Gibt es eine Möglichkeit, diese Ausgabedateien aufzuräumen, sodass sie nur das enthalten, was auf dem Bildschirm angezeigt wurde?

Oder gibt es eine andere Möglichkeit, eine interaktive Shell-Sitzung aufzuzeichnen (Eingabe und Ausgabe)?


"Oder gibt es eine andere Möglichkeit, eine interaktive Shell-Sitzung aufzuzeichnen (Eingabe und Ausgabe)?" Kennst du schon asciinema.org ?
Masterxilo

Antworten:


34

Wenn Sie die Datei anzeigen möchten, können Sie die Ausgabe über senden col -bp. Dies interpretiert die Steuerzeichen. Wenn Sie möchten, können Sie dann weniger durchpfeifen.

col -bp typescript | less -R

colVerwenden Sie auf einigen Systemen stattdessen die folgende Syntax:

col -bp <typescript | less -R

1
Auf meinem System colwürde ich keinen Dateinamen akzeptieren, also habe ich getan col -bp < typescript und bekommen, was ich wollte.
Andrew

Funktioniert bei mir nicht, verschlüsselt einen Teil der Ausgabe.
Alex

1
Auf meinem System less -Rbietet sich eine bessere Leistung an, als zuerst durchzuleiten col -bp.
Brian Hawkins

@ Brian Hawkins Ich stimme zu. Mit col -bp <typescript | less -Rwird die farbige Konsole nicht angezeigt. Mit less -R typescriptwird die farbige Konsole angezeigt!
Trevor Boyd Smith

Dies ist nur dann sinnvoll, wenn Sie das Skript interaktiv in anzeigen möchten less.
Trevor Boyd Smith

18
cat typescript | perl -pe 's/\e([^\[\]]|\[.*?[a-zA-Z]|\].*?\a)//g' | col -b > typescript-processed

Hier ist eine Interpretation der Zeichenfolgeneingabe für perl:

  • s/pattern//gbedeutet, dass eine Ersetzung für die gesamte gEingabezeichenfolge ausgeführt wird (die Option bedeutet, dass die gesamte Eingabe ausgeführt wird, anstatt bei der ersten Ersetzung anzuhalten)

Hier ist eine Interpretation des Regex-Musters:

  • \e Entspricht dem speziellen Steuerzeichen "Escape" (ASCII 0x1A)
  • (und )sind der Anfang und das Ende einer Gruppe
  • |bedeutet, dass die Gruppe mit einem von N Mustern übereinstimmen kann. wo die N Muster sind
    • [^\[\]] oder
    • \[.*?[a-zA-Z] oder
    • \].*?\a
  • [^\[\]] meint
    • passen eine Reihe von Zeichen nicht , wo die nicht Zeichen [und]
  • \[.*?[a-zA-Z] meint
    • Ordne eine Zeichenfolge zu, die mit beginnt, und führe [dann eine non-greedy-Operation .*?bis zum ersten Buchstaben aus
  • \].*?\a meint
    • Finde eine Zeichenfolge, die mit " ]Nicht gierig" beginnt, und tippe dann .*?auf das spezielle Steuerzeichen "Alarm (Glocke)".

1
Ich muss noch herausfinden, wie, aber das funktioniert wirklich;)
asdmin

@asdmin - Grundsätzlich wird hiermit die Ausgabe von typescriptan ein perlProgramm zurückgegeben, das bestimmte Steuerzeichen aus der Ausgabe entfernt, und anschließend die Ausgabe an den Unix- colBefehl weitergeleitet, dessen -bOption alle "Lösch" -Schlüsselartefakte im Transkript entfernt. Anschließend wird die Ausgabe in eine Textdatei umgeleitet.
Peter Nore

Dies verschlüsselt die Ausgabe in der ersten Zeile des Typoskripts für mich, ist aber die beste Antwort.
Alex

Dies scheint bei einigen Typoskripten sehr gut zu funktionieren; Es ist sicherlich lesbarer als die Ausgabe, die von der akzeptierten Antwort erzeugt wird.
Fakedad

legendäre Antwort!
Zack

2

Für eine große Menge von scriptAusgaben würde ich ein Perl-Skript iterativ zusammen hacken. Ansonsten Hand mit einem guten Editor bearbeiten.

Es ist unwahrscheinlich, dass es eine automatisierte Methode gibt, mit der Steuerzeichen scriptauf eine Weise aus der Ausgabe entfernt werden können, die das reproduziert, was zu bestimmten wichtigen Zeitpunkten auf dem Bildschirm angezeigt wurde (z. B. wenn der Host auf das erste Zeichen einer Benutzereingabe gewartet hat ).

Beispielsweise kann der Bildschirm leer sein, außer Andrew $wenn Sie rm /*zwölf Mal (weitaus mehr als erforderlich) die Rücktaste gedrückt haben und dann tippen , was am Ende auf dem Bildschirm angezeigt wird, hängt davon ab, welche Shell ausgeführt wurde und welche aktuellen sttyEinstellungen Sie vorgenommen haben ( Dies könnte sich während einer Sitzung ändern.) Und wahrscheinlich auch einige andere Faktoren.

Das oben Gesagte gilt für jede automatisierte Methode zur kontinuierlichen Erfassung von Ein- und Ausgaben. Die Hauptalternative ist das Aufnehmen von "Screenshots" oder das Ausschneiden und Einfügen des Bildschirms zu geeigneten Zeiten während der Sitzung (was ich für Benutzerhandbücher, Notizen für ein Tagesprotokoll usw. mache).



2

Ich habe verwendet, cat filenamewas Steuerzeichen entfernt :-)


imo das ist eine schönere Antwort, da es wirklich alle Steuerzeichen entfernt.
Nathanael Farley

Unter OSX entfernt cat keine Farbkontrollzeichen ...
Nick

9
Eigentlich entfernt cat die Steuerzeichen gar nicht, sondern gibt sie wörtlich aus und das Terminal interpretiert sie dann. Das könnte für Sie funktionieren, wenn Ihr Typoskript im Verhältnis zu Ihrem Terminalpuffer kurz ist und Sie es einfach kopieren und aus dem Terminal einfügen können. Nicht so gut, wenn Ihr Typoskript groß ist.
mc0e

1
Einverstanden. Dies entfernt nichts. Die Shell kann sie einfach interpretieren. Sie sind immer noch anwesend.
Kentgrav

2

Wenn Sie Ihre Befehle aufzeichnen möchten (z. B. um sie später in ein Bash-Skript umzuwandeln), müssen Sie einen vernünftigen Hack ausführen script(1)und anschließend ausführen

bash -x

Danach grepsucht die Ausgabedatei (normalerweise "typescript") nach Zeilen, die mit einem "+" beginnen. Der reguläre Ausdruck ^\+macht den Trick.


2

Wenn Sie die Ausgabe in eine Datei schreiben möchten:

col -bp < typescript >>newfile

Verwenden Sie den Befehl unix2dos, um Dateien in das Windows-Format zu konvertieren


1
Auf Ubuntu 14.04 hinterlässt das am Anfang und Ende von Zeilen viel Müll. Sehr gut lesbar, aber nicht wirklich sauber.
mc0e

2

col -bp verarbeitet die Backspaces wie gewünscht (AFAIK). Aber es verstümmelt die Farbfluchtsequenzen. Es kann sinnvoll sein, zuerst die Farbsequenzen zu entfernen und dann, falls möglich, die Backspaces zu verarbeiten.

Dies ist ein sehr häufiger Bedarf, und ich bin überrascht, dass es keine weiteren Lösungen dafür gibt. Es ist extrem üblich, eine Sitzung zu skripten, dann muss jemand das Verfahren überprüfen. Sie möchten all die kleinen Tippfehler beseitigen und Escape-Sequenzen einfärben, um ein "sauberes" Skript für den späteren Gebrauch zu erstellen. Einfacher ASCII-Text bevorzugt. Ich denke, dies ist das, was unter "lesbar für Menschen" zu verstehen ist, und es ist sehr vernünftig, dies zu tun.


1

Ich fand die Antwort, die Dewtall auf eine ähnliche Frage auf dem Unix-Board lieferte , effektiver beim Entfernen von Steuerzeichen aus der Skriptausgabe, wenn Sie sich in einer Umgebung befinden, in der Perl für Sie verfügbar ist.

Dewtalls Drehbuch:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}

So entfernen Sie die Steuerzeichen:

./dewtalls-script.pl < output-from-script-that-needs-control-characters-removed


0

Ich habe einen guten Weg gefunden, das zu tun. Auf meinem System werden lange Ausgabezeilen mit "^ M" (Leerzeichen gefolgt von Wagenrücklauf) bestreut. Das "^ M" kann gut durch das Nullzeichen "^ @" ersetzt werden, das beim Einfügen der Datei überhaupt nicht angezeigt wird.

Ich nehme auch das Timing auf. Um die Datei also perfekt wiederzugeben, kann ich "^ M" nicht einfach mit den folgenden Befehlen vollständig entfernen (da die Skriptwiedergabe Byte zählt):

tr '\r' '\0' | sed 's/ \x0//g'

Ich führe meinen Skriptbefehl folgendermaßen aus:

script -t -f session.log 2>timing

Also, was ich danach mache, ist:

cat session.log | tr '\r' '\0' > typescript 
scriptreplay -t timing | sed 's/ \x0//g'

Bei der ersten Bearbeitung (vor der Wiedergabe) wird die Anzahl der Bytes in der Datei beibehalten. Bei der zweiten Bearbeitung (nach der Wiedergabe) werden Leerzeichen an zufälligen Stellen entfernt. (Beachten Sie, dass die Skriptwiedergabe standardmäßig nach der Eingabedatei "typescript" sucht, weshalb ich sie nach "timing" nicht angegeben habe.)


-1

Auch dos2unix am Ausgang erledigt den Trick


7
Können Sie erklären, wie Sie damit die Aufgabe erledigen können?
Ben N

-1

Eine andere Lösung besteht darin, stringsnur druckbare Zeichen aus einer Datei (oder aus der Standardeingabe) zu drucken:

strings -n 1 filename

Mit dieser -n 1Option wird die Mindestlänge der zu erhaltenden Sequenzen auf eins festgelegt. Auf diese Weise wird sichergestellt, dass auch einzelne druckbare Zeichen, die von nicht druckbaren Zeichen umgeben sind, erhalten bleiben.

Ein möglicher Nachteil dieses Ansatzes besteht darin, dass stringsZeilenumbrüche zwischen aufeinander folgenden Zeichenfolgen für druckbare Zeichen eingefügt werden. Zum Beispiel eine Datei mit Inhalt

Foo<SOMECONTROLCHAR>Bar

(wobei <SOMECONTROLCHAR>es sich um ein Steuerzeichen oder ein anderes nicht druckbares Zeichen handelt) wird als zurückgegeben

Foo
Bar

Ein weiteres Problem, das in den Kommentaren angesprochen wurde, besteht darin, dass einige Folgen von Steuerzeichen aus einer Kombination von druckbaren und nicht druckbaren Zeichen bestehen und dieser Ansatz nur einen Teil davon entfernen würde.

Es ist stringsjedoch eine gute Aufgabe, Steuerzeichen wie die in der Frage erwähnte Rücktaste zu entfernen.


stringsentfernt nicht alle nicht druckbaren Zeichen. Es identifiziert und druckt Sequenzen druckbarer Zeichen . Das ist nicht dasselbe.
ein Lebenslauf

@ MichaelKjörling, Sie haben Recht, standardmäßig werden stringsnur Sequenzen mit einer Mindestlänge von 4 gedruckt. Ich habe meine Antwort korrigiert, indem ich die -n 1Option hinzugefügt habe, die die Mindestlänge auf 1 setzt. Vielen Dank für den Hinweis.
justfortherec

In der Antwort wird immer noch dieselbe Behauptung aufgestellt, bei stringsder alle nicht druckbaren Zeichen entfernt wurden. Daher ist die Behauptung genauso falsch wie vor der Bearbeitung. Es ist auch offensichtlich kaputt, weil "einige Farbcodes" (und Kontrollcodes im Allgemeinen) oft aus druckbaren und nicht druckbaren Zeichen bestehen. Zum Beispiel, um eine Steuercodesequenz der Textfarbe ändern könnte , ESC[01;52mwenn ESCdie Escape - Zeichen (Byte - Wert 27) Single ist. Die Verwendung von, stringswie Sie vorschlagen, würde [01;52min der Ausgabe verbleiben, was bedeutungslos ist.
ein CVn

Guter Punkt, @ MichaelKjörling. Besonders das Beispiel mit dem Farbcode war sehr unglücklich. Danke, dass Sie mir geholfen haben, meine Antwort zu verbessern. Gehen die Änderungen angemessen auf Ihre Bedenken ein? stringsMöglicherweise nicht die gleiche Aufgabe wie bei einigen anderen Antworten, aber meiner Meinung nach ist dies ein gültiger Ansatz, um das in der Frage beschriebene Problem zu lösen.
justfortherec
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.