very starnge behaviour in expect script - expect

I have expect script which I run to get some export of the live Network, but I have a stupid issue now. Script connect's to smotool, and log file to myfile.log, but today it won't work. Well when I put exp_internal 1 or log_user 1 it's working fine, otherwise not. It's really stupid and annoying but I don't know does anyone have idea what could I include in code. I want to hide the output, that's why I can't use log_user 1.
Sory if question is in some hand stupid:)
#!/usr/local/bin/expect
match_max 1000
exp_internal 0
log_user 0
set timeout 180
spawn smotool
log_file myfile.log
set prompt smo.*
expect -re $prompt
send -- "listnes -full"
expect -re $prompt

Related

why expect shell script for 'obexctl' not working as Expected

I want to send a file using bluetooth from one device to another device. For that i am using obex which has a command called 'obexctl'. It works as
described in this ... Please Take a look into this Doc
This is how sending file works. For automating this process i have written one shell script using expect. which is as below.
#!/usr/bin/expect -f
set address [lindex $argv 0]
set prompt "#"
spawn obexctl
sleep 2
expect -re $prompt
send "connect $address\r"
sleep 5
send "quit\r"
but it didnt work. It doesnt fully execute that connect command.and exit the code. Please let me know if any of you know the solution.

Why '\n'('\r') does not work in my expect script

I want to input y+enter to reply the question while executing copy tftp:something.
The script will send y, but \n does not work. It will stay (y/n)y and keep there without exiting or doing something else. I have tried \r, and the result was the same. Does anyone know the reason?
#!bin/bash
expect -c "
set timeout -1
spawn telnet x.x.x.x
expect \"username\"
send \"user\n\"
expect \"password\"
send \"pw\n\"
expect \"model\"
send \"copy tftp:something\n\"
expect \"(y/n)\"
send \"y\n\"
expect eof
"
exit 0
I prefer using \r to "hit enter".
Second, your entire bash script is expect, so remove the outer bash layer.
#!/usr/bin/expect -f
set timeout -1
spawn telnet x.x.x.x
expect "username"
send "user\r"
expect "password"
send "pw\r"
expect "model"
send "copy tftp:something\r"
expect "(y/n)"
send "y\r"
expect eof
If you have more logic in the bash part, to avoid quoting hell use a heredoc:
#!/bin/bash
expect <<'END_EXPECT'
set timeout -1
spawn telnet x.x.x.x
expect "username"
send "user\r"
expect "password"
send "pw\r"
expect "model"
send "copy tftp:something\r"
expect "(y/n)"
send "y\r"
expect eof
END_EXPECT
exit 0

Expect not waiting for prompt - script stops without sending other commands

Before this is chalked up as a timeout, or max_match issue, I will say that I have tried those. I have also tried using full_buffer, but it seems the only fix is to put a sleepafter theexpect when a large output comes before it. It's almost as if the expect ">$" is seen and processed by expect before the terminal can print the output.
term len 0 is a cisco command to basically prevent the default | more of the file
Example:
set timeout -1
spawn ssh host
expect "assword:"
send "$pass\r"
expect ">$"
send "term len 0\r"
expect ">$"
set size_orig [match_max]
match_max 60000000
send "show start\r"
expect ">$"
does not work. The output of "show start" is stopped x lines into the output.
If I put handling for timeout and full_buffer, the same thing happens:
set timeout -1
spawn ssh host
expect "assword:"
send "$pass\r"
expect ">$"
send "term len 0\r"
expect ">$"
set size_orig [match_max]
match_max 60000000
set timeout -1
send "show start\r"
expect {
timeout {
send $expect_out(buffer)
}
full_buffer {
send $expect_out(buffer)
}
">$" {
append outcome $expect_out(buffer)
}
}
The only way I was able to fix this was adding a sleep after the expect ">$" (I did this in the simple script below, and also in the script which handles full_buffer and timeout) :
set timeout -1
spawn ssh host
expect "assword:"
send "$pass\r"
expect ">$"
send "term len 0\r"
expect ">$"
set size_orig [match_max]
match_max 60000000
set timeout -1
send "show start\r"
expect ">$"
sleep 10
This works, but is there a proper way to do this as opposed to making the script wait by sleeping? Not all of the devices have such large outputs, so the sleep is not needed on each host.
one additional test I made was running the script with expect -d and the following was at the end of the truncated ouput:
tty_set: raw = 3, echo = 0
Thanks,
chris
The following resolved the issue in my script by suppressing the output displayed to the user, and rather, appending it to my log_file :
log_file -a initial_commands
log_user 0
send "some commands with large output"
log_file
log_user 1
In this case it does not matter whether the user sees the output, as I am parsing it and outputting it to a file anyway. To further disprove it was an error in my expect "<$" code, I experienced this same behavior (by complete accident) when running system "parse.pl". That perl script simply read the large output of show start and printed it line by line. Sure enough, the output stopped short and the script stopped. If anyone would like to dive deeper into this issue, please let me know and I can gladly provide more info.

