4

Today when I using this command to generate a rsa key in my CentOS 7.x, when I using enter to confirm my command, but the output is ^M, what's happening?

[root@izbp19pke6x0v6ruecuy1yz ~]# ssh-keygen -t rsa -b 4096 -C jiangtingqiang@gmail.com
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^M^C
[root@izbp19pke6x0v6ruecuy1yz ~]# ssh-keygen -t rsa -b 4096 -C jiangtingqiang@gmail.com
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): github-actions^C
[root@izbp19pke6x0v6ruecuy1yz ~]# ssh-keygen -t rsa -b 4096 -C jiangtingqiang@gmail.com
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): ^M^M^M^M^C

why would this happen and what should I do to fix it? This is the tty config:

[root@izbp19pke6x0v6ruecuy1yz ~]# stty -a
speed 38400 baud; rows 37; columns 210; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = M-^?; eol2 = M-^?; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = M-^?; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr -icrnl ixon -ixoff -iuclc ixany imaxbel iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke

I have never encount this problem before. And now I have no clue about this problem. any idea is welcome bro..., by the way, my local OS is Mac OS Catalina, I am using zsh, the terminal tool is iTerm.

Dolphin
  • 207

2 Answers2

10

It's normal for terminals to send CR (^M) upon Enter. They don't have to send LF (^J). In my Debian, Kubuntu, in few other Linux systems Ctrl+v, Enter shows ^M. I would say ^M (not ^J) is the correct (or at least common) character for line ending coming from the terminal.

Some shells accept both ^M and ^J to run the typed command. Bash does, Zsh does.

Apparently ssh-keygen needs ^J and it's OK because it should expect and get ^J. Trivia: when ssh-keygen (or almost anything) runs, the terminal is not in the raw mode and the program gets nothing until ^J comes.

Without changing any settings you can generate ^J "manually" by typing Ctrl+j. If you use this combination instead of Enter while providing input for ssh-keygen then it will work.

In my systems (where Enter sends ^M) ssh-keygen works because the respective terminal driver in each system translates ^M into ^J on the fly. A terminal driver does this when icrnl is set. It's normal to have a terminal that sends ^M upon Enter and a terminal driver that translates it to ^J on its end.

Your terminal apparently sends ^M but in the output of stty -a there is -icrnl which means the terminal driver in question does not translate ^M to ^J.

Either configure your terminal (iterm, PuTTY, konsole or whatever) to send ^J upon Enter, or use

stty icrnl

to make the terminal driver translate ^M into ^J expected by ssh-keygen.

2

Not a solution, but the ^M (Ctrl + M) character is caret notation for the unprintable character Carriage Return (CR) as noted in this Super User question.

Normally, Line Feed (LF) is used as the new line character in Unix based systems like Linux. If I am not misreading your TTY config, it appears CR may be being sent instead of LF. So it seems plausible that the on-screen terminal is printing the caret notation in place of recognizing it as a proper line ending or whatever.

As to "why" this is happening, I believe CR was used in the past on MacOS as the new line character but current versions of MacOS no longer use it (they have switched to LF as I understand it).

Assuming this is the issue, my thought would be to perhaps investigate changing your TTY config to send the "correct" character LF (^J based on this Wikipedia chart) in place of CR.

Anaksunaman
  • 18,227