Unable to call a command on windows server by connecting through linux - expect

I am using a following script which connects to windows server from Linux, but after connecting i have to call the a command by doing to a location under D: drive of windows followed by some folders (Where the Folder names consists of spaces eg: d:\Rakesh Tatineni\not able to execute\Manager.exe 1 1)
Above is the some how i want to execute/call a command with 2 argument 1 1.
Script using to connect to windows
#!/usr/bin/expect -f
# Expect script to supply username/admin password for remote ssh server
# and execute command.
# This script needs three argument to(s) connect to remote server:
# password = Password of remote Windows server, for Windows user.
# For example:
# ./call_engine.sh password
# set Variables
set password [lrange $argv 0 0]
set timeout -1
# now connect to remote windows box (ipaddr/hostname) with given script to execute
spawn ssh userid#<WindowsserverName>
match_max 100000
# Look for passwod prompt
expect "*?assword:*"
# Send password aka $password
send "$password\r"
# send blank line (\r) to make sure we get back to gui
send "\r"
expect eof
Appreciate your help , in between what kind of code we have to include to call a command as i mentioned above "d:\Rakesh Tatineni\not able to execute\Manager.exe 1 1"
Thanks,
Rakesh T

I see that you already give the script an argument of password. So you can change your script slighlty to add two more arguments like this:
set password [lrange $argv 0 0]
set arg1 [lrange $argv 1 1]
set arg2 [lrange $argv 2 2]

Related

expect command not working as expected but working if not using expect script

So I have this script to create a user in my openvpn and the create_user.sh is working fine. But I want to create a bulk user for my openvpn and when I run this expect script it's also working fine, its response exactly to the prompt of the openvpn easyrsa. But the problem comes if I test the user and try to connect to openvpn it gives me error.
#!/usr/bin/expect
set user [lindex $argv 0]
set pass1 [lindex $argv 1]
set pass2 [lindex $argv 2]
set phrase [lindex $argv 3]
set timeout -1
spawn ./create_user.sh
expect "Enter Username:" { send -- "$user\r" }
expect "Enter PEM pass phrase:" { send -- "$pass1\r" }
expect "Verifying - Enter PEM pass phrase:" { send -- "$pass2\r"}
expect "Enter pass phrase for /etc/openvpn/pki/private/ca.key:" { send -- "$phrase\r"}
expect eof
This error I received
I know that the problem is in my PEM pass and pass phrase but when I use my create_user.sh its working fine and it can connect to the openvpn server. So I guess my expect script is not working fine when passing the values to the prompt of PEM pass phrase and pass phrase. Can somebody help me on this I'm just newbie in expect scripting.
This is the prompt when the create_user.sh run.

Specifying the password to connect with gcloud MySQL

I want to pass the password along with the user id in the single statement while connecting to the gcloud SQL instance. How will I do that? I tried a few combinations but couldn’t get any solutions.
Ex:
gcloud sql connect scegold2-f44e-mysql --user=username --password=password --quiet
It shows error around password.
Any help and guidance can I get. Am I doing anything wrong?
The expect program can be used in order to pass every argument at once to gcloud sql connect, including the password, for example using this autoconnect.exp script:
#!/usr/bin/expect -f
# Call command with "expect autoconnect.exp $INSTANCE $USER $PASSWORD",
# or place the arguments literally in the script, where the variables are.
set INSTANCE [lindex $argv 0]
set USER [lindex $argv 1]
set PASSWORD [lindex $argv 2]
set timeout -1
spawn gcloud sql connect $INSTANCE --user=$USER
expect "*Password*"
send -- "$PASSWORD\r"
expect eof
What this does is to wait for the gcloud command to prompt for the password (expect "*Password*" means wait for a line containing "Password") and then feed it the password, and then the database management system is opened as normal.
A nice guide for expect here.
As mentioned in the documentation, the flags for the "gcloud sql connect"command are:
--user=USER, -u USER
Based on this, you cannot specify the password in the same command line, and even if you create an instance by specifying "no password", it will ask you for the password (in that case you should only press enter).

How to execute a command on server using Expect