Automatic disconnect telnet in bash scripting

When i run the script below, it connects the server but it disconnect before sending a command. How can i solve this problem.
#!/bin/bash
/usr/bin/expect << EOD
spawn telnet 31.168.109.31
sleep 2
expect ">"
sleep 1
send "my_password"
send "\n"
sleep 1
interact
As per your code you expect > before password. I am not getting you what is purpose of it but as for some example script look here. It's might be not an answer but probably help you.
#!/bin/bash
/usr/bin/expect << EOD
set timeout 200
spawn telnet 31.168.109.31
expect "login:"
send "root\r"
expect "password"
send "mypassword\r"
expect "root#"
#rest of your logic what you want.

How to use error codes inside bash script

Apologies if this has been asked before, I was unable to find an answer...
I have created a bash script for OS X to mount an AFP share. The script works successfully and allows a user to type their username and password into a graphical popup using cocoa dialog
My issue is that if the username and password are entered incorrectly, I want to be able to display a new pop up window explaining this.
I was trying to do this based on the exit status of the script but the script returns 0 regardless of whether or not the mount was successful
The script is as follows;
cd=/etc/cocoaDialog.app/Contents/MacOS/cocoaDialog
rvUsername=($($cd standard-inputbox --title "Network Mount" --informative-text "Please enter your username"))
username=${rvUsername[1]}
rvPassword=($($cd secure-standard-inputbox --title "Network Mount" --informative-text "Please enter your password"))
password=${rvPassword[1]}
mkdir "/Volumes/Test"
expect <<- DONE
set timeout -1
spawn /sbin/mount_afp -i "afp://servername/Software" /Volumes/Test
expect "*?ser:*"
send "$username\n"
expect "*?assword:*"
send "$password\r"
expect EOF
DONE
If I run this via Terminal or Textmate, I receive the following (as an example)
spawn /sbin/mount_afp -i afp://server/Software /Volumes/Test
User: username
Password:
mount_afp: the volume is already mounted
Program exited with code #0 after 7.32 seconds.
So mount_afp is giving me a message, which I would then like to use in my script...but the exit code is 0 and I don't know how else to get hold of that message to use
Any ideas? (Hope that makes sense!)
To get the exit code of the spawned command, use something like this:
# wait for the command to end : wait for the prompt $ followed by space
expect "\\$ "
send "echo \$?\r"
expect -re "(\\d+)" {
set result $expect_out(1,string)
}
send_user "command exit with result code : $result"
This will take the content of the variable $? (which is the exit code of the prevously ended command) and save it to $result.
Thanks for the responses all, helped point me in the right direction
I ended up taking this approach and setting the expect command as a variable
output=$(su -l $loggedInUser -c expect <<- DONE
set timeout -1
spawn /sbin/mount_afp -i "afp://$serverName" /Volumes/mount
expect "*?ser:*"
send "$username\n"
expect "*?assword:*"
send "$password\r"
expect EOF
DONE)

Resources