2

This is my main script:

#!/bin/bash

read -p "Name: " NAME
read -p "Age: " AGE
read -p "Country: " COUNTRY

echo "Your name is $NAME. You are $AGE years old. You live in $COUNTRY."

Suppose I have a file (data.txt) with the following format:

Charly
32
Spain

If I pipeline in the following way:

cat data.txt | ./main.sh

The result is obviously correct, but it ocurrs immediately.

It is possible to generate a pause between each read statement simulating the time it takes the user to answer?

As if I could send each value one by one through the pipe and pause, say, for 5 seconds, between each sending.

It is possible to display the information read from the file data.txt one by one (Charly, 32, Spain), the entire word for each iteration or character by character for each string (simulating the info is really typing by hand). For example:

I would see on the screen at the start of the process

NAME:

and after five seconds

NAME: Charly

AGE:

and so on.

My script

enter image description here

9
  • I forgot to mention that I can't modify the main script. Commented Oct 15 at 10:05
  • 3
    You can and should edit your question to provide any additional information, don't add it in comments where it can't be formatted and could be missed. Commented Oct 15 at 12:03
  • 2
    please update the question with details on what you are expecting as output when it comes to the 3x prompts and the inputs to said proimpts; your cat data.txt | ./main.sh does not display the prompts ... is that 'ok' or do you also want the prompts displayed? and while we're at it, are you looking for the inputs (Charly, 32, Spain) to be displayed, too (exactly as if being typed in by hand)? Commented Oct 15 at 15:58
  • The issues/objections you have raised seem to suggest that the script you have shown is not your main script. Please confirm and share your actual main script. Commented Oct 16 at 4:31
  • What I don't understand is why if I send the first value (Charly), the main script continues and terminates and doesn't wait for the other two values. That is, it skips the next two read statements. You can try with a echo "Charly" | ./main.sh. Regards. Commented Oct 16 at 7:10

3 Answers 3

4

Sleep between each line:


while IFS='' read -r line; do
    printf '%s\n' "$line"
    sleep 5
done < data.txt | ./main.sh
Sign up to request clarification or add additional context in comments.

4 Comments

for adhoc quick and dirty in terminal I would do cat data.txt | while IFS= read -r l; do echo "$l"; sleep 1; done | ./main.sh
Thank you. It works separately, but when I run the pipeline, the main script doesn't stop, it does not pause. Regards.
What happens when it doesn't stop or pause? Does it print anything?
Yes, it prints the following, the result: Your name is Charly. You are 32 years old. You live in Spain, but it does not prints prompts or answer, therefore it does not pause. And if I send a single line it prints: Your name is Charly. You are years old. You live in .
2

You could use awk to read the file & add a delay between lines:

awk '(NR>1){system("sleep 5")}; {print}' data.txt | ./main.sh

9 Comments

Thanks for your help, but the main script doesn't stop. Regards.
My script receives the first string of text and does not pause or wait for the others, it runs and does not stop.
When I run this piped to the script in your screenshot, it works as I expect: the set -x output has 5-second delays between the second and third read commands, and also between the third read and the final echo. No prompts are printed because input is coming from a pipe rather than the terminal (from the bash man page: "-p prompt Display prompt on standard error, without a trailing newline, before attempting to read any input. The prompt is displayed only if input is coming from a terminal.").
fwiw, when I run this solution it waits for 15 seconds and then displays Your name is Charly. You are 32 years old. You live in Spain. on the console (as expected); fwiw ... bash v5.1.16 and GNU awk v5.1.0
But I don't want to wait before then, that's easy. I want to it waits between replies, between read statements. Regards.
I want to simulate that the "user" is taking their time answering the questions one by one; I don't want to see the result all at once.
Thank you. I appreciate your comments. It is possible to set a variable inside the awk’s system sleep time? For example, system(“sleep $TIME”). I haven’t be able to do it yet.
Do you want to set a variable, or use a variable's value that was set somewhere else (like what this suggests)? If you're just using a variable, you can pass its value to awk with the -v option, like awk -v time="$TIME" '(NR>1){system("sleep " time)}; {print}' data.txt ...
Thank you! That’s what I need. One more observation: what really means NR>1 in this case?
1

You can use sleep to wait.

#!/bin/bash
sleep 2
echo Charly
sleep 1
echo 32
sleep 1.5
echo Spain

And you can run ./answers.sh | ./main.sh. The problem is read -p detect the input is not coming from the keyboard and doesn't display the prompt.

3 Comments

If I use “echo” command my script ends with only the name Charly (first field) and the rest (AGE and COUNTRY) is blank.
It works for me. What version of bash are you using? Are you running it through the pipe as I showed?
My version of Bash is 4.2. I've tried some of your answers and the pause works separately. But when I pipeline to the main script, it does not pause or sleep; the main script runs and does not stop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.