1

I understand these 3 options for automating an interactive script:

  • Pipe answers to executable eg. yes '\n\n\n\n\nY\n' | ./script
  • yes command to pass the same reply to all questions
  • expect to provide explicit answers

What I'm struggling over is this scenario:

I have a script that will ask a bunch of questions. The number of questions can actually vary depending on the version of the script. The final question is a Y/N confirmation for all previous answers.

Every question has you select from a list. Each question also has a default answer except the last one. So, you simply press "Enter" to accept the default.

What I'd like to happen:

When running the script, accept the default value for all questions and select "Y" for the final question.

Why I can't (I don't think) use the above options:

  • Piping - The number of questions vary depending on the script version
  • yes command - This can't account for the last question, which is a Y/N
  • expect command - The number of questions vary. I do not know if expect can handle this

So here is a small sample:

Installation Choice for Product A
********************************************************

0. Do not install Product A
1. Install Product A Version - 1.0.1.7
2. Install Product A Version - 1.1.4.8

ANSWER [0]: *Press Enter*

Installation Choice for Product B
********************************************************

0. Do not install Product B
1. Install Product B Version - 10.0.1.4239.03
2. Install Product B Version - 10.0.1.4239.04

ANSWER [2]: *Press Enter*

The package versions below have been selected for installation?

Product A   Do not install                 
Product B   10.0.1.4239.04

Cancel=N, Download and Install=Y [Y/N] *Type 'Y' and press Enter*

You'll notice that each question has a different default answer, so I don't even know what the correct one should be besides using the "default".

Final caveat: I can't edit the script that I am trying to run.

3
  • There's no default on the last question?
    – Kusalananda
    Commented Dec 21, 2018 at 18:26
  • There is not. Pressing "enter" on the last command will just keep prompting for an answer
    – Troncoso
    Commented Dec 21, 2018 at 18:31
  • I have gotten expect working with a static number of questions. But as I mentioned in my questions, I don't know how many there will be, so I need to loop over the questions and provide the default answer until I reach the last question.
    – Troncoso
    Commented Dec 21, 2018 at 20:24

2 Answers 2

3

Here's your expect script:

#!/usr/bin/expect
exp_internal 1 ; # remove this when you're done testing.

spawn /path/to/your/program

set timeout -1
expect {
    -re {ANSWER \[\d+\]: $} {
        send "\r"
        exp_continue
    }
    {Cancel=N, Download and Install=Y} {
        send "Y\r"
    }
}
expect eof

The secret ingredient is exp_continue which essentially "loops" back to the top of the expect command so it can match one of the given patterns again.

1
  • Thanks so much for this! You're right, the exp_continue is exactly what I needed.
    – Troncoso
    Commented Jan 2, 2019 at 20:29
0

I understand these 3 options for automating an interactive script:

  • expect to provide explicit answers
    • The number of questions vary. I do not know if expect can handle this

I rebuilt the expect solution by @glennjackman and made it work with an example of mine. This is a nice solution, but a bit complicated.

  • Pipe answers to executable eg. yes '\n\n\n\n\nY\n' | ./script

    • The number of questions vary depending on the script version

Piping can actually work. The Yes/No question will be repeated until there is a good answer, so if you supply enough newlines the Y will be found and there will be a happy end. You have to estimate the max number of selecting questions (with some margin). This is a simple and quick solution with a script to make it convenient to test various max numbers.

#!/bin/bash

if [ $# -eq 1 ]
then
 maxq="$1"
else
 echo "Enters default answers to the program 'trfix' and finishes with 'Y' (yes)"
 echo "Usage:   $0 <expected max number of questions>"
 echo "Example: $0 15"
 exit
fi

str="Y\n"
for ((i=0;i<"maxq";i++))
do
 str="\n$str"
done
#echo -en "$str"
echo -en "$str"|./trfix

Demo run with 2 selecting questions and the maxq set to 5:

$ ./check4Troncoso 5
Installation Choice for Product A
********************************************************

0. Do not install Product A
1. Install Product A Version - 1.0.1.7
2. Install Product A Version - 1.1.4.8

ANSWER [0]: *Press Enter*

Installation Choice for Product B
********************************************************

0. Do not install Product B
1. Install Product B Version - 10.0.1.4239.03
2. Install Product B Version - 10.0.1.4239.04

ANSWER [2]: *Press Enter*


The package versions below have been selected for installation?

Product A   Do not install                 
Product B   10.0.1.4239.04

Cancel=N, Download and Install=Y [Y/N] *Type "Y" and press Enter*"?
Cancel=N, Download and Install=Y [Y/N] *Type "Y" and press Enter*"?
Cancel=N, Download and Install=Y [Y/N] *Type "Y" and press Enter*"?
Cancel=N, Download and Install=Y [Y/N] *Type "Y" and press Enter*"?
Yes :-)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .