Common Sense
Common Sense

Reputation: 85

Redirect to a script that uses /dev/tty

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

Answers (2)

Philippe
Philippe

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

hek2mgl
hek2mgl

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

Related Questions