I have the following script working. I would like the result of command send -- "/system identity print\r" executed saved to a file, but it is probably badly written. At the moment, I can only write the path to the file tmp.
#!/bin/bash
HOSTNAME="xx.xx.xx.xx"
PORT="22422"
USER="admin"
PASS="pass"
TMP=$(mktemp)
PATH="/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin"
# Create Expect script
cat > $TMP << EOF
#exp_internal 1 # Uncomment for debug
set timeout -1
spawn ssh -p$PORT $USER#$HOSTNAME
match_max 100000
expect -exact "password:"
send -- "$PASS\r"
expect " > "
$nazwa send -- "/system identity print\r"
expect " > "
send -- "quit\r"
expect eof
EOF
# Run Expect script
#cat $TMP # Uncomment for debug
expect -f $TMP
echo $TMP >> log.log
# remove expect script
rm $TMP
Since your are actually developing your script, uncomment exp_internal 1 to get Expect to help you.
Related
I have a script that spawns another process.
I want to redirect output of that process to a log file.
But >> doesnt work
#!/bin/bash
#!/usr/local/bin/expect -f
####echo $#
/usr/local/bin/expect <<EOD
set timeout 10
spawn $sec/add.zims.user ${1} "${2} ${3}" >> /home/arvind/logs/ADD.log
expect "e4234234's Password: " { send "${4}\n" }
expect "*'s New password: " { send "${5}\n" }
expect "Enter the new password again:" { send "${5}\n" }
EOD
'''
Yes, the spawn command does not process shell redirections (1)
You could either let the shell handle the redirection:
/usr/local/bin/expect <<EOD
# ...
spawn ... ;# with no redirection
# ...
EOD
Or, use the expect log_file and log_user commands:
log_file -a $env(HOME)/logs/ADD.log will send output into that log file (appending unless you specify the -noappend flag). This does not turn off regular output to stdout
log_user 0 will turn off the usual stdout output. This does not alter logging using log_file
So:
/usr/local/bin/expect <<EOD
set timeout 10
log_user 0
log_file -a /home/arvind/logs/ADD.log
spawn $sec/add.zims.user ${1} "${2} ${3}"
# ...
END
(1) -- the exec command does do redirections, but not exactly like the shell: see the exec manual
I am trying to have an expect script inside a bash to login to a router, execute a command and store output in a text file.
#!/usr/bin/bash
FQDN=$1
LogFile=/tmp/Router_${FQDN}.txt
> $LogFile
expect -d <<EOF > $LogFile
set timeout 20
set FQDN [lindex $argv 0]
set Username "user"
set Password "***$$$"
spawn ssh $Username#$FQDN
expect "*assword:"
send "$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
expect eof
EOF
cat $LogFile
I am getting the below error message.
system personnel =\r\r\n= may provide the evidence of such monitoring to law enforcement officials. =\r\r\n=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==\r\r\npassword: "
send: sending "\n" to { exp6 }
expect: does "" (spawn_id exp6) match glob pattern "#"? no
password:
Enter old password:
Based on the error it appears that script is hitting the {return} key "\r" which is not to be sent at password prompt.
I don't have a return once i ssh. Not sure where i am going wrong.
This is my expect script which is working fine. Its only when i code this inside a bash script its failing.
#!/usr/bin/expect -f
set timeout 20
set FQDN [lindex $argv 0]
set Username "user"
set Password "***$$$"
spawn ssh -o "StrictHostKeyChecking no" $Username#$FQDN
expect "*assword: "
send "$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
-Abhi
In a here-doc, variables like $Username and $Password are being expanded by the shell, so they're not seen as literals for Expect to expand. Since those shell variables aren't set anywhere, they're being expanded to null strings. As a result, it's executing ssh #$FQDN and sending an empty password.
You need to escape the $ so that Expect can process them.
You also don't need the set FQDN line in the Expect script, since you're using the shell variable for that.
#!/usr/bin/bash
FQDN=$1
LogFile=/tmp/Router_${FQDN}.txt
> $LogFile
expect -d <<EOF > $LogFile
set timeout 20
set Username "user"
set Password "***$$$"
spawn ssh \$Username#$FQDN
expect "*assword:"
send "\$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
expect eof
EOF
cat $LogFile
Or you could set them as shell variables, just like FQDN.
#!/usr/bin/bash
FQDN=$1
Username=user
Password="***$$$"
LogFile=/tmp/Router_${FQDN}.txt
> $LogFile
expect -d <<EOF > $LogFile
set timeout 20
spawn ssh $Username#$FQDN
expect "*assword:"
send "$Password\r"
expect "#"
send "some command\r"
expect "#"
send "exit\r"
sleep 1
exit
expect eof
EOF
cat $LogFile
I'm calling a function in which I'm scp files to remote server. but its giving out error.
Function below :-
scp_files()
{
######## scp files to remote host ###############
echo "**************************************************************************"
echo " scp files to remote host .. *"
echo "**************************************************************************"
echo "value of first argument is $1"
echo "silver username is $silver_username"
expect <<- DONE
log_user 0
set timeout -1
spawn scp commands.txt $silver_username#$1:/tmp/
expect "password: "
send "test123\r"
expect "$ "
send "exit\r"
expect eof
DONE
}
calling function
scp_files ${!REDIS_IP} ${!REDIS_PORT}
here im getting error as below :
send: spawn id exp5 not open
Where could be the issue here?
The question is to preserve a variable and to perform actions after closing ssh within expect script inside bash.
This is what I`ve got so far:
echo "Getting package name..."
getPackageName=$(expect -c '
exp_internal 1
log_user 1
global expect_out
# puts "Getting package name..."
spawn ssh -q -o StrictHostKeyChecking=no -o PreferredAuthentications=password -o PubkeyAuthentication=no -o RSAAuthentication=no -l user 10.20.30.40
sleep 1
expect {
"*sword*" {
send "12341234\r"
}
timeout {
send_user "Error: timeout\n"
exit 1
}
}
expect {
"*user#*>*" {
# getting name of the latest modified file
send "cd /export/home/user/Releases/build/1.3.32.0 && find * -type f -printf '"'"'%T# %p\\n'"'"' | sort -n | tail -1 | cut -f2- -d\" \"\r"
}
timeout {
send_user "Error: timeout\n"
exit 1
}
}
expect {
"BUILD_MAIN*" {
# assigning value to variable
set result_lines [split $expect_out(0,string) \r\n]
set package_filename [lindex $result_lines 0]
puts "package_filename: $package_filename"
}
timeout {
send_user "Error: timeout\n"
exit 1
}
}
expect "*#"
send "exit\r"
# here I need to perform some actions on local machine after ssh logout
expect "Connection*"
send "export LATEST_BUILD=$package_filename\r"
send_user "Message sent to user"
')
So, in the bottom block I am trying to set environment variable (LATEST_BUILD) on the local machine after closing ssh, and also to paste there a value of variable (package_filename) which has been defined earlier during ssh session.
The point here is that I see the last "Message sent to user" in the output, but the previous send "export LATEST_BUILD=12345\r" obviously does not work.
#!/bin/bash
getPackageName=$(expect -c '
# A common prompt matcher
set prompt "%|>|#|\\\$ $"
# To suppress any other form of output generated by spawned process
log_user 0
### Spawning ssh here ###
spawn ssh user#xxx.xx.xxx.xxx
expect "password"
send "welcome!2E\r"
expect -re $prompt
# Your further code
send "exit\r"
expect eof
##### The below segment is not needed ######
##### if your intention is to get only the 'package_filename' value #####
# spawn bash
# expect -re $prompt
# send "export LATEST_BUILD=54.030\r"
# expect -re $prompt
# send "echo \$LATEST_BUILD\r"
# expect -re $prompt
# send "exit\r"
# expect eof
#
##### The End ######
# Enabling logging now ...
log_user 1
# Print only the value which you want to return
puts "$package_filename"
')
echo $getPackageName
eof is used to identify the end-of-file event i.e. closure of connection.
Note : The exported variable LATEST_BUILD only be available for the spawned bash session.
Update :
log_user is used to turn off/on the logging generated by Expect at any time.
log_user 0; # Turn off logging
log_user 1; # Turn on logging
I hope that your only intention is to get the package_filename. So, we don't even need to spawn bash shell. Instead, simply print the value at last, thereby making it to be available to the parent bash script.
This is the code snippet I am using in the following Bash script:
for user_input in `awk '{print}' testfile_$$.txt`
do
ipaddress=`echo $user_input | cut -d';' -f 1`
command="${config_mode}`echo $user_input | cut -d';' -f 2-`"
ping -w 1 $ipaddress 1> /dev/null 2> $ERR_LOG_FILE 1> $LOG_FILE
if [ $? -eq 0 ];then
ssh "$USERNAME#$ipaddress" "$command"
>> $LOG_FILE
fi
done
How do I use Expect to automate the SSH login in this script?
I am very new to Expect and started testing this (it failed):
#!/usr/bin/bash
set force_conservative 0 ;# Set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#
set timeout -1
spawn ssh auto21#10.38.227.229 {uname -a; df -h}
match_max 100000
expect "*?assword: "
send -- "bar01\r"
expect eof
Do I need to write the Bash script all over again in an Expect script or can Expect be used inside a Bash script?
If it can be done:
Moreover, I need to get the Bash variables $command, $username, $password, and $ipaddress and use it in the Expect part.
What solution would you suggest?
Or can I create an Expect script and call it from the Bash script just for login, error handling, execution, and logfiles.
Well, you will need to run two separate scripts, a shell script that calls an Expect script:
#!/usr/bin/bash
set force_conservative 0 ;
Change the above to
#!/usr/bin/expect
set force_conservative 0 ;
Or alternatively in your shell script I am unsure about the format, but you can send expect -c with the command to execute:
expect -c "send \"hello\n\"" -c "expect \"#\""
expect -c "send \"hello\n\"; expect \"#\""
Actually, there is also one other alternative:
#!/bin/bash
echo "shell script"
/usr/bin/expect<<EOF
set force_conservative 0 ;# Set to 1 to force conservative mode even if
;# script wasn't run conservatively originally
if {$force_conservative} {
set send_slow {1 .1}
proc send {ignore arg} {
sleep .1
exp_send -s -- $arg
}
}
#
set timeout -1
spawn ssh auto21#10.38.227.229 {uname -a; df -h}
match_max 100000
expect "*?assword: "
send -- "bar01\r"
expect eof
EOF