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.

  • There's no default on the last question? – Kusalananda Dec 21 '18 at 18:26
  • There is not. Pressing "enter" on the last command will just keep prompting for an answer – Troncoso Dec 21 '18 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 Dec 21 '18 at 20:24
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.

  • Thanks so much for this! You're right, the exp_continue is exactly what I needed. – Troncoso Jan 2 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 :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.