windows 为什么会出现“非法字符:^M”错误?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2658931/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 14:18:03  来源:igfitidea点击:

Why error "illegal character: ^M"?

windowsunixformatasciizsh

提问by hhh

I got some sort of formatting -problem that I cannot understand, a short example below using Zsh. Why?

我遇到了一些我无法理解的格式问题,下面是一个使用 Zsh 的简短示例。为什么?

$ values=( 300 400 )
$ echo "scale=20; $values[1]-$values[2]" | bc
(standard_in) 1: illegal character: ^M         // Why does it not print -100?
$ echo $values                                 // no ^M sign found!
300 400

Helper questions

帮手问题

  1. Why is 5E 4d 0a, ie ^M, 13th char in ASCII?
  2. Why is the ending sign "0a" shown as a dot "."? The "." is "2E" in Hex.
  1. 为什么5E 4d 0a,即^M,第13字符以ASCII?
  2. 为什么结尾符号“0a”显示为点“.”?这 ”。” 是十六进制的“2E”。

回答by rjh

Unix and Windows have different line ending formats. In the Unix world, lines end with the linefeed character (LF, ascii char 10). Windows ends lines with a carriage return (CR, ascii char 13) followed by a linefeed.

Unix 和 Windows 有不同的行结束格式。在 Unix 世界中,行以换行符(LF,ascii char 10)结束。Windows 以回车符 (CR, ascii char 13) 结束行,后跟换行符。

Files with Windows line endings must be converted to Unix format before they can work with Unix tools. Otherwise programs like bcsee the CR characters as junk and complain, as in your case.

带有 Windows 行结尾的文件必须先转换为 Unix 格式,然后才能使用 Unix 工具。否则bc,像您的情况一样,程序会将 CR 字符视为垃圾并抱怨。

