Expect: Some long delay at the shell prompt after ssh login - tcl

Running my expect script
set timeout 15
spawn ssh -t -q -o StrictHostKeychecking=no "$user\#$host"
expect {
-re "closed by remote host" { continue }
-re "(P|p)assword: " { send "$pass\r"; exp_continue }
}
expect -re $prompt
send -- "sudo passwd\r"
...
always waits at the shell prompt for 10+ seconds before sending the "sudo passwd" command, no matter what timeout value I use.
$ (<-- always waits here for 10+ seconds)
Any tip would be much appreciated.
Thanks.

Related

Expect script should not end

I need some help with my script. I have written a piece of code where the script uses ssh to remote host and executes a tail command and need to stay there. It should not come out of the script.
#!/usr/bin/tclsh
package require Expect
set IP [lindex $argv 0]
set spawnID [spawn ssh root#$IP]
expect {
password: {
send "XXXXXXX\r"
exp_continue
}
"# "
}
send "kubectl -it exec server-0 bash\r"
expect "# "
send "tail -f Server.log\r"
expect "$"
The tail -f command should stay but its coming out of the script in few seconds.
Its printing the logs as expected but comes out of the session in 10 seconds.
Requirement is to stay there unless the user hits "ctrl c"

Exit #!/usr/bin/expect when Status was VPN tunnel closed

i am using an expect script
#!/usr/bin/expect -f
set force_conservative 0 ;
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
set timeout -1
spawn $env(SHELL)
match_max 100000
send -- "cd /home/forticlientsslvpn/64bit/\r"
send -- "./forticlientsslvpn --server ip:port --vpnuser UN"
expect -exact "./forticlientsslvpn --server ip:PORT --vpnuser UN"
send -- "\r"
expect -exact "\r
Password for VPN:"
send -- "PW\r"
expect -exact "\r
STATUS::Setting up the tunnel\r
STATUS::Connecting...\r"
send -- "Y\r"
expect eof
file which will connect VPN,
when VPN connection is successful it will display STATUS::Tunnel running,
But when connection closed, STATUS will be Tunnel closed and still the script will keep on running
STATUS::Stopping tunnel
STATUS::Tunnel closed...```
How to exit the script when we get ```STATUS::Tunnel closed```
The problem is that you spawn a shell, and when the vpn client closes, the shell is still running.
Spawn the vpn client directly:
#!/usr/bin/expect -f
set timeout -1
cd /home/forticlientsslvpn/64bit
spawn ./forticlientsslvpn --server ip:port --vpnuser UN
match_max 100000
expect "Password for VPN:"
send -- "PW\r"
expect "STATUS::Connecting..."
send -- "Y\r"
expect eof
By adding expect Stopping and expect closed in the last lines of the script will exit the script.
expect Stopping
expect closed
exit

How to stop tcpdump remotely using expect from a new telnet session

I am trying to stop the tcpdump command from running on a remote terminal. If I telnet to the terminal, start tcpdump, and then send a ^c, tcpdump stops with no issues. However if I telnet to the same terminal, start tcpdump, and then exit the telnet session, when I reconnect to the same telnet session I am unable to stop tcpdump via a ^c. When I do this instead of stopping tcpdump it seems that it just quits the telnet session and tcpdump continues to run on the remote terminal. I provided my script below. Any help is greatly appreciated.
#!/usr/local/bin/expect -f
exp_internal 1
set timeout 30
spawn /bin/bash
expect "] "
send "telnet 192.168.62.133 10006\r"
expect "Escape character is '^]'."
send "\r"
expect "# "
set now [clock format [clock seconds] -format {%d_%b_%Y_%H%M%S}]
set command "tcpdump -vv -i trf400 ip proto 89 -s 65535 -w /tmp/test_term420_${now}.pcp "
send "$command\r"
expect "tcpdump: listening on"
# This works correctly. tcpdump quits and I am returned to the expected prompt
send "\x03"
expect "# "
send "$command\r"
expect "tcpdump: listening on"
# Exit telnet session
send -- "\x1d"
expect "telnet> "
send -- "q\r"
expect "] "
# Reconnect to telnet session
send "telnet 192.168.62.133 10006\r"
expect "Escape character is '^]'."
send "\r"
# This does not work as intended. The ^c quits the telnet session instead of stopping tcpdump
send "\x03"
expect "] "
send "ls\r"
expect "] "
To send a Ctrl+C to a subordinate process with Expect, do this:
send "\x03"
(Ctrl+#=0, Ctrl+A=1, Ctrl+B=2, Ctrl+C=3, etc.)
The correct handling of the Ctrl+C depends on the virtual terminal engine intercepting it and converting a character into a request to send a signal. This only happens when the terminal is in cooked mode. You've probably got the terminal cooked — it's the default after all — but if this doesn't work, that's the first thing to check.
It sounds to me that the tcpdump process has fallen to the background after the first telnet session disconnected.
Maybe what you need to do when you connect over your second telnet session is find the process id using ps and then signal it via the kill command?
Or better yet, launch it in the background in the first place ("&" at the end):
tcpdump -vv -i trf400 ip proto 89 -s 65535 -w /tmp/test_term420_${now}.pcp &
and the shell will give you the pid of the tcpdump process before it returns the prompt... you can read it via expect -re and later on when you re-connect, issue a kill -HUP <pid> (or -INT or whatever).
You should get something like the following (using sleep 5 as command, just as an example):
$ sleep 5 &
[1] 29344
$
Just my 2c.

how to copy a file from remotehost to localhost by using tcl-expect

Here i am making a connection b/w two machines using telnet and in the remote host i am creating a file named "file.txt" and storing the result of the "ls" command execution in the file.txt. now i need to send the file to the local host. i dont know how to do it. anybody who knows it kindly help me out here.
#!/usr/local/bin/expect
spawn telnet <machine ip>
expect "login:"
send "<username>\n"
expect "Password:"
send "<password>\n"
expect "bash"
send " ls > file.txt\r "
expect "bash"
send " cat file.txt \r "
expect "bash"
send " command for copying file to the localhost computer\r"
expect "bash"
send "exit\r"
You're strongly recommended to use ssh and scp for this task.
#!/usr/local/bin/expect
### Factor these out
set user <username>
set pass <password>
set host <machineIP>
### Get the file list into a file remotely
spawn ssh $user#$host sh -c {ls -1 >file.txt}
expect {
"Password:" {
send "$pass\r"
exp_continue
}
eof {
close
}
}
### Copy the file to the local machine
spawn scp $user#${host}:file.txt .
expect {
"Password:" {
send "$pass\r"
exp_continue
}
eof {
close
}
}

Expect Tcl script - Error passing quoted argument using spawn

I just wrote a very simple Expect script for wrapping around rsync, but it seems to be giving me trouble. Basically, I am automating the SSH login prompt called from rsync. I also have to pass arguments through rsync to SSH so it doesn't do the host key checking. I am well aware of SSH authentication keys and ssh-keygen, but I have good reasons for doing things this way so no lectures on passing passwords on the command-line.
Script
#!/usr/local/bin/expect -f
if {$argc != 5} {
puts "usage: remoteCopy {remotehost, username, password, localfile, remoteloc}"
exit 1
}
set remotehost [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set localfile [lindex $argv 3]
set remoteloc [lindex $argv 4]
set timeout -1
spawn rsync -e \"ssh -q -o StrictHostKeyChecking=no\" $localfile $username#$remotehost:$remoteloc
expect "Password"; send "$password\r"
Here is the complete output from the script:
Output
avoelker#localhost $ ./remoteFileCopy.tcl remotehost remoteuser remotepass ~/localfile /tmp/
spawn rsync -e "ssh -q -o StrictHostKeyChecking=no" /localhost/home/avoelker/localfile remoteuser#remotehost:/tmp/
rsync: Failed to exec "ssh: No such file or directory (2)
rsync error: error in IPC code (code 14) at pipe.c(83)
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(434)
send: spawn id exp6 not open
while executing
"send "$password\r""
(file "./remoteFileCopy.tcl" line 17)
avoelker#localhost $
It appears to me that rsync is trying to execute "ssh instead of just ssh, however, copying and pasting the first line of output from Expect's stdout (rsync -e "ssh -q -o StrictHostKeyChecking=no" /localhost/home/avoelker/localfile remoteuser#remotehost:/tmp/) directly into the shell works perfectly fine, so I know it isn't a problem with rsync.
When I remove the -e argument entirely from the spawn rsync line, the Expect script executes without errors, but I would have to add in host key checking to the script, which I do not want to do.
Does someone more experienced with Expect/Tcl know what I am doing wrong?
Drop your backslashes. The spawn line should just say:
spawn rsync -e "ssh -q -o StrictHostKeyChecking=no" $localfile $username#$remotehost:$remoteloc
After all, you don't want rsync to see a command with a quote in it, do you?