How to write bash script that enters password after the first command? [duplicate] - linux

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Using expect to pass a password to ssh
I want to have ssh connection to a remote machine and instead of using ssh command along with the machine address and password, I just want to write a little function that executes the ssh command to the machine and enters the pass after the server asks it. I can write the ssh part but how can I make the script that enters also the pass when the host ask for it?

You may use expect script. You can pass arguments from cmd line. Sample code I write:
#!/usr/bin/expect
set timeout 100
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set command [lindex $argv 3]
spawn ssh $username#$host $command
#puts $command
expect {
"(yes/no)?"
{
send "yes\n"
expect "*assword:" { send "$password\n"}
}
"*assword:"
{
send "$password\n"
}
}

You can use Expect tool
It's exactly what you need:
EDIT
#!/usr/bin/expect
set timeout 60
set user "yourName"
set machine "nameOfYourMachine"
set password "yourPassword"
set command "command that you want execute via ssh"
spawn ssh $user#$machine
while {1} {
expect {
eof {break}
"The authenticity of host" {send "yes\r"}
"password:" {send "$password\r"}
"*\]" {send "exit\r"}
"bash" {send "$command"}
}
}
wait
close $spawn_id
Just workaround it as you need

Related

Linux Shell script (bash) to change IP address of remote machine using SSH

I'd like to have a shell script to change the IP address of a remote machine using SSH.
The problem I am having is that both SSH and remote commands require passwords. I am using 'expect' to handle the password input and this works works well in isolation for each step, but not combined.
i.e. I have a separate script on the remote machine to change the IP address. This works when running manually on the remote machine.
#!/usr/bin/expect -f
set ipaddr [lindex $argv 0]
set password "mypassword"
set timeout 2
if {[llength $argv] == 0} {
send_user "Usage: ./set_ip.sh ipaddress/24\n"
exit 1
}
spawn sudo nmcli dev modify eth0 ipv4.addresses $ipaddr
expect {
password { send "$password\r" ; exp_continue }
timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
eof exit
}
close
And I have a script to perform the SSH, then call the above remote script
#!/usr/bin/expect -f
set target [lindex $argv 0]
set newipaddr [lindex $argv 1]
set password "mysshpassword"
set timeout 2
spawn ssh $target
expect {
password: {send "$password\r"}
timeout { send_user "\nFailed to get password prompt\n"; exit 1 }
eof exit
}
send "~/set_ip.sh $newipaddr/r"
send "exit\r"
close
When the remote script gets called, it seems to run okay but the password prompt following the nmcli command is never received.
If someone could advise where I am going wrong I'd be grateful.
Also, this is the first time I've used bash, so feel free to express critique.
Thanks

SFTP connection issue with password

I am running this script to copy pattern files in local but it is asking for password even passing the hardcode value.
Script:
PASSWORD="xyz"
sftp -oport=1002 user#host:/dir/archive/file*.txt /di/data/
<< EOF
$PASSWORD
quit
EOF
Got error:
-bash-4.1$ sh sftp_with_password.sh
Connecting to user#host...
Password Authentication
An expect script could do the job.
For instance copy-sftp.exp:
#!/usr/bin/expect
set password [lindex $argv 0]
spawn sftp -oport=1002 user#host:/dir/archive/file*.txt /di/data/
expect "Password"
send "$password\r"
send "quit\r"
Then you can execute it:
expect copy-ftp.exp $PASSWORD
Thanks to Gonzalo Matheu I've managed to do a send-sftp.exp using a proxy which send a big file to a sftp :
#!/usr/bin/expect
set timeout -1
set password [lindex $argv 0]
set file [lindex $argv 1]
spawn sftp -o "ProxyCommand /usr/bin/connect -H <proxy-host>:<proxy-port> %h %p" <sftp-Username>#<sftp-HOST>
expect "password:"
send "$password\r"
expect "sftp>"
send "put $file\r"
expect "sftp>"
send "quit\r"
Then I execute it :
expect send-sftp.exp $PASSWORD /PATH/TO/MYFILE.zip
set timeout allows the transfer not to be stoped by expect's wait timeout, you can adapt it to your needs ;)

Running shell command after expect login

