one-liner
one-liner

Reputation: 799

Expect: exit/finish/close interact on returned output

I need to use expect in order to navigate a program menu and then allow user input. After the user finishes the input, I need to tell expect to take away user control if a specific string is returned by that program.

expect -c '
[login etc, navigate to the desired option]
expect "[string]"; interact
[user input] -> until here everything works

expect "[specific string returned by the PROGRAM, NOT user input]"
[take away control from the user / exit interact if the above specific string is returned] -> this doesn't work

expect "string"; send "[exit command]\r"' -> what should happen after

Also, I need to trap all possible signals because if one of them is used, the user can end up at shell cli with root access.

I've been trying to find an answer on this for hours but my attempts on producing a valid syntax within expect ended up in frustration as the documentation did not help me at all in this direction.

Upvotes: 0

Views: 1999

Answers (1)

glenn jackman
glenn jackman

Reputation: 247082

Here's an example for you. Expect will be controlling this shell script:

#!/bin/sh
PS3="your choice? "
select answer in foo bar baz quit; do
    case $answer in
        quit) echo "bye bye"; break;;
        *) echo "you chose $answer";;
    esac
done
echo "out of select loop: hit enter..."
read x
echo "exiting ..."

The expect program is:

#!/usr/bin/env expect

spawn sh test.sh

set keyword "out of select loop"

# signal handlers: ignore these (can't trap SIGKILL)
trap SIG_IGN {HUP INT TERM QUIT}

# interact until a certain pattern is seen
# in the output (-o) of the process
interact {
    \003 {
        # prevent the user sending SIGINT to the spawned process
        puts "don't press Ctrl-C again"
    }
    -o $keyword {
        send_user "you quit\n"
        send_user $keyword
        return                  # "return" exits the interact command
    }
}

# do other stuff here, for example, hit enter to allow the 
# shell script to terminate
expect -re {\.\.\.\s*$}
send_user "... hitting enter ...\n"
send -- \r
expect eof

The expect man page is rough going. You'll be much happier with the Exploring Expect book.

Upvotes: 1

Related Questions