plink的输出有什么问题?

plink的输出有什么问题?

在我的 Windows7 机器上,我正在遍历 PuTTy 应用程序的安装路径并运行:

plink <hostname>

连接到我的远程 Linux 主机。

我在输出中看到一些无法识别的字符:

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

这里有什么问题吗?与编码有关吗?

答案1

正如米哈斯所解释的,这些是终端转义序列。如何解释它们取决于终端。您可以按照 michas 的建议进行操作并调用lslike \ls,这将调用ls中的可执行文件$PATH,而不是常见的 shell 别名ls --color=auto。要删除该 shell 别名,您可以执行以下操作:

unalias ls

您还可以添加选项...

ls ${opts} --color=never

...随时将其关闭。例如,禁用颜色序列的另一种方法是:

ls ${opts} | cat

这是可行的,因为在--color=auto模式下ls检查其输出以确定它是否是 tty 设备,如果是,它会注入终端转义来为其输出着色。当它不是终端设备时(例如当它是文件时,|pipe如上面的示例所示),ls不打印转义序列。这是大多数可以为其输出着色的应用程序的标准行为。

但更有趣的是大多数实现提供的 apils来控制这种行为——我觉得这很有趣,并促使我写下这个答案。

ls根据环境变量中的值确定输出的哪些部分要着色$LS_COLORS。该dircolors应用程序是一个用于处理此问题的接口。例如,在我的机器上:

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

...我们可以开始了解ls正在做什么。不过,其中任何一个中都没有具体显示的是编译后的值......

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

其中每一个都处理终端转义代码左侧、终端转义代码右侧以及终端转义序列末尾的内容。正如您在输出中看到的dircolors,myfi=:没有设置为默认值 - 因为通常ls不会对常规文件进行着色。

但如果我们把所有这些放在一起并添加一点,我们可以做这样的事情......

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应该ec在输出开始时打印一次转义符,并在最后打印一次lcand转义符。rc它们每隔一次出现就紧接在文件名之前或之后。该ec序列仅在设置后才会出现 - 默认行为是使用resetor序列,而不是与andrs组合。您的输出显示的配置类似于:lcrc

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

...这是典型的,但ec可以让您拥有更多控制权。例如,如果您想要一个\0null 分隔的ls,可以简单地完成如下:

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^@^@^@$
^@%

您再次可以看到,我们ec在打印第一个转义序列之前额外获得了一个,在最后打印了一个。除了这两个之外,\0空字节仅出现在紧邻文件名之前或之后。您甚至可以看到/用于指示目录的额外斜杠超出了包围它的空值。

这对于包含新行的文件名也适用:

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^@^@^@$
^@%                                       

如果我们把所有这些放在一起,我们可以推测,就您的情况而言,存在三个主要问题,如果其中一个问题得到解决,则可能会消除其他问题。

  • 首先,您的终端设备根本无法正确解释终端颜色转义,或者plink以某种方式使它们无法被您的终端读取。我不确定哪个是真的,但是plink文档对此有这样的说法:

服务器发送的输出将直接写入命令提示符窗口,这很可能不会按照服务器期望的方式解释终端控制代码。因此,例如,如果您运行任何全屏应用程序,您可能会看到窗口中出现奇怪的字符。像这样的交互连接并不是Plink的重点。

为了使用不同的协议进行连接,您可以给命令行选项-ssh-telnet-rlogin-raw。要建立 SSH 连接,例如:

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

如果您已经设置了 PuTTY 保存的会话,则可以提供保存的会话名称,而不是提供主机名。这允许您使用公钥身份验证、指定用户名以及使用 PuTTY 的大多数其他功能:

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:~$
  • 如果这些选项中的任何一个对您不起作用或不可行,那么您可以通过在登录时获取的文件plink中运行检查来解决此问题。.${shell}rc您可以因此启用ls别名,仅有的如果您的登录设备是不是一个plink连接。或者,我想您可以将其完全删除,但这样做会使ls任何登录会话呈现无色。您还可以向 的登录命令添加一个unalias ls或 甚至alias ls='ls --color=never命令plink,从而在使用 登录时仅删除别名plink

  • 最后一个问题是ls- 无论它的别名命令行选项如何 - 都提供了一个在$LS_COLORS.与问题 2 的后一种情况类似,您可以$LS_COLORS在使用 登录时简单地设置为 null 值plink。这样,就不会渲染任何颜色代码,也ls --color=auto不会产生任何差异。

答案2

这些是设置颜色的转义序列:

  • ←[00;34尝试打开蓝色
  • ←[00m尝试重置颜色

由您的终端来解释这些序列并进行着色。

真实的putty有它自己的终端,它能够解释这些。

如果您使用plink,则您正在使用 Windows 终端,该终端无法执行此操作,只能将它们打印出来。

在远程主机上键入type ls,它应该打印如下内容:

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

--color=auto正在生成这些颜色序列。如果通过键入 禁用别名\ls,着色序列就会消失。

答案3

您可能会发现这很有帮助:

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

如果您将 plink 作为 的参数调用ansicon.exe,则会自动转换转义序列。当我连接到我的 Linux 盒子时, 的输出ls会自动着色。

答案4

这种奇怪的行为是由于 ansi 转义码造成的。您可以下载解释 ansi 代码的 ansicon.exe 程序并显示它(ansicon plink.exe plink 参数),这样您就可以看到 shell 生成的颜色并摆脱显示的转义序列...

相关内容