How to show read prompt with a new line - linux

I'm using read builtin to read a variable, but I'd like to let the input appears on the next line, that is, the prompt output a new line, but neither of the two works:
$ read -p "Please input:\n" name
Please input:\n
$ read -p 'Please input:\n" name
Please input:\n
As you see new line escape sequence is not interpreted even in the double quote case. So is there anyway to do that?

You can separate the prompt from the actual read :
echo "Please input:"
read name
You can put both on a single line :
echo "Please input:" ; read name
You can also use a different form of quoting :
read -p $'Please input\n' name
This is barely shorter, and many would probably find it a bit less readable, but that is a matter of taste.

Related

Give output of one shell script as input to another using named pipes

I'm new to linux and have been coding some beginenr level shell scripts.
What I want to do is write 2 scripts. The first script will read input from user and the 2nd script will display this input in a loop till it detects an "exit" from the user.
This is how I've coded the 2 shell scripts.
File1.sh:
read var1
echo $var1
File2.sh:
while [ "$var2" != "exit" ]
do
echo $1
read var2
done
Now, I want to use a named pipe to pass the output of File1.sh as input to var1 of File2.sh. I probably will have to modify code in File2.sh so that it will accept argument from a named pipe (as in instead of $1 the input will be from the named pipe), but I'm not at all sure how to go about it.
Giving the output of File1.sh as input to the named pipe can be given as follows:
mkfifo pipe
./File1.sh > pipe
This command keeps asking for input until i break out using ctrl + c. I don't know why that is.
Also how do I make the File2.sh read from this pipe?
will this be correct?
pipe|./File2.sh
I'm very new to linux but I've searched quite a lot online and there isn't even one example of doing this in shell script.
As for your original question, the syntax to read from a named pipe (or any other object in the file system) is
./File2.sh <pipe
Also, your script needs to echo "$var2" with the correct variable name, and double quotes to guard the value against wildcard expansion, variable substitution, etc. See also When to wrap quotes around a shell variable?
The code in your own answer has several new problems.
In File1.sh, you are apparently attempting to declare a variable pipe1, but the assignment syntax is wrong: You cannot have whitespace around the equals sign. Because you never use this variable for anything, this is by and large harmless (but will result in pipe1: command not found which is annoying, of course).
In File2.sh, the while loop's syntax is hopelessly screwed; you dropped the read; the echo still lacks quotes around the variable; and you repeatedly reopen the pipe.
while [ "$input" != "exit" ]
do
read -r input
echo "$input"
done <pipe1
Redirecting the entire loop once is going to be significantly more efficient.
Notice also the option -r to prevent read from performing any parsing of the values it reads. (The ugly default behavior is legacy from the olden days, and cannot be fixed without breaking existing scripts, unfortunately.)
First in File1.sh, echo var1 should be echo $var1.
In order to get input from pipe, try:
./File2.sh < pipe
This is how I solved it.
First mistake I made was to declare the pipe outside the programs. What I was expecting was there is a special way in which a program accepts input parameters of the type "pipe". Which as far as I've figured is wrong.
What you need to do is declare the pipe inside the program. So in the read program what you do is,
For File1.sh:
pipe1=/Documents
mkfifo pipe1
cat > pipe1
This will send the read input from the user to the pipe.
Now, when the pipe is open, it will keep accepting input. You can read from the pipe only when its open. So you need to open a 2nd terminal window to run the 2nd program.
For File2.sh:
while("$input" != "exit")
do
read -r input < pipe1
echo "$input"
done
So whenever you input some string in the first terminal window, it will be reflected in the 2nd terminal window until "exit" is detected.

properly using IO redirection to append user input to a file in linux scripting?

