在我的 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 的建议进行操作并调用ls
like \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
在输出开始时打印一次转义符,并在最后打印一次lc
and转义符。rc
它们每隔一次出现就紧接在文件名之前或之后。该ec
序列仅在设置后才会出现 - 默认行为是使用reset
or序列,而不是与andrs
组合。您的输出显示的配置类似于:lc
rc
`lc=\033[:rc=m:rs=0...`
...这是典型的,但ec
可以让您拥有更多控制权。例如,如果您想要一个\0
null 分隔的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 生成的颜色并摆脱显示的转义序列...