Qual é o problema com a saída do plink?

6

Na minha máquina Windows7, estou atravessando para o caminho instalado do Aplicativo PuTTy e executando:

plink <hostname>

para se conectar ao meu host Linux remoto.

Eu vejo alguns caracteres não reconhecidos na saída como:

-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$

O que está errado aqui? É algo sobre codificação?

    
por Keyshov Borate 10.07.2014 / 08:27

5 respostas

6

Como explicaram michas , essas são sequências de escape de terminal. Como eles são interpretados depende do terminal. Você pode fazer o que o michas sugeriu e chamar ls como \ls , que chamará o executável ls em $PATH , em vez do alias de shell comum ls --color=auto . Para remover esse alias de shell, você pode fazer:

unalias ls

Você também pode adicionar a opção ...

ls ${opts} --color=never

... a qualquer momento para desligá-lo. Outra maneira de desativar as seqüências de cores, por exemplo, é fazer:

ls ${opts} | cat

Isso funciona, porque no --color=auto mode ls verifica sua saída para determinar se é um dispositivo tty e, em caso afirmativo, injeta o terminal para colorir sua saída. Quando não é um dispositivo terminal - por exemplo, quando é um arquivo |pipe como no exemplo acima - ls imprime sem seqüências de escape. Esse é o comportamento padrão da maioria dos aplicativos que podem colorir sua saída.

Mais interessante, porém, é a API que a maioria das implementações de ls fornece para controlar esse comportamento - o que eu acho interessante e que me levou a escrever essa resposta.

ls determina quais partes de sua saída devem ser coloridas, com base nos valores da variável de ambiente $LS_COLORS . O aplicativo dircolors é uma interface para lidar com isso. Por exemplo, na minha máquina:

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.)

... e assim por diante. Quando comparado com ...

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:...

... podemos começar a ter uma ideia do que o ls está fazendo. O que especificamente não é mostrado em qualquer um destes, é o compilado em valores para ...

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

Cada uma dessas lida com o que vai para o lado esquerdo de um código de escape de terminal, o lado direito de um código de escape de terminal e o final de uma sequência de escape de terminal. Como você pode ver na saída dircolors , meu fi=: não está definido como padrão - porque normalmente ls não colore arquivos regulares.

Mas se juntarmos tudo isso e adicionarmos um pouco, podemos fazer coisas como ...

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$

ls deve imprimir a ec escape uma vez no início da saída e lc e rc escapa uma vez no final. Todas as outras ocorrências são imediatamente anteriores ou posteriores a um nome de arquivo. A sequência ec só ocorre se estiver definida - o comportamento padrão é usar a sequência reset ou rs , em vez disso, em combinação com lc e rc . Sua saída mostra uma configuração como:

'lc=3[:rc=m:rs=0...'

... o que é típico, embora ec lhe conceda mais controle. Por exemplo, se você quisesse um ls null delimitado em ec , isso poderia ser feito da seguinte maneira:

LS_COLORS='lc=
touch 'new
line
file'
LS_COLORS='lc=
Z:\sysosd>plink -ssh login.example.com
login as:
:rc=:ec=
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:~$
unalias ls
ls ${opts} --color=never
: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^@^@^@$ ^@%
:rc=:ec=
ls ${opts} | cat
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.)
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:...
: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^@^@^@$ ^@%

Novamente, você pode ver que obtemos um / extra antes que a primeira sequência de escape seja impressa e outra apenas no final. Além desses dois, plink null bytes ocorrem apenas imediatamente antes ou depois de um nome de arquivo. Você pode até ver que a barra plink extra usada para indicar um diretório fica fora dos nulos que o delimitam.

Isso funciona bem também para nomes de arquivos que contêm novas linhas:

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

Se tomarmos tudo isso em conjunto, podemos supor que, no seu caso, há três problemas principais, e se algum deles é abordado, é provável que obvie os outros.

  • Em primeiro lugar, o seu dispositivo de terminal simplesmente não interpreta as fugas de cor do terminal corretamente ou plink está, de alguma forma, tornando-as ilegíveis para o seu terminal. Não sei ao certo o que é verdade, mas os .${shell}rc docs têm isto a dizer sobre isso:

The output sent by the server will be written straight to your command prompt window, which will most likely not interpret terminal control codes in the way the server expects it to. So if you run any full-screen applications, for example, you can expect to see strange characters appearing in your window. Interactive connections like this are not the main point of Plink.

In order to connect with a different protocol, you can give the command line options -ssh, -telnet, -rlogin or -raw. To make an SSH connection, for example:

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$

If you have already set up a PuTTY saved session, then instead of supplying a host name, you can give the saved session name. This allows you to use public-key authentication, specify a user name, and use most of the other features of PuTTY:

'lc=3[:rc=m:rs=0...'
  • Se qualquer uma dessas opções não funcionar para você ou não for viável, você pode resolver isso talvez executando uma verificação em relação a ls no arquivo plink que é originado no login. Você pode, portanto, ativar o ls alias, somente se o seu dispositivo de login não for uma conexão unalias ls . Alternativamente, você poderia removê-lo completamente, suponho, mas isso renderizará alias ls='ls --color=never incolor para qualquer sessão de login. Você também pode adicionar um comando plink ou mesmo plink ao comando de login ls e, desse modo, remover apenas o alias, quando conectado com $LS_COLORS .

  • O último problema é que $LS_COLORS - independentemente das opções de linha de comando com alias - é fornecido um ambiente que especifica os escapes do terminal em plink . Semelhante ao último caso do problema 2, você poderia simplesmente definir ls --color=auto como um valor nulo ao efetuar login com %code% . Dessa forma, não haverá códigos de cores para renderizar e %code% não fará diferença alguma.

por 10.07.2014 / 09:22
6

Essas são seqüências de escape para definir cores:

  • ←[00;34 tenta ativar a cor azul
  • ←[00m tenta redefinir a cor

Cabe ao seu terminal interpretar essas sequências e fazer a coloração.

O% realputty traz seu próprio terminal, que é capaz de interpretá-los.

Se você usa plink , está usando o terminal do Windows, que não é capaz de fazer isso e simplesmente imprime.

No tipo de host remoto type ls , que deve imprimir algo como:

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

Este --color=auto está gerando essas seqüências de cores. Se você desativar o alias digitando \ls , as seqüências de coloração desaparecerão.

    
por 10.07.2014 / 08:39
2

Você pode achar isso útil:

link

Se você chamar plink como um argumento de ansicon.exe , isso traduz as seqüências de escape automaticamente. Quando me conecto à minha caixa linux, a saída de ls é colorida automaticamente.

    
por 06.09.2014 / 01:22
1

Você pode querer executar plink na janela de comando do PowerShell, que pode mostrar caracteres ANSI corretamente ou, na janela cmd.exe, execute este:

C: \ Usuários \ decui > powershell plink.exe [email protected]

(eu testei isso no Win10)

    
por 09.10.2016 / 08:54
0

O estranho beavior é devido aos códigos de escape ansi. Você pode baixar o programa ansicon.exe que interpreta os códigos ansi e exibi-lo (argumentos de plugue ansicon plink.exe) Desta forma você fica capaz de ver as cores geradas pelo shell e se livrar das seqüências de escape sendo mostradas ...

    
por 03.11.2017 / 11:11