bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Interactive Expect from bash Script


From: Bob Proulx
Subject: Re: Interactive Expect from bash Script
Date: Sat, 29 Mar 2014 15:28:45 -0600
User-agent: Mutt/1.5.23 (2014-03-12)

Esben Stien wrote:
> If I run this, it works: 
> 
> #!/usr/bin/expect

Sounds good.  Is there anything particular bad about running it as an
expect script?  (Or in native python using pexepect?  Or in native perl
using Perl's expect library?  Or Ruby's?)

> Andreas Schwab writes:
> > Since you are passing the expect script on stdin the interact command
> > will immediately read EOF, and expect will run into its implicit
> > timeout.
> 
> Hmm, I see, so how am I supposed to run it?;)

Personally I would use "#!/use/bin/env expect" and be done with it.
But if you really want to call it then the first easy way is to create
a script that does the expect portion just by itself.  This is very
common such as often seen with 'sed' scripts called like:

  #!/bin/sh
  sed -f sedscript infile > outfile

But if you want the expect script to be contained within the shell
script then you need to write it out from the shell script first.
Then clean up the script.  Which means things get more complicated due
to the need for trap handling and temporary file cleanup.  Which is
why the use of expect directly seems best to me.

But if you really want to know then the following should do it.  Note
that I didn't test it.  There may be some detail still broken.

Note that with #!/bin/bash using trap on EXIT is sufficient.  To use
this with a #!/bin/sh script one must also trap properly on every
other signal that might happen, usually HUP, INT, QUIT, TERM, and
perhaps PIPE though PIPE is definitely subtle and special.  It is
rather of a mess.  Bash is definitely better in this regard.

Bob

#!/bin/bash

unset tmpfile
cleanup() {
  test -n "$tmpfile" && rm -f "$tmpfile"
}
trap "cleanup" EXIT

tmpfile=$(mktemp) || exit 1

cat >"$tmpfile" <<'EOF'
set passwd $env(_passwd)
set usr $env(_usr)
set host $env(_host)

spawn /usr/bin/ssh $usr@$host
expect {
    -re ".*Are.*.*yes.*no.*" {
        send "yes\n"
        exp_continue
        #look for the password prompt
    }

    "*?assword:*" {
        send $passwd
        send "\n"
        interact
        #The expect command will now return
    }
}
EOF

env _passwd=foo _usr=foo _host=foo expect "$tmpfile"



reply via email to

[Prev in Thread] Current Thread [Next in Thread]