To convert files to Unix format, you can use dos2unix(1)if you have it installed, or alternately pass it through sed 's/^M//g'(but don't type a literal ^M - press Ctrl+V, followed by Ctrl+M).

要将文件转换为 Unix 格式,您可以使用(dos2unix(1)如果您安装了它),或者通过它sed 's/^M//g'(但不要输入文字 ^M - 按 Ctrl+V,然后按 Ctrl+M)。

So why ^M? Well, the carriage return is a nonprintable character. It has no printable representation. For convenience, your terminal will display it as ^M*. So why didn't it appear when you did echo $values? Unfortunately, the command line argument processing strips it out, so you don't see it.

那为什么^M?嗯,回车是一个不可打印的字符。它没有可打印的表示。为方便起见,您的终端会将其显示为^M*. 那为什么你这样做的时候它没有出现echo $values呢?不幸的是,命令行参数处理把它去掉了,所以你看不到它。

Also for your convenience, your terminal allows you to typenonprintable characters via Ctrl+V and Ctrl + some letter. Ctrl+V and Ctrl+M will produce a ^Mcharacter, but move your cursor left and right and you'll see it skips over the whole thing as a single character - notthe same as typing ^followed by M. While yousee ^M, command line programs see only the raw data, and will see an actual carriage return character.

同样为了您的方便,您的终端允许您通过 Ctrl+V 和 Ctrl + 一些字母输入不可打印的字符。按Ctrl + V和Ctrl + M将产生一个^M字符,但左右移动光标,然后右拐,你就会看到它跳过了整个事情作为一个单一的字符-打字一样^其次M。当看到 时^M,命令行程序只能看到原始数据,并且会看到实际的回车符。

Why is 5E 4d 0a, ie ^M, 13th char in ASCII?

为什么 5E 4d 0a,即 ^M,ASCII 中的第 13 个字符?

You ran hexdumpon the output of echo "^M", which produces three characters: a ^, a M, and a linefeed character (LF). See above, that's not the same as a carriage return!

您运行hexdump了 的输出echo "^M",它产生三个字符:a ^、aM和换行符 (LF)。见上,这和回车不一样!

Why is the ending sign 0a shown as .? . is 2E in DEC. Hex number 5E is 94 in DEC, 4d is 77 in DEC.

为什么结尾符号 0a 显示为 .?. 是 2E 在 DEC。十六进制数 5E 在 DEC 中是 94,4d 在 DEC 中是 77。

Hexdump displays all non-printable characters as .characters, including carriage return and line feed characters.

Hexdump 将所有不可打印的字符显示为.字符,包括回车符和换行符。



*Why M in particular? The convention is to add 64 to the ASCII code. A carriage return is ASCII code 13 (0x0D). Add 64 and you get 77 (0x4D) which is an uppercase M. See this pagefor a full listing.

*为什么特别是M?约定是将 64 添加到 ASCII 代码。回车是 ASCII 码 13 (0x0D)。添加 64,您会得到 77 (0x4D),这是一个大写的 M。请参阅此页面以获取完整列表。

回答by Bozhidar Batsov

^M in one character - the Carriage Return is dos/windows, or ASCII 13 character. It seems that somehow you compromised your input, maybe by pasting something from a windows file or something like that...

^M 一个字符 - 回车是 dos/windows,或 ASCII 13 字符。似乎您以某种方式妥协了您的输入,也许是通过粘贴 Windows 文件中的某些内容或类似的内容...

回答by Platinum Azure

You might have better luck if you run your file through dos2unix, if that program is available on your system.

如果您通过 运行您的文件dos2unix,如果该程序在您的系统上可用,您的运气可能会更好。

Among other things, dos2unixwill convert the Windows \r\n line endings to Unix-style \n line endings.

除其他外,dos2unix将 Windows \r\n 行尾转换为 Unix 样式 \n 行尾。

回答by hhh

Answers to Helper Questions

帮手问题的答案

I. Why is 5E 4d 0a, ie ^M, 13th char in ASCII?

The newline is the 0a, please, see the example provided by ZyX below. rjh clarified something about the 13th char. The "echo -nprevents echo from adding a newline at the end of its output". I am using Debian.

$ echo "scale=20; $values[1]-$values[2]" | hexdump -C
00000000  73 63 61 6c 65 3d 32 30  3b 20 5b 31 5d 2d 5b 32  |scale=20; [1]-[2|
00000010  5d 0a                                             |].|
00000012
xyz@xyz:~$ echo -n "scale=20; $values[1]-$values[2]" | hexdump -C
00000000  73 63 61 6c 65 3d 32 30  3b 20 5b 31 5d 2d 5b 32  |scale=20; [1]-[2|
00000010  5d                                                |]|
00000011

II. Why is the ending sign "0a" shown as a dot "."? The "." is "2E" in Hex.

TODO: Did someone answer this already? Please, comment, answer or edit.

一、为什么 5E 4d 0a,即 ^M,ASCII 中的第 13 个字符?

换行符是0a,请参见下面 ZyX 提供的示例。rjh 澄清了一些关于第 13 个字符的信息。的echo -n防止从在其输出端的末尾添加一个新行回声”。我正在使用 Debian。

$ echo "scale=20; $values[1]-$values[2]" | hexdump -C
00000000  73 63 61 6c 65 3d 32 30  3b 20 5b 31 5d 2d 5b 32  |scale=20; [1]-[2|
00000010  5d 0a                                             |].|
00000012
xyz@xyz:~$ echo -n "scale=20; $values[1]-$values[2]" | hexdump -C
00000000  73 63 61 6c 65 3d 32 30  3b 20 5b 31 5d 2d 5b 32  |scale=20; [1]-[2|
00000010  5d                                                |]|
00000011

二、为什么结尾符号“0a”显示为点“.”?这 ”。” 是十六进制的“2E”。

TODO:有人已经回答了吗?请评论,回答或编辑。

Information to help with the examples

帮助示例的信息

ASCII to HEX

`.` is `2E` in Hex
`5E` is `^` in Hex 
`4d` is `M` in Hex

Hex to ASCII: use this see what the Hex -things mean

$ echo "^M" | hexdump -C
00000000  5e 4d 0a                                          |^M.|
00000003
$ ascii -x              
    0 NUL    10 DLE    20      30 0    40 @    50 P    60 `    70 p 
    1 SOH    11 DC1    21 !    31 1    41 A    51 Q    61 a    71 q 
    2 STX    12 DC2    22 "    32 2    42 B    52 R    62 b    72 r 
    3 ETX    13 DC3    23 #    33 3    43 C    53 S    63 c    73 s 
    4 EOT    14 DC4    24 $    34 4    44 D    54 T    64 d    74 t 
    5 ENQ    15 NAK    25 %    35 5    45 E    55 U    65 e    75 u 
    6 ACK    16 SYN    26 &    36 6    46 F    56 V    66 f    76 v 
    7 BEL    17 ETB    27 '    37 7    47 G    57 W    67 g    77 w 
    8 BS     18 CAN    28 (    38 8    48 H    58 X    68 h    78 x 
    9 HT     19 EM     29 )    39 9    49 I    59 Y    69 i    79 y 
    A LF     1A SUB    2A *    3A :    4A J    5A Z    6A j    7A z 
    B VT     1B ESC    2B +    3B ;    4B K    5B [    6B k    7B { 
    C FF     1C FS     2C ,    3C <    4C L    5C \    6C l    7C | 
    D CR     1D GS     2D -    3D =    4D M    5D ]    6D m    7D } 
    E SO     1E RS     2E .    3E >    4E N    5E ^    6E n    7E ~ 
    F SI     1F US     2F /    3F ?    4F O    5F _    6F o    7F DEL

ASCII 到 HEX

`.` is `2E` in Hex
`5E` is `^` in Hex 
`4d` is `M` in Hex

Hex to ASCII:使用这个看看 Hex 的含义

$ echo "^M" | hexdump -C
00000000  5e 4d 0a                                          |^M.|
00000003
$ ascii -x              
    0 NUL    10 DLE    20      30 0    40 @    50 P    60 `    70 p 
    1 SOH    11 DC1    21 !    31 1    41 A    51 Q    61 a    71 q 
    2 STX    12 DC2    22 "    32 2    42 B    52 R    62 b    72 r 
    3 ETX    13 DC3    23 #    33 3    43 C    53 S    63 c    73 s 
    4 EOT    14 DC4    24 $    34 4    44 D    54 T    64 d    74 t 
    5 ENQ    15 NAK    25 %    35 5    45 E    55 U    65 e    75 u 
    6 ACK    16 SYN    26 &    36 6    46 F    56 V    66 f    76 v 
    7 BEL    17 ETB    27 '    37 7    47 G    57 W    67 g    77 w 
    8 BS     18 CAN    28 (    38 8    48 H    58 X    68 h    78 x 
    9 HT     19 EM     29 )    39 9    49 I    59 Y    69 i    79 y 
    A LF     1A SUB    2A *    3A :    4A J    5A Z    6A j    7A z 
    B VT     1B ESC    2B +    3B ;    4B K    5B [    6B k    7B { 
    C FF     1C FS     2C ,    3C <    4C L    5C \    6C l    7C | 
    D CR     1D GS     2D -    3D =    4D M    5D ]    6D m    7D } 
    E SO     1E RS     2E .    3E >    4E N    5E ^    6E n    7E ~ 
    F SI     1F US     2F /    3F ?    4F O    5F _    6F o    7F DEL

回答by dmix

I fixed this by removing this from ~/.gitconfig

我通过从 ~/.gitconfig

[core]
  autocrlf = true

Which was appending ^Mto my vim-plug plugins automatically for some reason and breaking neovim.

^M由于某种原因,它自动附加到我的 vim-plug 插件并破坏了 Neovim。