I want to remotely delete a file/execute another script on my server. Manually this could be done by ssh-login -> cd /path/ -> rm somefiles -> . script.sh
I want to automatic this process. So that when I execute expect expectscript.sh port serverip user userpasswd, the script would do the whole process for me.
So I write the following script. Things go smoothly till the ssh-login process finished. I don't know what is wrong with the last 3 lines of the code. Could someone help?
#!/usr/bin/expect
set timeout 20
set port [lindex $argv 0]
set ip [lindex $argv 1]
set user [lindex $argv 2]
set password [lindex $argv 3]
spawn ssh "$user\#$ip" "-p" "$port"
expect "password:"
send "$password\r"
spawn "cd /etc/abcd/"
spawn "rm -f efg/*"
spawn ". somescriptinefg.sh"
Change the spawn to send solve the problem~
Literally,
spawn "Creates a new process by running a given program."
send "Sends string to the current process."
The problem seems to be that the password is being sent with a spawn command rather than a send command. Additionally, ssh can be called with a specific command to run during the session, for example:
#!/usr/bin/expect
set timeout 20
set port [lindex $argv 0]
set ip [lindex $argv 1]
set user [lindex $argv 2]
set password [lindex $argv 3]
spawn ssh $user#$ip -p $port "cd /etc/abcd/; rm -f efg/*; . somescriptinefg.sh"
expect "password:*"
send "$password\r"
expect eof
It might be worth configuring ssh keys for passwordless access instead. This would eliminate the need for an expect script and reduce the whole thing to a single line. If you really need to have an interactive ssh session, then a tool such as sshpass could be a less impractical alternative.

Bash/Expect Script for SSH