Iam trying to exceute a command after logging in to a linux RHEL box using expect and interact.
Below is script
#!/usr/bin/expect
set timeout 100
set temp [lindex $argv 0]
spawn ssh userid#10.20.30.40
expect "Password:"
send "password\n";
interact
expect "*3.2*"
send "./p.sh\n";
Its successfully logging in to the box but after that its not excecuting the command.
This is the actual output of the commnad after login , which iam trying to exceute.
Using keyboard-interactive authentication.
Password:
Last login: Sun Mar 22 11:04:01 2015 from com
-sh-3.2$ pbrun pbapp wasapp=ksh
Please note home directories are intended only for user/application profiles.
$
These are the errors i received
-sh-3.2$ exit
logout
Connection to 10.20.30.40 closed.
expect: spawn id exp7 not open
while executing
"expect "*$""
(file "./testWas.sh" line 8)
when i try
expect "*$"
exec "pwd"
-sh-3.2$ exit
logout
Connection to 10.20.30.40 closed.
couldn't execute " pwd ": no such file or directory
while executing
"exec { pwd }"
(file "./testWas.sh" line 8)
Edit:
Thanks to red #glenn jackman
iam able to excute pbrun commands after login..
But after excecuting the pbrun command script is exiting
#!/usr/bin/expect
set timeout 100
set host [lindex $argv 0]
set username [lindex $argv 1]
set password [lindex $argv 2]
set command [lindex $argv 3]
spawn ssh $username#$host expect "Password:"
send "$password\n";
expect -re {\$ $} ; # put here string from your server prompt
send "./p.sh\n";
expect -re {\$ $} ;
send "pwd\n";
This is the content of p.sh
Only first line of the script is executing..
-sh-3.2$ cat p.sh
pbrun pbapp wsapp=ksh
pwd
clear
-sh-3.2$
There is a similar unanswered question
How to run "pbrun pbapp wasapp=ksh" command using SSH java client?
interact tells expect that you are going into manual mode, where you, the human, is in control of the spawned command. I see you then typed exit which ended the ssh session. Since the spawned command ended, the interact command ended and control returned to the script. The next command dies because the spawned command is not running.
Simply put, remove interact:
#!/usr/bin/expect
set timeout 100
set temp [lindex $argv 0]
spawn ssh userid#10.20.30.40
expect "Password:"
send "password\r" # a carriage return more exactly represents
# "hitting enter"
expect -re {\$ $} # this regular expression matches the end of the prompt
send "./p.sh\r"
if { you want to interact manually with the ssh session } {
interact
} else {
expect -re {\$ $} # if p.sh exits the ssh session, remove this line
send "exit\r" # and this one too.
expect eof
}

Expect command asks for password again in Linux

I am new to Linux Shell Scripting.I need to execute a shell script that gets username, password, host-name, command-to-be-executed as 1,2,3,4 parameters respectively. I used expect command but it prompts for password again.The main theme of this script is to execute a command from a remote server. Password security issues is not a problem. The main issue is that I must not be prompted for password input. I have to run this for about 80 servers, so I cant provide password for each and every time. Please help me solving this.
My script:
echo username = $1
echo Password = $2
echo Host-Name = $3
echo Command to Be executed = $4
expect -c "spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no $1#$3 $4; expect \"*assword:*\"; send "$2"; interact
#expect eof
"
My Output:
username = root
Password = root#123
Host-Name = host-name
Command to Be executed = ls
spawn ssh -oStrictHostKeyChecking=no -oCheckHostIP=no root#host-name ls
root#host-name's password:
~
first your index will start at 0 not 1 so username = $0
also you need to set your variables like so: (this is the expect script i use on sever hundred nodes)
#!/usr/bin/expect
set user [lindex $argv 0]
set password [lindex $argv 2]
set ip [lindex $argv 2]
set command [lindex $argv 3]
spawn ssh -o StrictHostKeyChecking=no "$user\#$ip"
expect "assword:"
send "$password\r";
expect "$ "
send "$command\r"
expect "$ "
send "exit\r"

spawn_id: spawn id exp6 not open

I know that this issue is already mentioned here, but the solution does not work for me.
I have this script (let's name it myscript.sh) that spawns a process on remote environment and that should interact with it.
#!/usr/bin/expect
log_user 0
set timeout 10
spawn ssh -o PubkeyAuthentication=no [lindex $argv 0] -n [lindex $argv 1]
expect "password:" {send "mypassword\r"}
expect "Continue to run (y/n)" {send "n\r"}
interact
When I call this script on local environment...
myscript.sh user#host "command1;./command2 parameter1 parameter2"
I get the above error at line 7 (interact)
Any ideas??
I suspect the expect is not able to find out(matching) the pattern you are sending.
expect "password:" {send "mypassword\r"}
expect "Continue to run (y/n)" {send "n\r"}
Check out again whether the "password:" and "Continue to run (y/n)" are in correct CAPS.
If still getting the same error, you can try using regular expression.
Try to do a normal ssh without script. See if it works. Sometimes the remote host identification changes, and the host has a new ip or new key. Then it helps to remove the old key with ssh-keygen -f ~/.ssh/known_hosts -R old_host, or something similar.
I had this problem and it was down to using the wrong port.
/usr/bin/expect <<EOF
spawn ssh-copy-id -i $dest_user#$ip
expect {
"yes/no" {
send "yes\r";exp_continue
} "password" {
send "$passwd\r"
} eof {
exit
}
}
expect eof
EOF
I ran into this issue as well but it was due to me creating/editing the following file for an unrelated item:
~/.ssh/config
Once I deleted that, all my scripts began working and I no longer got that issue with my expect file.

Resources