I'm just starting to learn linux scripting, and with them user output/inputs. One of the things i need to learn and keep trying to do to no avail is append user input to a file output. Something like
read text > text.dat
or
read text
$text > text.dat
Typically ends up in failure, or the creation of text.dat which ends up empty no matter what is typed in by the user. What am i missing?
The read command, as documented in it's manual file, will take a line of user input and assign it to a variable which you can name as an argument. It will also split the user input and assign it to multiple variables if you pass more than one name. It will do this all in the background without printing any kind of confirmation to the standard out. We also know that the > operator will redirect the standard out of a command to a file descriptor. It is also important to note that unless bash is explicitly told that a line contains multiple commands (by using a semi-colon or similar) it will assume it is all one command with multiple arguments.
So lets have a look at your examples and see what is happening:
read text > text.dat
This will run the read command, which will silently assign the user input to a variable called $text. It will then redirect the output of the command (nothing, as it is silent) to a file called text.dat. End result: an empty text.dat and an unused $text variable.
read text $text > text.dat
Bash will parse this command and first attempt to get the value assigned to the $text variable, at this point it is undefined and so it will be ignored. So it will run the read command, which will silently assign the user input to a variable called $text. It will then redirect the output of the command (nothing, as it is silent) to a file called text.dat. End result: an empty text.dat and an unused $text variable.
So how can we resolve this? The first command is fine, we use read text to allow the user to input a line and have that line assigned to a variable called $text. Then, we need a way to send that variable to standard out so we can redirect it. To do that, we can use the echo command, which we can redirect.
So for example:
read text
echo $text > text.dat
Another thing to note is that the > operator will overwrite the file, to append to it you can use the >> operator.
So to take a user input and append it to a file we have:
read text
echo $text >> text.dat

linux counting characters then output number of characters in a string entered by user and it also needs a while loop

I have been trying to get linux to count the characters in a string and then out put them i want the user to be able to enter a string and the amount of characters in a string to be outputed however i have a limited understanding of linux so i really need your help thank you!
so far i have got this:
#!/bin/bash
x="This is a test"
y="${x//[^s]}"
echo "$y"
echo "${#y}"
but that only does it for one type of character and it's not in a while loop that will allow the user to quit if they wan to if you can help it would be appretiated
an example input would be "i like pie"
i would want the program to output "the string you have entered has 10 characters
You can use read to get input from user and then use ${#var} to get the length:
#!/bin/bash
read -p "Enter some input text: " input
echo "# of chars in input: ${#input}"

While Read Stores Each User Entry without Spaces

I want to ask the user to enter a few lines of text, it can by anything and I want to store it as a variable that I can call later on. I don't want to create multiple read commands, just one that can hold multiple paragraphs if needed.
I tried this:
echo "Enter your your paragraph:"
read -d '' -n 1 message
while read -d '' -n 1 -t 2 c
do
message+=$c
done
echo ""
echo "$message"
the output is always put into one line of text without spaces or anything. It would look like this when I run the code and enter a few lines of code:
Enter your broadcast message (When done, wait 2 seconds):
This is supposed to be a sentence.
And so is this.
Thisissupposedtobeasentence.Andsoisthis.
It should output the two sentences on sperate lines and with spaces included.
Don't use read for this; requiring all typing to be done without any two-second pauses (and conversely, forcing a wait of two seconds to complete the input) is not very user-friendly. Instead, just read input directly from standard input, which for interactive use simply requires an EOF (Control-d) to finish the input.
c=$(</dev/stdin)
read uses the characters in $IFS as word delimiters. Change your read statement to:
IFS= read -r -d '' -n 1 -t 2 c

Underlining User Input

I am intending to underline the user input but after doing research, I still cant find the way to do it.
So far this is what I have got from doing research, but it still doesn't work.
Anyone knows how to solve it? or rather the proper method to do it?
What if I am using read -p "What is your name: " name instead of the one below? As what I am expecting for the output is.
What is your name? (the input from user and is underlined)
function underlineInput()
{
PS1='\033[4;47;40m'
}
function UNunderlineInput()
{
PS1='\033[0;47;40m'
}
function hi()
{
echo "Please enter your name: "
underlineInput
read input
underlineInput
}
Thanks to those who helped in advance!
Cheers!
Check out this link here
But its just:
$ echo -e "\033[4mThis is a underlined line.\033[0m"
The key parts are the \033[4m to underline and \033[0m to change it back.
Put the escape sequence to turn on underlining at the end of the prompt, then send the back-to-normal-sequence afterward:
read -p $'Please enter your name: \033[4m' name
printf '\033[0m' # Use printf instead of echo to avoid newline, and it translates escape without $''
BTW, if you want this script to work on other types of terminal as well, you can use the terminfo database to get the relevant escape (/whatever) sequences. The terminfo capability names for underlining on and off are "smul" and "rmul":
read -p "Please enter your name: $(tput smul)" name
tput rmul

Resources