BASH and Carriage Return Behavior

Your echo "$a" prints "hello", then goes back to the beginning of the line (which is what \r does), print "again", goes back again, prints "george", goes back again, and goes to the next line (\n). It’s all perfectly normal, but as chepner points out, it doesn’t have anything to do with Bash: \r and \n are interpreted by the terminal, not by Bash (which is why you get the full output when you pipe the command to od).

You can see this better with

$ a=$(printf "hellooooo\r  again,\rgeorge\r\n")
$ echo "$a"

since that will leave the end of the overwritten text:

georgen,o

You can’t really use that to hide commands though, only their output (and only if you can be sure to overwrite with enough characters), unless using eval as you show (but using eval is generally not recommended). A more dangerous trick is using CSS to mask commands intended to be copied and pasted from web sites.


In the Unix world, a carriage return (commonly encoded as \r in programming languages) is an unremarkable control character. You can have carriage returns inside a line of text, like any other character apart from a line feed (also called newline), which marks the end of a line.

In particular, in a bash script, a carriage return is an ordinary word constituent character, like letters and digits. Any special effect of the carriage return comes from the terminal, not from the shell.

A carriage return is a control character. When you print it to a terminal, instead of displaying a glyph, the terminal performs some special effect. For a carriage return, the special effect is to move the cursor to the beginning of the current line. Thus, if you print a line that contains a carriage return in the middle, then the effect is that the second half is written over the first half.

Several other control characters have special effects: the backspace character moves the cursor left by one position. The bell character causes the terminal to emit a sound or otherwise attract the user's attention. The escape character starts an escape sequence which can have all kinds of special effects.

If you display untrusted output, you need to scrub or escape control characters. Not only carriage returns, but also several others, in particular the escape character, which can cause all kinds of bad effects. See Can “cat-ing” a file be a potential security risk? and How to avoid escape sequence attacks in terminals? for more on the topic.