Was ist das Problem mit der Ausgabe von Plink?

8

Auf meinem Windows7-Computer gehe ich zum installierten Pfad der PuTTy-Anwendung und führe Folgendes aus:

plink <hostname>

um eine Verbindung zu meinem Remote-Linux-Host herzustellen.

Ich sehe einige nicht erkannte Zeichen in der Ausgabe als:

-bash-3.2$ ls -lrt
←[00mtotal 96
drwx------ 5 lg262728 lg262728  4096 Jun 10 15:32 ←[00;34mmyScripts←[00m
drwx------ 2 lg262728 lg262728  4096 Jun 12 13:19 ←[00;34mmyLangs←[00m
drwxr-xr-x 4 lg262728 lg262728  4096 Jul  1 07:43 ←[00;34mmyWorkSpace←[00m
←[m-bash-3.2$

Was ist hier falsch? Geht es um Codierung?

Keyshov Borate
quelle

Antworten:

7

Wie michas erklärt hat , handelt es sich um terminale Escape-Sequenzen. Wie sie interpretiert werden, hängt vom Terminal ab. Sie können tun, was michas vorgeschlagen hat, und lslike aufrufen \ls, wodurch die lsausführbare Datei $PATHanstelle des allgemeinen Shell-Alias aufgerufen wird ls --color=auto. So entfernen Sie diesen Shell-Alias:

unalias ls

Sie können auch die Option hinzufügen ...

ls ${opts} --color=never

... jederzeit auszuschalten. Eine andere Möglichkeit, die Farbsequenzen zu deaktivieren, besteht beispielsweise darin, Folgendes zu tun:

ls ${opts} | cat

Dies funktioniert, da im --color=autoModus lsdie Ausgabe überprüft wird, um festzustellen, ob es sich um ein tty-Gerät handelt, und in diesem Fall das Terminal-Escape injiziert, um die Ausgabe einzufärben. Wenn es sich nicht um ein Endgerät handelt - wie wenn es sich stattdessen um eine |pipeDatei wie im obigen Beispiel handelt - werden lskeine Escape-Sequenzen gedruckt. Dies ist das Standardverhalten der meisten Anwendungen, die ihre Ausgabe einfärben können.

Interessanter ist jedoch die API, die die meisten lsImplementierungen zur Steuerung dieses Verhaltens bereitstellen - was ich interessant finde und die mich veranlasst hat, diese Antwort zu schreiben.

lsBestimmt anhand der Werte in der $LS_COLORSUmgebungsvariablen , welche Teile der Ausgabe eingefärbt werden sollen. Die dircolorsAnwendung ist eine Schnittstelle, um dies zu handhaben. Zum Beispiel auf meinem Computer:

dircolors -p

...
# Below are the color init strings for the basic file types. A color init
# string consists of one or more of the following numeric codes:
# Attribute codes:
# 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
# Text color codes:
# 30=black 31=red 32=green 33=yellow 34=blue 35=magenta 36=cyan 37=white
# Background color codes:
# 40=black 41=red 42=green 43=yellow 44=blue 45=magenta 46=cyan 47=white
#NORMAL 00 # no color code at all
#FILE 00 # regular file: use no color at all
RESET 0 # reset to "normal" color
DIR 01;34 # directory
LINK 01;36 # symbolic link. (If you set this to 'target' instead of a
 # numerical value, the color is as for the file pointed to.)

... und so weiter. Wenn verglichen mit...

printf %s "$LS_COLORS"

rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:\
bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:\
ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:...

... wir können anfangen, eine Vorstellung davon zu bekommen, was lstut. Was in keinem von diesen speziell gezeigt wird, sind die in ...

lc=\e[:rc=m:ec=:

Jedes dieser Elemente behandelt die linke Seite eines Terminal-Escape-Codes, die rechte Seite eines Terminal-Escape-Codes und das Ende einer Terminal-Escape-Sequenz. Wie Sie in der dircolorsAusgabe sehen können, ist my fi=:nicht als Standard festgelegt, da lsreguläre Dateien normalerweise nicht eingefärbt werden.

Aber wenn wir all dies zusammen nehmen und ein wenig hinzufügen, können wir Dinge tun wie ...

mkdir dir ; touch file1 file2
LS_COLORS=\                                    
'lc=\nLEFT_SIDE_ESCAPE_SEQUENCE\n:'\                                                            
'rc=\nRIGHT_SIDE_ESCAPE_SEQUENCE\n:'\
'ec=\nEND_OF_ESCAPE_SEQUENCE:'\
'fi=REGULAR_FILE_ESCAPE_CODE:'\                          
'di=DIRECTORY_ESCAPE_CODE:'\
ls -l --color=always | cat -A
total 0$
drwxr-xr-x 1 mikeserv mikeserv 0 Jul 10 01:05 $
END_OF_ESCAPE_SEQUENCE$
LEFT_SIDE_ESCAPE_SEQUENCE$
DIRECTORY_ESCAPE_CODE$
RIGHT_SIDE_ESCAPE_SEQUENCE$
dir$
END_OF_ESCAPE_SEQUENCE/$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 $
LEFT_SIDE_ESCAPE_SEQUENCE$
REGULAR_FILE_ESCAPE_CODE$
RIGHT_SIDE_ESCAPE_SEQUENCE$
file1$
END_OF_ESCAPE_SEQUENCE$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 $
LEFT_SIDE_ESCAPE_SEQUENCE$
REGULAR_FILE_ESCAPE_CODE$
RIGHT_SIDE_ESCAPE_SEQUENCE$
file2$
END_OF_ESCAPE_SEQUENCE$
$
LEFT_SIDE_ESCAPE_SEQUENCE$
$
RIGHT_SIDE_ESCAPE_SEQUENCE$

lssollte das ecEscape einmal am Anfang der Ausgabe und das lcund Escape einmal am Ende drucken rc. Jedes zweite Mal, wenn sie auftreten, steht unmittelbar vor oder nach einem Dateinamen. Die ecSequenz tritt nur auf, wenn sie festgelegt ist. Standardmäßig wird die Sequenz resetoder rsstattdessen in Kombination mit lcund verwendet rc. Ihre Ausgabe zeigt eine Konfiguration wie:

`lc=\033[:rc=m:rs=0...`

... was typisch ist, aber ecIhnen mehr Kontrolle gewährt. Wenn Sie beispielsweise jemals eine durch \0Nullen getrennte Null haben wollten ls, können Sie dies so einfach erreichen wie:

LS_COLORS='lc=\0:rc=:ec=\0\0\0:fi=:di=:' ls -l --color=always | cat -A                                        
total 0$
drwxr-xr-x 1 mikeserv mikeserv 0 Jul 10 01:05 ^@^@^@^@dir^@^@^@/$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file1^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file2^@^@^@$
^@%

Wieder können Sie sehen, dass wir eine zusätzliche erhalten, eckurz bevor die erste Escape-Sequenz gedruckt wird, und eine direkt am Ende. Abgesehen von diesen beiden treten \0Null-Bytes nur unmittelbar vor oder nach einem Dateinamen auf. Sie können sogar sehen, dass der zusätzliche /Schrägstrich, der zum Anzeigen eines Verzeichnisses verwendet wird, außerhalb der Nullen liegt, die es einschließen.

Dies funktioniert auch für Dateinamen, die neue Zeilen enthalten:

touch 'new
line
file'
LS_COLORS='lc=\0:rc=:ec=\0\0\0:fi=:di=:' \
ls -l --color=always | cat -A

total 0$
drwxr-xr-x 1 mikeserv mikeserv 0 Jul 10 01:05 ^@^@^@^@dir^@^@^@/$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file1^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:08 ^@file2^@^@^@$
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 10 01:43 ^@new$
line$
file^@^@^@$
^@%                                       

Wenn wir all dies zusammen nehmen, können wir vermuten, dass es in Ihrem Fall drei Hauptprobleme gibt, und wenn eines davon angesprochen wird, wird es wahrscheinlich die anderen vermeiden.

  • Erstens interpretiert Ihr Endgerät entweder die Escapefarben der Terminals einfach nicht richtig oder plinkmacht sie auf irgendeine Weise für Ihr Terminal unlesbar. Ich bin mir nicht sicher, was wahr ist, aber die plinkDokumente haben Folgendes zu sagen:

Die vom Server gesendete Ausgabe wird direkt in Ihr Eingabeaufforderungsfenster geschrieben, in dem die Terminalsteuerungscodes höchstwahrscheinlich nicht so interpretiert werden, wie es der Server erwartet. Wenn Sie beispielsweise Vollbildanwendungen ausführen, können Sie erwarten, dass in Ihrem Fenster seltsame Zeichen angezeigt werden. Solche interaktiven Verbindungen sind nicht der Hauptpunkt von Plink.

Um mit einem anderen Protokoll zu verbinden, können Sie die Befehlszeilenoptionen geben -ssh, -telnet, -rloginoder -raw. So stellen Sie eine SSH-Verbindung her:

Z:\sysosd>plink -ssh login.example.com
login as:

Wenn Sie bereits eine gespeicherte PuTTY-Sitzung eingerichtet haben, können Sie anstelle eines Hostnamens den Namen der gespeicherten Sitzung angeben. Auf diese Weise können Sie die Authentifizierung mit öffentlichem Schlüssel verwenden, einen Benutzernamen angeben und die meisten anderen Funktionen von PuTTY verwenden:

Z:\sysosd>plink my-ssh-session
Sent username "fred"
Authenticating with public key "fred@winbox"
Last login: Thu Dec  6 19:25:33 2001 from :0.0
fred@flunky:~$
  • Wenn eine dieser Optionen für Sie entweder nicht funktioniert oder auf andere Weise nicht durchführbar ist, können Sie dies beheben, indem Sie möglicherweise eine Prüfung plinkin Ihrer .${shell}rcDatei durchführen, die beim Anmelden bezogen wird. Sie könnten dadurch die ermöglichen lsalias, nur wenn Ihre Login - Gerät ist nicht eine plinkVerbindung. Alternativ können Sie es vermutlich ganz entfernen, aber dies macht es lsfür jede Anmeldesitzung farblos. Sie können dem Anmeldebefehl auch einen unalias lsoder sogar einen alias ls='ls --color=neverBefehl hinzufügen plinkund dabei den Alias ​​nur entfernen, wenn Sie mit angemeldet sind plink.

  • Das letzte Problem besteht darin, dass ls- unabhängig von den Alias-Befehlszeilenoptionen - eine Umgebung bereitgestellt wird, in der Terminal-Escapezeichen angegeben sind $LS_COLORS. Ähnlich wie im letzteren Fall von Problem 2 können Sie $LS_COLORSbeim Anmelden mit einfach einen Nullwert festlegen plink. Auf diese Weise müssen keine Farbcodes gerendert werden, und ls --color=autoes macht überhaupt keinen Unterschied.

mikeserv
quelle
sehr gute Erklärung, insbesondere von Farbcodes, aber ls | Katze wird mir keine Ausgabe vom Typ ls -l geben, danke!
Keyshov Borate
@ Keys - nein, Sie ls -l | cat
müssten
Ich habe es gerade getan, aber wie funktioniert das Ganze? Soweit ich wusste, benötigt cat einen Dateinamen als Parameter. Hier übergeben wir diese Ausgabe nur an cat!
Keyshov Borate
@Keys - nun, catder Hauptzweck ist es, es stdinmit seinem zu verketten stdout. Nun ja ... ok, so kann es auch vorhandene Dateien hinzufügen , auf der Befehlszeile angegeben , um seine , stdinaber es ist nach wie vor nur verketten zwei Ströme - <inzu >out. Ich verwende es oben in einigen Beispielen, weil die GNU-Version auch Steuerzeichen interpretieren und anzeigen kann - die ^@NUL-Bytes darstellen. In jedem Fall ist die |pipeist Datei ihre stdin- was auch ist ls‚s stdout- und das Terminal ist cat‘ s stdoutso tut es < lsin > $TTYaus.
Mikeserv
7

Dies sind Escape-Sequenzen zum Festlegen von Farben:

  • ←[00;34 versucht die blaue Farbe einzuschalten
  • ←[00m versucht die Farbe zurückzusetzen

Es liegt an Ihrem Terminal, diese Sequenzen zu interpretieren und die Färbung durchzuführen.

Der Real puttybringt ein eigenes Terminal mit, das diese interpretieren kann.

Wenn Sie verwenden plink, verwenden Sie Ihr Windows-Terminal, das dies nicht kann, und drucken sie einfach aus.

Auf dem Remote-Host-Typ type ls, der Folgendes drucken soll:

ls is aliased to `ls --color=auto'

Dies --color=autoerzeugt diese Farbsequenzen. Wenn Sie den Alias ​​durch Eingabe deaktivieren \ls, sind die Farbsequenzen nicht mehr vorhanden.

michas
quelle
cool! Wie auch immer, um die Farbe dauerhaft zu deaktivieren oder die Windows-Eingabeaufforderung zu lesen und zu erfahren, was dies "← [00; 34" & "← [00m" ist.
Keyshov Borate
Um dies dauerhaft zu deaktivieren, suchen Sie den Ort, an dem der Alias ​​festgelegt ist. Dies ist wahrscheinlich eine Init-Datei wie ~/.bashrcoder ~/.profile. Entfernen / kommentieren Sie einfach den Alias ​​dort.
Michas
3

Dies kann hilfreich sein:

http://adoxa.altervista.org/ansicon/

Wenn Sie plink als Argument von aufrufen ansicon.exe, werden die Escape-Sequenzen automatisch übersetzt. Wenn ich mich mit meiner Linux-Box verbinde, wird die Ausgabe von lsautomatisch gefärbt.

Nickzeff
quelle
1

Möglicherweise möchten Sie plink im PowerShell-Befehlsfenster ausführen, in dem ANSI-Zeichen ordnungsgemäß angezeigt werden können, oder im cmd.exe-Fenster Folgendes ausführen:

C: \ Users \ decui> Powershell plink.exe [email protected]

(Ich habe dies in Win10 getestet)

Dexuan
quelle
Funktioniert nicht unter Win7. Oder meintest du ISE? Das hätte vielleicht funktioniert, hängt aber einfach für mich.
Adil Hindistan
für mich funktioniert es nicht auf W10, es kann keine Charaktere zeigen
stiv
0

Das seltsame Verhalten ist auf Ansi-Fluchtcodes zurückzuführen. Sie können das Programm ansicon.exe herunterladen, das Ansi-Codes interpretiert und anzeigt (Argumente von ansicon plink.exe plink). Auf diese Weise können Sie die von der Shell erzeugten Farben sehen und die angezeigten Escape-Sequenzen entfernen ...

Jean Michael
quelle