Reputation: 85
I am writing a git hook that might require human input. According to this answer one has to use exec < /dev/tty
in that script. This does the job, but now there is no possibility to redirect the standard output to that hook (for test purposes). I guess the problem can be narrowed down to a question: how to send a message to /dev/tty
in such a way that another process will read it? Not sure if this is even possible.
Here is the minimum reproducible example:
# file: target.sh
exec < /dev/tty # we want to use /dev/tty
read -p "Type a message: " message
echo "The message ${message}"
I tried several solutions like this:
echo -e "foo\n"| tee /dev/tty | source target.sh
And it actually prints the message in the console after the read
prompt, but the message
variable remains unset. Is there any way to fix it?
Upvotes: 4
Views: 2135
Reputation: 26442
You can use expect
to achieve the result:
#!/bin/bash
expect << EOF
spawn bash target.sh
expect {
"Type a message: " {send "foo\r"; interact}
}
EOF
Upvotes: 2
Reputation: 157957
You could make the input file an optional parameter:
#!/bin/bash
input_file=${1:-/dev/tty}
read -p "Type a message: " message < "${input_file}"
echo "The message ${message}"
# other stuff ...
Now test the command like this:
your_script
your_script <(echo foo)
some_cmd | your_script
some_cmd | your_script <(echo foo)
PS: The syntax <(echo foo)
which I'm using is a so called process substitution.
Upvotes: 2