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.

  • This is most likely a character encoding mismatch issue. Your terminal is sending the ^M as carriage return but CentOS is not interpreting it correctly. Check your macOS terminal app settings and see if anything is amiss. – Giacomo1968 May 10 at 17:52
  • Are you using SSH to connect to the CentOS box, or are you running CentOS in a virtual machine? – chepner May 10 at 18:08
  • I am using ssh to connect CentOS, the cloud CentOS should be KVM virtual machine. My local machine is not virtual machine. @chepner – Dolphin May 11 at 1:34
  • you might get better responses on Unix & Linux – phuclv May 11 at 2:39

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.


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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.