I am trying to install a rpm package after logging into a virtual machine(VM) using expect script.
The logging is fine but when trying to run rpm command it is exiting from the VM and returning back to the called machine.
The command called for rpm installation
rpm -ivh --force pkg_name
To login using expect I use
spawn ssh root#1.1.1.1 and then when it expects the password I send it.
Has anybody faced such problems?
Any help will be useful.
Thanks.
Below is the expect file to login to the system
login_script.exp
#!/usr/bin/expect
set timeout 60
set prompt {[#>$] }
system "rm -f ~/.ssh/known_hosts"
spawn ssh root#1.1.1.1
expect {
"yes/no" {
send "yes\r"
expect {
"*?assword: " {
send "abcdefgh\r"
expect -re $prompt {}
}
}
}
"*?assword" {
send "abcdefgh\r"
expect -re $prompt {}
}
}
send "sleep 1\r"
send "sudo -i\r"
expect "*?assword" { send "abcdefgh\r" }
And the original script will call
/usr/bin/expect << -EOF-
source login_script.exp
expect "\$prompt" ;# wait for prompt
send "rpm -ivh --force /tmp/pkg_abc\r"
expect "\$prompt" ;# wait for prompt
-EOF-
Output for both:
[root#
YYY-BServer01 ~]# rpm -ivvh --force /tmp/pkg_abc
D: ============== /tmp/pkg_abc
D: loading keyring from pubkeys in /var/lib/rpm/pubkeys/*.key
D: couldn't find any keys in /var/lib/rpm/pubkeys/*.key
D: loading keyring from rpmdb
D: opening db environment /var/lib/rpm cdb:0x401
D: opening db index /var/lib/rpm/Packages 0x400 mode=0x0
D: locked db index /var/lib/rpm/Packages
D: opening db index /var/lib/rpm/Name 0x400 mode=0x0
D: read h#
622 Header sanity check: OK-bash-4.1#
Related
This question already has answers here:
Execute sudo using expect inside ssh from bash
(3 answers)
Closed 5 years ago.
I'm trying to install a pkg file on remote machines. Facing issue while using expect inside ssh. unable to pass the password while using actual password or variable $pass
#!/bin/bash
agentpath="/Users/vigneshganapathy/Downloads/FS-Agent"
pass="xxx"
expect -c "spawn ssh -o StrictHostKeyChecking=no shyamkarthikv#192.168.57.33
expect \"*?assword:\" {send \"$pass\r\"; exp_continue}
spawn sudo installer -pkg \"/tmp/FS-Agent/FS-Agent.pkg\" -target \"/\"
expect \"*?assword:\" {send \"xxx/r\"; exp_continue}"
here-documents are a good way to embed code from another language into a shell script: The heredoc word is quoted (expect <<'END_EXPECT') which single-quotes the whole document. This allows you to not have to escape everything.
I use the environment to pass variables from shell to expect
I am assuming that you want to execute the "installer" command on the remote host, in which case, you want to send it not spawn it.
#!/bin/bash
agentpath="/Users/vigneshganapathy/Downloads/FS-Agent"
export pass="xxx"
expect <<'END_EXPECT'
spawn ssh -o StrictHostKeyChecking=no shyamkarthikv#192.168.57.33
expect {
"*?assword:" {
send "$env(pass)\r"
exp_continue
}
somePatternThatMatchesYourPrompt
}
set timeout -1 ;# in case it takes a long time to complete
send "sudo installer -pkg /tmp/FS-Agent/FS-Agent.pkg -target / \r"
expect {
"*?assword:" {
send "$env(pass)\r"
exp_continue
}
somePatternThatMatchesYourPrompt
}
set timeout 2
send "exit\r"
expect eof
END_EXPECT
This doesn't look like a correct expect-script to me. In general, it is a good idea to use an expect script instead of trying to put it all in an argument.
spawn ssh -o StrictHostKeyChecking=no shyamkarthikv#192.168.57.33
expect \"*?assword:\"
{send \"$pass\r\"; exp_continue}
spawn sudo installer -pkg \"/tmp/FS-Agent/FS-Agent.pkg\" -target \"/\"
expect \"*?assword:\"
{send \"xxx/r\"; exp_continue}"
So what this does is
start an ssh-session on 192.168.57.33
start sudo installer on the local machine
That is almost certainly not what you want. What I think that you want is:
#!/usr/bin/expect
eval spawn ssh -o StrictHostKeyChecking=no shyamkarthikv#192.168.57.33
expect "ord:"
send "$env(PASSWORD)\r";
expect "~"
send "sudo installer -pkg /tmp/FS-Agent/FS-Agent.pkg -target /\r"
expect "ord:"
send "$env(PASSWORD)\r";
make sure you export the variable PASSWORD in your calling shell.
I found the following script which gives me the possibility to go to a server without manually type in a required password.
Sadly I don't know how to execute commands after the connection is made :(
#!/usr/bin/expect -f
spawn ssh user#server
expect "assword:"
send "pw123\r"
interact
#the following is not executed anymore
cd /tmp/
The cd /tmp/ command is not executed, does someone know how to do this ?
I don't care about security :)
Key-based authentication is not an option.
Edit:
Ok, I found a solution that fits my needs:
#!/usr/bin/expect -f
spawn user#server
expect "assword:"
send "pw123\r"
expect "> " { send "cd /tmp\r" }
interact
The expect "> " has to be like your prompt.
After the connection is made, you are in the shell of the remote host to which you connected through the script. So to execute any command you will have to execute command manually on the command prompt.
If you want only to execute the command on the remote server automatically without need for ssh then you can use the below command.
#!/usr/bin/expect -f
#Changed here
spawn ssh user#server "cd /tmp && ls"
expect "password:"
send "pw123\r"
interact
I constantly need to log into a remote server and do all kinds of work. I am using my Mac and every time I have to type in a long command to do that.
ssh -i ~/key.pem ubuntu#255.255.255.255
I am wondering what would be the easiest way to log into the remote server without typing in the command everyday.
Handy apple apps are also welcome
Updated:
1> Thanks to Matt Bryant's answer. I successfully avoided typing in the whole username and host address by modifying ~/.ssh/config (doesn't exist as default) to
Host <ShortName>
User <UserName>
HostName <HostIP>
IdentityFile <KeyPath>
then I could just type this command to avoid typing in the full name of host and full path of the key:
ssh <ShortName>
2> Anyone knows how to store the pem key or avoid typing in the password if there is no pem key?
Use the ~/.ssh/config file. Try adding the following to it:
Host server
User ubuntu
HostName 255.255.255.255
This will allow you to login using ssh -i ~/key.pem server. If you look up ssh config, there are many other settings that will allow you to simplify and enhance your ssh experience.
Hi B MR W yes I am going to post up an expect script since this comes up a lot:
E2A The instructions are for linux
There is expect on mac https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/expect.1.html
It might be mean messing with the script to meet the criteria of the mac expect I don't have enough knowledge on that but in principal having had a look the below process should work
Which bit was you interested in the ssh-copy-id or a script?
to get a script going you need to
sudo-apt-get install expect or
sudo yum install expect
Once installed
This is a typical script:
#!/usr/bin/expect -f
set force_conservative 1
if {$force_conservative} {
set send_slow {1 .001}
proc send {ignore arg} {
sleep .001
exp_send -s -- $arg
}
}
;# Validate user input - make sure all fields required are given
if {$argc >= 1} {
;# Setting password
set user "MYUSER";
set supass "MYPASSWORD"
set host [lindex $argv 0]
# set command1 [lindex $argv 2]
set prompt "(:|#|%|>|\\\$|% |# |> |\\\$ )"
set prompt1 "(>)"
set timeout -1
;###############################################################
;#connect to specified host given by addstaff or globalstaff.
spawn ssh $user#$host
expect {
"*word:*" {}
"*(yes/no)?*" {
send - "yes\r"
expect "*word:" { }
}
}
send - "$supass\r"
expect eof exit -re $prompt
send - "sudo bash\r"
expect {
"*word:*" {
send "$supass\r"
expect eof exit -re $prompt
}
"*" {
expect eof exit -re $prompt
}
}
send - "whoami\r"
expect eof exit -re $prompt
interact
;#send - "$command\r"
;# expect eof exit -re $prompt
;#Logout of current ssh session
;#send - "exit\r"
;#expect eof exit -re $prompt
;#send - "exit\r"
;#expect eof exit -re $prompt
} else {
send - "echo Sorry require user host command \n\n\r";
exit
}
If you have noticed I have commented out the commands which is not being sent - its using interact mode to allow you to actually log in without a password, user password defined at the top of the script... Once logged in you type as you would per normal ssh
Here is me running it locally:
whoami
myuser
./ssh-connection.exp localhost
spawn ssh myuser#localhost
myuser#localhost's password:
Welcome to Ubuntu 12.04.2 LTS (GNU/Linux XXXX)
* Documentation: https://help.ubuntu.com/
Last login: Sat Sep 7 20:19:53 2013 from localhost
sudo bash
This is BASH 4.2- DISPLAY on localhost:0.0
Sat Sep 7 20:25:09 BST 2013
whoami
[20:25 myuser#myuser-DP ~] > sudo bash
whoami
This is BASH 4.2- DISPLAY on localhost:0.0
Sat Sep 7 20:25:09 BST 2013
[20:25 myuser#myuser-DP ~] > whoami
root
[20:25 myuser#myuser-DP ~] > whoami
root
Within the script it also does a sudo bash which is why it reconnects me to localhost and I become root
I realize this question has been asked a few times but I could not find a relevant answer anywhere in my searching.
I am working in a development environment where security is not an issue and anyone could just guess the password if the thought for a few seconds.
What I am trying to do is simple. I have created an alias function in my local .bashrc file and I would like this function to automatically log into a machine with a default password.
My current implementation looks something like this:
function s () {
ssh root#192.168.1.$1
}
When I run it I get something like this:
~]s 122
ssh root#192.168.1.122
root#192.168.1.122's password:
Using Bash, and not using RSA keys I would like to get this to use the default password 'password'.
I've tried the following where IP and User have already been set.
Do=$(expect -c "
spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}
expect \"yes/no\"
send \"yes\r\"
expect \"assword\" send \"password\"")
echo $Do
$Do
It gives the follwing error:
Connecting and logging into server using expect
usage: send [args] string
while executing
"send"
invoked from within
"expect "assword" send "password""
Administrator#192.168.1.176's password:
bash: spawn: command not found...
Using the following command I am able to connect a machine. If I remove the interact it just runs the uptime command and closes the connection. With the interact command I am unable to see what I am typing or actually interact with the machine. Any ideas?
Do=$(expect -c "spawn ssh $User#${IP[0]}.${IP[1]}.${IP[2]}.${IP[3]}; set timeout 4; expect \"assword\"; send \"password\n\"; expect \"test\"; send \"uptime\n\"; interact;");echo $Do;
You can do this with the expect tool: http://expect.sourceforge.net/
It's widely available, so depending on your system, the equivalent of sudo apt-get install expect or yum install expect will install it.
Here's an example of an expect script with ssh. This logs you in and gives you control of the interactive prompt:
#!/usr/bin/expect
set login "root"
set addr "127.0.0.1"
set pw "password"
spawn ssh $login#$addr
expect "$login#$addr\'s password:"
send "$pw\r"
expect "#"
send "cd /developer\r"
interact
Here's an example of how to use expect as part of a bash script. This logs in with ssh, cd to /var, runs a script, then exits the ssh session.
#!/bin/bash
...
login_via_ssh_and_do_stuff() {
# build the expect script in bash
expect_sh=$(expect -c "
spawn ssh root#127.0.0.1
expect \"password:\"
send \"password\r\"
expect \"#\"
send \"cd /var\r\"
expect \"#\"
send \"chmod +x my_script.sh\r\"
expect \"#\"
send \"./my_script.sh\r\"
expect \"#\"
send \"exit\r\"
")
# run the expect script
echo "$expect_sh"
}
You can leave these snippets in a script on your local system, and then just alias to the scripts.
Also: I know you said security isn't an issue, but I'd like to just note, again, that the "proper" way to ssh without using a password is to use a ssh key-pair =)
Use sshpass which is available in package repositories on major Linux-es.
For example, when password is in password.txt file:
sshpass -fpassword.txt ssh username#hostname
sshpass runs ssh in a dedicated tty, fooling it into thinking it is
getting the password from an interactive user.
I have tried to write a script to download file from remote server as below:
#!/bin/bash
######!/usr/bin/expect -f
# connect via scp
server='remoteserver#202.132.251.225'
pass='abcde12345'
remoteServerDesitination='/home/vijay/myHOMEdir'
file_to_get='amber9_installation_steps.txt'
directory_to_safe='/home/vijay/Simulation-Folders'
/usr/bin/expect << EOF
spawn scp "$server:$remoteServerDesitination/$file_to_get" $directory_to_safe
expect {
-re ".*sword.*" {
exp_send "$pass\n"
}
}
interact
EOF
when I execute this script, it doesn't pop out any error and no files downlaoded either. I can not trace out what the missing error.
Is your expect script attempting to supply a password to scp? You may be better off using a keypair, and just skipping password authentication altogether. Try googling "ssh keypair tutorial" for instructions on setting this up.
Use sshpass!
#!/bin/bash
SERVER=remoteserver#202.132.251.225
PASS=abcde12345
REMOTESERVERDESITINATION=/home/vijay/myHOMEdir
FILE_TO_GET=amber9_installation_steps.txt
DIRECTORY_TO_SAFE=/home/vijay/Simulation-Folders
sshpass -p $PASS scp $SERVER:$REMOTESERVERDESITINATION/$FILE_TO_GET $DIRECTORY_TO_SAFE