Reputation: 41
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?
Upvotes: 4
Views: 462
Reputation: 80921
(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).
Upvotes: 1
Reputation: 44023
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.
Upvotes: 5