简体   繁体   中英

echo backspace switch creates newline

I understand

\n = new line or carriage return
\b = move cursor to the left once (does not delete anything)

When you put those two together in this command:

read -p "$(echo -e 'Enter your age: \n\b')"

That outputs:

Enter your age:
_

With _ being your cursor asking for an input.

My Question : If I remove the \\b switch, the cursor will not be on a newline. Can someone explain to me how this works?

Trailing newlines are removed from $() command substitutions. Quoth the manpage:

Command substitution allows the output of a command to replace the command name. There are two forms:

  $(command) 

or

  `command` 

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. (...)

(Emphasis mine).

A way to achieve the same behavior without \\b is to use bash-specific $'' strings:

read -p $'Enter your age:\n'

Or to just put a newline inside a quoted string:

read -p 'Enter your age:
'

The formatting isn't pretty, but it'll also work.

(Just for information when I run your \\b version my cursor is on the end of the first line not at the start of the second line but that's likely just a terminal difference.)

By way of illustration compare this:

$ printf "$(echo -e 'Enter your age: \n ')_" | xxd
0000000: 456e 7465 7220 796f 7572 2061 6765 3a20  Enter your age:
0000010: 0a20 5f                                  . _

and this:

$ printf "$(echo -e 'Enter your age: \n\b')_" | xxd
0000000: 456e 7465 7220 796f 7572 2061 6765 3a20  Enter your age:
0000010: 0a08 5f                                  .._

To this:

$ printf "$(echo -e 'Enter your age: \n')_" | xxd
0000000: 456e 7465 7220 796f 7572 2061 6765 3a20  Enter your age:
0000010: 5f                                       _

Notice the 0a20 in the first output? That's the newline and space from our pattern.

Notice the 0a08 in the second output? That's the newline and backspace from our pattern.

Now look at the third output. We don't have any character after the newline so we don't see 20 or 08 in that output which makes sense but where did the newline go?

Turns out this is a "feature" of Command Substitution .

Bash performs the expansion by executing command and replacing the command substitution with the standard output of the command, with any trailing newlines deleted.

So by putting \\b after the newline you are protecting it from being deleted by the command substitution.

Wintermute covers the correct workarounds/solutions in his answer (you could also put the string in a variable and expand it in quotes on the read line to get the formatting on that line a little nicer).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM