How to end Expect script?

Hi,
I'm not sure how to properly end an Expect script that will eventually be called by a cronjob. Right now, I'm running it from the command line. The gist of it:

spawn $env(SHELL)

### SSH to remote server

### perform operation

### logout

### now at parent shell, do a SCP

### SCP done, now need to exit
expect eof

However, it never really exits when I'm testing this. I see the prompt back after the scp, but it is still expecting the next input (i.e. any command I type just sits there until I do a ctrl-c). If I do "interact", then I'm able to regain shell back.

Eventually this will be called by a cronjob and I don't want multiple dead shells sitting out there. Will this be the case?

Appreciate any pointers.

what is your full code?

Perhaps I wasn't clear in my original post. The script is working, but I'm not sure how to properly exit from Expect when invoking manually from a term vs calling it from a cron job.

Here's a little bit more of the code.

#!/usr/bin/expect -f

set timeout -1

##
## START OF SCRIPT
##
spawn $env(SHELL)

### SSH to remote server
send -- "ssh root@myserver\r"
... (code removed) ...

### perform operation
... (code removed) ...

### logout
send -- "logout\r"
... (code removed) ...

### now at parent shell, do a SCP
send -- "scp root@myserver:/path/to/file/somefile.tar .\r"
expect -exact "root@myserver's password"
send -- "mypassword\r"
expect -regexp {..*}

### SCP done, now need to exit
expect eof

It is the last line I'm not sure what I need to send. I've tried the following in one form or another based on other threads. If I'm running manually, it appears, I just need to supply interact. If I'm calling this from a cron job eventually, I just want to make sure Expect exits properly and I do not have zombie shells. Thanks.

#send -- "^C\r"
#expect eof
#interact
#catch wait result
#exit 0

you're spawning an instance of a shell.. you need to exit the shell or spawn scp instead of shell.

How do I end the shell? Send the ^D char? I recall trying this but when testing from the term, I still do not get control back after the script ends.

Can you provide an example of how to properly exit assuming I spawn? Thanks.

Not 100% clear on the expect syntax for it, but if you can close the file handle you write shell commands into, the shell will get EOF and quit.

As trey85stang said, you need to send exit to the shell or directly spawn ssh (I would choose the second one ...).

I tried the following:

#!/usr/bin/expect -f

set timeout -1

##
## START OF SCRIPT
##

### SSH to remote server
spawn ssh root@myserver
expect "*?assword:*"
... (code removed) ...

### perform operation
... (code removed) ...

### logout
send -- "logout\r"
... (code removed) ...

### now at parent shell, do a SCP
spawn scp root@myserver:/path/to/file/somefile.tar .
expect "*?password"
... (code removed) ...


### SCP done, now need to exit
expect eof

A few questions. I'm new to Expect. When I ran the script w/o the second spawn on scp, it gave me this error:

send: spawn id exp5 not open
    while executing
"exp_send -s -- $arg"
    (procedure "send" line 3)
    invoked from within
"send -- "mypassword\r""
    (file "./geturtserv.exp" line 123)

So, I added spawn in front of it. How should I do it instead?

Now, with this script, at the command prompt, whatever I type doesn't appear. For example, I type "ls" but it doesn't show. However if I hit enter, it runs "ls". To get out of it, I have to do ctrl-d.

Now that I'm using spawn, how should I properly end the Expect script? Thanks.

send -- "logout\r"

Why \r? why not \n? If you're talking to a UNIX shell it expects \n

The main part of the script (ssh, logout, scp etc.) came from using autoexpect. The actual operations after ssh etc. are what I wrote.

I believe \r is correct from what I have read. Also autoexpect recorded \r as well.

The "logout\r" portion works. scp works as well as I go get the tar file from the remote server. It is only after that, I'm not sure how to properly end/exit from running the script manually vs calling it from a cron job.

the suggestion's been made in this thread many times. Send one more thing to the shell, 'exit'.

Sorry, I'm not understanding it.

The advice was to either send "exit" OR directly spawn ssh and the advice was to take the second route. So, I'm using spawn instead, but I'm still not getting my prompt back.

This code works for me:

#!/usr/bin/expect --

set timeout -1
set password "a_password"

### SSH to remote server
spawn ssh root@localhost
expect "*assword:*"
send "$password\r"

### logout
send  "logout\r"

### now at parent shell, do a SCP
spawn scp root@localhost:/home/dd/.histfile /tmp
expect "*assword:*"
send "$password\r"


### SCP done, now need to exit
expect eof

Please try to run the script with:

expect -d ./script_name

... and post the output.

Thanks for the suggestion. I tried it again and it works (exits). I executed it previously using ./myscript.exp but I tried it again and it worked as well. I'm not entirely sure what happened before. Most likely operator error :frowning:

Thanks again all for your help.