Why '\n'('\r') does not work in my expect script - expect

I want to input y+enter to reply the question while executing copy tftp:something.
The script will send y, but \n does not work. It will stay (y/n)y and keep there without exiting or doing something else. I have tried \r, and the result was the same. Does anyone know the reason?
#!bin/bash
expect -c "
set timeout -1
spawn telnet x.x.x.x
expect \"username\"
send \"user\n\"
expect \"password\"
send \"pw\n\"
expect \"model\"
send \"copy tftp:something\n\"
expect \"(y/n)\"
send \"y\n\"
expect eof
"
exit 0

I prefer using \r to "hit enter".
Second, your entire bash script is expect, so remove the outer bash layer.
#!/usr/bin/expect -f
set timeout -1
spawn telnet x.x.x.x
expect "username"
send "user\r"
expect "password"
send "pw\r"
expect "model"
send "copy tftp:something\r"
expect "(y/n)"
send "y\r"
expect eof
If you have more logic in the bash part, to avoid quoting hell use a heredoc:
#!/bin/bash
expect <<'END_EXPECT'
set timeout -1
spawn telnet x.x.x.x
expect "username"
send "user\r"
expect "password"
send "pw\r"
expect "model"
send "copy tftp:something\r"
expect "(y/n)"
send "y\r"
expect eof
END_EXPECT
exit 0

Related

How to save output expect in bash

I am trying to make a script to save a output of the command show version in cisco.
I need made a connection to one server for that the ssh connection, and then i have connection with the device.
In the file out.txt, I have the output of the first connection, the ssh connection, but i dont know how to save the output of the show version
#!/usr/bin/expect -f
#!/bin/sh
spawn ssh -l user x.x.x.x
expect "login as:"
expect "password:"
send "password\r"
expect "$\r"
send "telnet nemonic\r"
expect "$\r"
expect "login:"
send "user\r"
expect "password:"
send "password\r"
expect "*>"
send "terminal length 0\r"
send "show version \r"
expect "*>"
set results $expect_out(buffer)
set config [open out.txt w]
puts $config $results
close $config
send "exit\r"
expect eof
send "\r"
send "exit\r"
Could you help me?
Best regards
I solve with
log_file -noappend status.txt
after the command show version
Thank you && Best Regards

How to automate the process with expect tool?

I want to automate a process with expect :
1.login with a common user in ssh
2.su to root
3.make diretory /home/test
set user xxxx
set host yyyy
set password1 pass1
set password2 pass2
set timeout 60
spawn ssh $user#$host
expect "*assword:*"
send "$password1\r"
spawn su
expect "*assword:*"
send "$password2\r"
send "mkdir /home/test"
close
How to fix the codes to automate my process?
Basically, expect will work with two feasible commands such as send and expect. In this case, if send is used, then it is mandatory to have expect (in most of the cases) afterwards. (while the vice-versa is not required to be mandatory)
This is because without that we will be missing out what is happening in the spawned process as expect will assume that you simply need to send one string value and not expecting anything else from the session, making the script exits and causing the failure.
Apart from the commands being missed, I see one issue with su command. I hope your intention is to create directory with su command execution in the remote host, not in local. So, assuming that, you just have to send the command as su to the server. Your current code will spawn su in the local machine.
#!/usr/bin/expect
set host xxx.xxx.xxx.xxx
set user dinesh
set loginpwd welcome
set adminpwd root
set timeout 60
set prompt "#|>|\\\$"; # We escaped the `$` symbol with backslash to match literal '$'
spawn ssh $user#$host
expect -nocase "password:"
send "$loginpwd\r"
expect -re $prompt
send "su\r"
expect -nocase "password:"
send "$adminpwd\r"
expect -re $prompt
send "mkdir /home/test\r"
expect -re $prompt
send "logout\r"
expect eof
eof will wait for the closure of the ssh session.

bash script which downloads a file with sftp

I need to make a sftp connection with a password and download a file. There is an ip restriction so first of all i should make a ssh connection. I wrote a script but it stucks after connecting with ssh.
Note: i also tried doing it with an expect script but it also didn't work.
#!/usr/local/bin/
ssh test#test1.t.com
lftp sftp://test2:123456#test2.com
get "file.xls"
Edit: You can also see my expect code here.
#!/usr/local/bin/expect -f
expect -c "
spawn ssh test#test1.t.com
expect \"test\#test1\:\~\$\"
spawn sftp test2#test2.com
expect \"*assword:\"
send \"123456\r\"
expect \"sftp\>\"
send \"get file.xls\r\"
expect \"sftp\>\"
exit 1
";
I'm not sure exactly what you're trying to accomplish here. First, I'll address the problems in your expect script. Since your shebang line invokes expect, you don't need to wrap the expect body in a call to expect. That gets rid of all the backslashes. Next, you have 2 spawn calls, which raises questions about you're intent. I'm going to assume that you want to ssh to test1, then grab the file from test2 so the file exists on test1. This assumption changes the 2nd spawn to a plain send command.
#!/usr/local/bin/expect -f
set shell_prompt "test#test1:~$"
set sftp_prompt "sftp>"
spawn ssh test#test1
expect $shell_prompt
send "sftp test2#test2\r"
expect "*assword:"
send "123456\r"
expect $sftp_prompt
send "get file.xls\r"
expect $sftp_prompt
send "exit\r"
expect $shell_prompt
send "exit\r"
expect eof
Now, you can scp the file to your local machine. Let's put those 2 steps into one shell script:
#!/bin/sh
expect <<'EXPECT_SCRIPT'
set shell_prompt "test#test1:~$"
set sftp_prompt "sftp>"
spawn ssh test#test1
expect $shell_prompt
send "sftp test2#test2\r"
expect "*assword:"
send "123456\r"
expect $sftp_prompt
send "get file.xls\r"
expect $sftp_prompt
send "exit\r"
expect $shell_prompt
send "exit\r"
expect eof
EXPECT_SCRIPT
scp test#test1:file.xls .

Automatic disconnect telnet in bash scripting

When i run the script below, it connects the server but it disconnect before sending a command. How can i solve this problem.
#!/bin/bash
/usr/bin/expect << EOD
spawn telnet 31.168.109.31
sleep 2
expect ">"
sleep 1
send "my_password"
send "\n"
sleep 1
interact
As per your code you expect > before password. I am not getting you what is purpose of it but as for some example script look here. It's might be not an answer but probably help you.
#!/bin/bash
/usr/bin/expect << EOD
set timeout 200
spawn telnet 31.168.109.31
expect "login:"
send "root\r"
expect "password"
send "mypassword\r"
expect "root#"
#rest of your logic what you want.

Pipe stdin into "expect" script

I am uploading a file via ftp using expect. The file is piped into my bash script.
#!/bin/bash
HOST='example.com'
USER='XXX'
PASSWD='XXX'
expect << EOT
spawn ftp $HOST
expect "Name*:"
send "$USER\r"
expect "Password:"
send "$PASSWD\r"
expect "ftp>"
send "binary\r"
expect "ftp>"
send "prompt\r"
expect "ftp>"
send "put - $1\r" ####
expect "ftp>"
send "bye\r"
expect eof
EOT
On the highlighted line I want ftp to get access to the main script stdin.
Thank you
I believe the key to what you are looking for is Expect's interact command. You'd get a script like this:
#!/usr/bin/env expect
# Set these in the Tcl way, not the bash way
set HOST "example.com"
set USER "XXX"
set PASSWD "YYY"
# You should recognize this bit...
spawn ftp $HOST
expect "Name*:"
send "$USER\r"
expect "Password:"
send "$PASSWD\r"
expect "ftp>"
send "binary\r"
expect "ftp>"
send "prompt\r"
expect "ftp>"
# New stuff starts here
send "put - [lindex $argv 0]\r"
interact {
"ftp>" { return }
}
send "bye\r"
wait
exit
I've rewritten your script so it doesn't use a here document, because that would have interfered with the reading of the content (here-docs are presented as stdinā€¦) and switched it to use a few more idiomatic ways of doing things (idiomatic argument access being the main one).
That said, if I was doing this sort of thing for real, I'd look into using the ftp package from Tcllib as that talks the protocol directly instead of using a possibly-problematic subprocess. (Indeed, if you were going to be doing this on Windows, you'd have to do it that way because of quirks of how Expect and FTP.EXE work on that platform).

Resources