Bash script - second login after logging in with SSH - bash

After you succesfuly SSH into IP Cisco phone, another login prompt (snoopyplus login:) and after that Password:appears.
I want to create a script that spawns ssh, connects to the device, logs in again in the second login prompt and then does something. So far I tried something like that:
$!/usr/bin/expect -f
spawn ssh user#ip
expect "assword:"
send "pw"
expect "snoopyplus login:"
send "user2"
expect "Password:"
send "pw2"
Script connects with SSH and ends up on the snoopyplus login:I tried to expect different words (login, ogin, snoopy..) instead of the "snoopyplus login" but it never worked. I tested it with sshpass but it ends up in the same place.
I don't want to use SSH key and I don't mind having password visible.
Is there a way to do it?
Thank you

I would put a sleep interval after you send password the first time, this will allow expect to have time. Most of my expect use is in python with pexpect using sendline which appends a carriage return, it looks like you would need to add this manually in Tcl. Also with my experience between multiple different mfgs and OS's, expecting the end of your prompt ('>', "#", "%", ":") mitigates some issues.

Related

including conditional statements in expect

I am trying to write a bash script that uses expect to scp a file to remote systems. The expect block that I have so far looks like this
expect -c "
set timeout -1
spawn scp $file user#host:$file
expect "\Are you sure you want to continue connection (yes/no)\"
send -- \"$password\r\"
expect eof
"
The problem is that this handles the case in which the host is not a known host and it asks if I want to continue connecting. I would like to add a an option for the case in which the host is already known and it simply wants the password.
The other issue is that I would like to handle the event in which the password the user entered is not correct. In that case, I would like to have the user reenter the password.
What would be the best way of accomplishing this using bash and expect?
Many thanks in advance!
host is not a known host and it asks if I want to continue connecting
Use: scp -o "StrictHostKeyChecking no" <...>
event in which the password the user entered is not correct
If your script is considered to be interactive, why you are using expect at all? scp can ask and re-ask a password by itself.
Like this:
expect -c "
set timeout -1
spawn scp $file user#host:$file
expect
{Are you sure you want to continue connection (yes/no)} {
send \"yes\r\"
exp_continue
}
{Password: } {
send -- \"$password\r\"
}
}
expect eof
"
The exp_continue command loops back to the containing expect command so that other patterns have a change to be matched.

Handle multiple statements in an Expect script

I am new to Expect scripting.
I wrote an Expect script for ssh in a Linux machine, where I am facing a problem in ssh'ing to different Linux machines. Below I have copied the script.
!/usr/local/bin/expect
set LinuxMachine [lindex $argv 0]
spawn ssh root#$LinuxMachine
expect "root#$LinuxMachine's password:"
send "root123\n"
expect "[root#Client_FC12_172_85 ~]#"
send "ls"
interact
When I supply 10.213.172.85 from command line the expect in the 4th line, it reads as "root#10.213.172.85's password:" and logs in successfully
But some Linux will expect
The authenticity of host '10.213.172.108 (10.213.172.108)' can't be established.
RSA key fingerprint is da:d0:a0:e1:d8:7a:23:8b:c7:d8:40:8c:b2:b2:9b:95.
Are you sure you want to continue connecting (yes/no)
In this case the script will not work.
How can I have two Expect statements in one Expect command?
You can use exp_continue in such a case:
expect {
"Are you sure you want to continue connecting (yes/no)" {
send "yes\r"
exp_continue
}
"root#$LinuxMachine's password:" {
send "root123\r"
expect "[root#Client_FC12_172_85 ~]#"
send "ls\r"
interact
}
}
In the above, the Expect block waits for either the yes/no question OR the prompt for password. If the latter, it moves on with providing password, expecting prompt, sending ls command and giving control back.
If the former, it will answer 'yes' and repeat the expect block, ready to find the prompt for a password (or even the yes/no question again, for that matter - not that you will need that).
I would also include some timeouts with meaningful messages in case some expect option does not match as expected, but the above should work.
As a side comment, you don't want to set a root password in a script... I recommend using ssh key authentication.
We like to call it "long log in". There are ssh options that don't check the host keys:
send -- "ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no username#host\n"
expect {
"Password" {
send -- "$passwd\n"
}
Part of the Bash script that calls on the expect sets the password:
echo -n "Enter LDAP password: "
read -s passwd
echo

BASH scripting for username/password constructs

I want to write a simple bash script using ncat to open a connection to a ISP and its port.
The first command would be:
nc address port
Upon doing this, I am prompted first to provide a username. I must hit ENTER, and then I will be prompted to provide a password and then I must hit ENTER again.
After this, I want to open a Terminal process window. Can anyone point me to sufficient resources for this type of scripting?
I know the username and password already, but I'm not too sure how to work around the fact that I must provide it and then hit enter. I'm also unsure how to open a new Terminal proceses.
Thanks in advance!
Check out expect script
Expect
Example:
# Assume $remote_server, $my_user_id, $my_password, and $my_command were read in earlier
# in the script.
# Open a telnet session to a remote server, and wait for a username prompt.
spawn telnet $remote_server
expect "username:"
# Send the username, and then wait for a password prompt.
send "$my_user_id\r"
expect "password:"
# Send the password, and then wait for a shell prompt.
send "$my_password\r"
expect "%"
# Send the prebuilt command, and then wait for another shell prompt.
send "$my_command\r"
expect "%"
# Capture the results of the command into a variable. This can be displayed, or written to disk.
set results $expect_out(buffer)
# Exit the telnet session, and wait for a special end-of-file character.
send "exit\r"
expect eof
The secret lies in the HEREDOC
You can solve this problem with something akin to:
$ command-that-needs-input <<EOF
authenticate here
issue a command
issue another command
EOF
Look at the link I provided for here documents - it includes support for variable substitution and lots of other useful things. Enjoy!

Writing strings to standard input in bash script

I'm trying to automate a startup of a specific service with bash
When the service is started with init.d (/etc/init.d/openvpn.custom) it is promting for username and then password - and then it connects
The auth-user-pass from-file is not possible with the installed version, and it cannot be upgraded because of dependencies
So i'm trying to write a simple bash scripts that executes the init.d script, sleeps for a bit, inputs the username, returns, sleeping a bit, inputting the password - you'll get the flow.
like http://pastebin.com/qWHX7Di5
I've experimented with echo, but it doesent seem to work
This is for a rather legacy firewall i'm asked to keep connected.
Is this even possible?
I would use expect instead of bash. You can still call it from within bash if you need to do other tasks as well.
In expect, the script would be something like the following (untested):
#!/usr/bin/expect -f
set username "username"
set password "password"
spawn /etc/init.d/openvpn.custom start
expect "Username:"
send "$username\r"
expect "Password:"
send "$password\r"
expect eof
You'd want to change the expect "Username:" & expect "Password:" lines to match the actual login prompts that are output by your init.d script.
See the expect man page for further details.
You can try using a here-doc:
/path/to/init.d << END
$username
$password
END

SSH login with expect(1). How to exit expect and remain in SSH? [duplicate]

This question already has answers here:
Using expect to pass a password to ssh
(6 answers)
Closed 5 years ago.
So I wanted to automate my SSH logins. The host I'm with doesn't allow key authentication on this server, so I had to be more inventive.
I don't know much about shell scripting, but some research showed me the command 'expect' and some scripts using it for exactly this purpose. I set up a script and ran it, it worked perfectly to login.
#!/usr/bin/env expect -f
set password "my_password"
match_max 1000
spawn ssh -p 2222 "my_username"#11.22.11.22
expect "*?assword:*"
send -- "$password\r"
send -- "\r"
expect eof
Initially, it runs as it should.
Last login: Wed May 12 21:07:52 on ttys002
esther:~ user$ expect expect-test.exp
spawn ssh -p 2222 my_username#11.22.11.22
my_username#11.22.11.22's password:
Last login: Wed May 12 15:44:43 2010 from 20.10.20.10
-jailshell-3.2$
But that's where the success ends.
Commands do not work, but hitting enter just makes a new line.
Arrow keys and other non-alphanumeric keys produce symbols like '^[[C', '^[[A', '^[OQ' etc.[1]
No other prompt appears except the two initially created by the expect script.
Any ignored commands will be executed by my local shell once expect times out.
An example:
-jailshell-3.2$ whoami
ls
pwd
hostname
(...time passes, expect times out...)
esther:~ user$ whoami
user
esther:~ ciaran$ ls
Books Documents Movies Public
Code Downloads Music Sites
Desktop Library Pictures expect-test.exp
esther:~ ciaran$ pwd
/Users/ciaran
esther:~ ciaran$ hostname
esther.local
As I said, I have no shell scripting experience, but I think it's being caused because I'm still "inside of" expect, but not "inside of" SSH. Is there any way to terminate expect once I've logged in, and have it hand over the SSH session to me?
I've tried commands like 'close' and 'exit', after " send -- "\r" ". Yeah, they do what I want and expect dies, but it vindictively takes the SSH session down with it, leaving me back where I started. What I really need is for expect to do its job and terminate, leaving the SSH session back in my hands as if I did it manually.
All help is appreciated, thanks.
[1] I know there's a name for this, but I don't know what it is. And this is one of those frightening things which can't be googled, because the punctuation characters are ignored. As a side question, what's the story here?
I think your problem has been solved here before:
Using expect to pass a password to ssh
The command you're looking for is interact. It hands the control over to you/your keyboard.
I've used a similar script to autologin.
I used "interact" and I removed "expect eof". By doing this, I can get the screen back so that I can enter commands by hand.
expect "?assword: "
send -- "$password\r"
expect "$"
interact
putting it all together, log you in and leave you on the command line exactly as though you typed it manually
#!/usr/bin/expect -f
set ip "127.001.001.001"
set password "xxyykkx"
spawn ssh $ip -l root
expect "?assword:"
send "$password\r"
interact

Resources