efitz
efitz

Reputation: 71

How can I automate a bash script that is 'read'-ing from /dev/tty?

I have a script (that I cannot modify) that I must run regularly that has the following construct:

read -r response < /dev/tty
if [ "$response" = 'y' ]; then
...

I want to wrap this script such that I always send a "y" character to it. I've tried running the script with the standard tricks for sending a yes:

echo y | '/bin/bash /path/to/script'

and

yes | ./myscript

and

printf "y\n" | ./myscript

and

/bin/bash /path/to/script < /path/to/y-file

None of these work. I also tried expect.

It's not clear if Mac OS X's built-in expect is working; with expect diagnostic information enabled, expect is properly detecting to the prompt and responding, but the script then terminates.

#!/bin/bash
set timeout -1
SCRIPT="~/myscript"

expect -d <<EOF
spawn $SCRIPT
expect "prompt string"
send "y\r"
EOF

Also, to clarify, this is on Mac OS X Monterey.

I'd appreciate any help. Again, I cannot modify the original script.

Upvotes: 6

Views: 3221

Answers (2)

phranz
phranz

Reputation: 69

You could try to use autoexpect to generate the wrapper (autoscript) script for you:

autoexpect -f autoscript ./myscript.sh

Upvotes: 0

ceving
ceving

Reputation: 23863

You can use socat to fake a new pseudo terminal for a child process.

Let tty.sh be the following script:

#! /bin/bash

read -r response < /dev/tty
if [ "$response" = 'y' ]; then
  echo yes
else
  echo no
fi

Then you can connect stdin to the new pty of the child process this way:

echo y | socat stdio exec:./tty.sh,pty,setsid,echo=0

Upvotes: 4

Related Questions