How to break a long string into multiple lines in the prompt of read -p within the source code?
Solution 1
First of all, let's decouple the read from the text line by using a variable:
text="line-1 line-2" ### Just an example.
read -p "$text" REPLY
In this way the problem becomes: How to assign two lines to a variable.
Of course, a first attempt to do that, is:
a="line-1 \
line-2"
Written as that, the var a
actually gets the value line-1 line-2
.
But you do not like the lack of indentation that this creates, well, then we may try to read the lines into the var from a here-doc (be aware that the indented lines inside the here-doc need a tab, not spaces, to work correctly):
a="$(cat <<-_set_a_variable_
line-1
line-2
_set_a_variable_
)"
echo "test1 <$a>"
But that would fail as actually two lines are written to $a
.
A workaround to get only one line might be:
a="$( echo $(cat <<-_set_a_variable_
line 1
line 2
_set_a_variable_
) )"
echo "test2 <$a>"
That is close, but creates other additional issues.
Correct solution.
All the attempts above will just make this problem more complex that it needs to be.
A very basic and simple approach is:
a="line-1"
a="$a line-2"
read -p "$a" REPLY
The code for your specific example is (for any shell whose read
supports -p
):
#!/bin/dash
a="goat can try change directory if cd fails to do so."
a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
read -p "$a" REPLY
For all the other shells, use:
#!/bin/dash
a="goat can try change directory if cd fails to do so."
a="$a Would you like to add this feature? [Y|n] "
# absolute freedom to indent as you see fit.
printf '%s' "$a"; read REPLY
Solution 2
I find @BinaryZebra's approach using a variable to be cleaner, but you can also do it the way you were attempting. You just need to keep the line breaks inside the quotes:
read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
Solution 3
The backslash at the end of the lines is allowing the continuation of the command over multiple lines, not actual line breaks in the output.
So your first approach, for example, becomes the command
read -p "goat can try change directory if cd fails to do so. " "Would you like to add this feature? [Y|n] " REPLY
I'm not sure why you want read to output multiple lines, but I would simply use read
for the prompt line and echo
the preceding line(s).
To make the code more readable over multiple lines, don't close/open your quotes between lines.
Try this:
read -p "goat can try change directory if cd fails to do so. \
Would you like to add this feature? [Y|n] " REPLY
Related videos on Youtube
![Mateusz Piotrowski](https://i.stack.imgur.com/lIYBa.png?s=256&g=1)
Mateusz Piotrowski
Updated on September 18, 2022Comments
-
Mateusz Piotrowski almost 2 years
I am writing an installation script that will be run as
/bin/sh
.There is a line prompting for a file:
read -p "goat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n] " REPLY
I would like to break this long line into many lines so that none of them exceed 80 characters. I'm talking about the lines within the source code of the script; not about the lines that are to be actually printed on the screen when the script is executed!
What I've tried:
Frist approach:
read -p "oat may try to change directory if cd fails to do so. " \ "Would you like to add this feature? [Y|n] " REPLY
This doesn't work since it doesn't print
Would you like to add this feature? [Y|n]
.Second approach:
echo "oat may try to change directory if cd fails to do so. " \ "Would you like to add this feature? [Y|n] " read REPLY
Doesn't work as well. It prints a newline after the prompt. Adding
-n
option toecho
doesn't help: it just prints:-n goat oat may try to change directory if cd fails to do so. Would you like to add this feature? [Y|n] # empty line here
My current workaround is
printf '%s %s ' \ "oat may try to change directory if cd fails to do so." \ "Would you like to add this feature? [Y|n] " read REPLY
and I wonder if there is a better way.
Remember that I am looking for a
/bin/sh
compatible solution. -
Mateusz Piotrowski over 8 yearsDo you think that adding newlines after every line would increase the readability? Because I wasn't looking for the way to insert
\n
into my prompt. I just wanted to break the code into multiple lines so that every line is at most 80 characters long. -
Mateusz Piotrowski over 8 yearsI don't want it to print two lines! I just want the code to fit in 80 characters per line in the source code of the script! Thank you for the answer though :)
-
terdon over 8 years@MateuszPiotrowski oh, that makes a lot more sense. Then my answer isn't very useful. Please edit your question and clarify that you want to split the code and not the output. I'm on mobile now but I'll see if I can come up with something tomorrow.
-
Mateusz Piotrowski about 8 yearsI don't like the approach you suggested because there is no indentation. If my
read
is indented within a function then your approach seems to mess the readability. -
terdon about 8 years@MateuszPiotrowski done, I added a working version of what you were originally trying.
-
terdon about 8 years@BinaryZebra I know. I just corrected the "for any shell" since not all shells have read and not all those that do have -p.
-
Admin about 8 years@terdon We are both in agreement That's the reason for the thanks :-). Thanks again.
-
Mateusz Piotrowski over 5 yearsHow do you indent it?