I am new to Expect and scripting in general. I am trying to make a few scripts to make my life a bit easier when pulling network device configurations. I managed to create a basic Expect script to SSH to a device and save the configuration.
I want to expand upon this and allow the script to connect to a number of IP addresses instead of just one like I have right now. I have a file named list.txt with a few different IP addresses with each IP address on a separate line.
What would I need to do to have the Expect script connect to each of these IP addresses and perform the rest of the tasks in the script as well?
Here is the Expect script I have so far:
#!/usr/bin/expect -f
# Tells interpreter where the expect program is located. This may need adjusting according to
# your specific environment. Type ' which expect ' (without quotes) at a command prompt
# to find where it is located on your system and adjust the following line accordingly.
#
#
# Use the built in telnet program to connect to an IP and port number
spawn ssh 192.168.1.4 -l admin
#
# The first thing we should see is a User Name prompt
#expect "login as:"
#
# Send a valid username to the device
#send "admin"
#
# The next thing we should see is a Password prompt
expect "Password:"
#
# Send a valid password to the device
send "password\n"
#
# If the device automatically assigns us to a privileged level after successful logon,
# then we should be at an enable prompt
expect "Last login:"
#
# Tell the device to turn off paging
#
# After each command issued at the enable prompt, we expect the enable prompt again to tell us the
# command has executed and is ready for another command
expect "admin#"
#
# Turn off the paging
send "set cli pager off\n"
#
# Show us the running configuration on the screen
send "show config running\n"
#
# Set the date.
set date [timestamp -format %C%y%m%d]
#
# Test output sent to file with a timestamp on end
#-noappend will create a new file if one already exists
log_file -noappend /home/test.cfg$date
#
expect "admin#"
#
# Exit out of the network device
send "exit\n"
#
# The interact command is part of the expect script, which tells the script to hand off control to the user.
# This will allow you to continue to stay in the device for issuing future commands, instead of just closing
# the session after finishing running all the commands.`enter code here`
interact
Do I need to integrate this with a Bash script? If so, is it possible to read one line of the list.txt file, use that as the IP address/host variable and then read the next and repeat?
I would do this (untested):
#!/usr/bin/expect -f
set logfile "/home/text.cfg[clock format [clock seconds] -format %Y%m%d]"
close [open $logfile w] ;# truncate the logfile if it exists
set ip_file "list.txt"
set fid [open $ip_file r]
while {[gets $fid ip] != -1} {
spawn ssh $ip -l admin
expect "Password:"
send "password\r"
expect "admin#"
send "set cli pager off\r"
log_file $logfile
send "show config running\r"
expect "admin#"
log_file
send "exit\r"
expect eof
}
close $fid
Notes:
I removed all your comments for brevity
use \r to simulate hitting enter when you send commands.
I assumed you only want to log the "show config running" output
use expect eof after you send "exit"
This is a Perl version for this issue:
Install instruction:
cpan Expect
This script works perfectly for my needs.
Parameter 1: Connection string (example: admin#10.34.123.10)
Parameter 2: Clear text password
Parameter 3: Command to execute
#!/usr/bin/perl
use strict;
use Expect;
my $timeout = 1;
my $command = "ssh " . $ARGV[0] . " " . $ARGV[2];
#print " => $command\n";
my $exp = Expect->spawn($command) or die "Cannot spawn $command: $!\n";
$exp->raw_pty(1);
LOGIN:
$exp->expect($timeout,
[ 'ogin: $' => sub {
$exp->send("luser\n");
exp_continue;
}
],
[ 'yes\/no\)\?\s*$' => sub {
$exp->send("yes\n");
goto LOGIN;
}
],
[ 'assword:\s*$' => sub {
$exp->send($ARGV[1]."\n");
#print "password send: ", $ARGV[1];
exp_continue;
}
],
'-re', qr'[#>:] $'
);
$exp->soft_close();
A possibility is to pass the IP address as a parameter in your Expect script:
set host_ip [lindex $argv 0]
and then make a shell script, calling your Expect script inside a while loop:
ips_file="list.txt"
while read line
do
your_expect_script line
done < $ips_file
Or use set ip [gets stdin] to the IP address from the user input.
For example,
puts "Enter your IP address\n"
set ip [get stdin]
Use this in spawn. We can do the same for multiple IP addresses using a loop -
spawn ssh $ip -l admin
Here's a good way to integrate expect with bash:
ssh_util.expect-
#!/usr/bin/expect
set timeout -1
set ip [lindex $argv 0]
set user [lindex $argv 1]
set pwd [lindex $argv 2]
set commands [lrange $argv 3 [llength $argv]]
spawn ssh -o LogLevel=QUIET -t $user#$ip $commands
expect {
yes/no {send "yes\r" ; exp_continue}
*?assword {send "$pwd\r" ; exp_continue}
}
You can run this in the terminal with ./ssh_util.expect <commands...>. In your shell script you can use it to run commands on your host machine like this:
example.sh -
#! /bin/bash
# ssh_exp <commands...>
ssh_exp () {
./ssh_util.expect 192.168.1.4 username password $*
}
# run commands on host machine here
ssh_exp ls
ssh_exp ls -la
ssh_exp echo "Echo from host machine"
# you can even run sudo commands (if sudo password is same as user password)
ssh_exp sudo apt install
Make sure to run
chmod +x ssh_util.expect
chmod +x example.sh
in the terminal to make both files executable. Hope this helps!

how to use a shell script to supply a password when the interface asks for it

I have a script(dobrt) which upon executing asks for a password.How can i write a script which executes dobrt and automatically supplies the password it asks for.
when i execute ./dobrt -p file.txt , the system asks for a password. I want the password to be sent in automatically by the script. Here is the output
$ ./dobrt -p file.txt
Found 194 tests to execute
------------ 2010 February 11 11:27:33 ------------
Password: ***************
I tried using shell and expecxt scripts for this. here is what i did.
I have 2 scripts. I call the second script(run_dobrt.exp) from the first one(run_dobrt.sh).
Script 1 : run_dobrt.sh
#!/bin/ksh
TESTCASE_HOME="/home/abhijeet/code/testcases";
TESTCASE_LIST="file.txt";
PASSWORD="*****";
echo "Running Expect Script"
`./run_dobrt.exp $TESTCASE_HOME $TESTCASE_LIST $PASSWORD`
Script 2: run_dobrt.exp
#!/usr/local/bin/expect -f
set TESTCASE_HOME [lindex $argv 0];
set TESTCASE_LIST [lindex $argv 1];
set PASSWORD [lindex $argv 3];
set timeout 200
spawn $TESTCASE_HOME/dobrt -p $TESTCASE_HOME/$TESTCASE_LIST
expect "*?assword:*" {send -- "$PASSWORD\r";}
expect eof
Now when i run run_dobrt.sh i get the following error
run_dobrt.sh[20]: spawn: not found
How to get rid of this error and get this task done? Please help.
What is dobrt? is a self-made program? If this is the case I think you will have to recode it to parse an extra argument that accepts the password. Then you will be able to pass this passowrd to dobrt just as you do it like "-p file.txt" in the command line (through a script).
I see two problems:
In the last line of your shell script, remove the back-quotes `` around the command,
they will cause the output of the expect script to be executed as a shell command.
In the expect script, change
set PASSWORD [lindex $argv 3];
to
set PASSWORD [lindex $argv 2];
you are skipping an argument.
If the password is the only input dobrt prompts for, you could try this:
Script 1 : run_dobrt.sh
#!/bin/ksh
TESTCASE_HOME="/home/abhijeet/code/testcases";
TESTCASE_LIST="file.txt";
PASSWORD="*****";
./run_dobrt.exp $TESTCASE_HOME $TESTCASE_LIST << EOF
$PASSWORD
EOF

Resources