cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5244
Views
22
Helpful
10
Replies

Unable to run tcl script via crontab(buffer error)

pantelis1
Level 1
Level 1

Hi All

I am correcrtly executing the script below from my linux server. However, it seems that once I try to run it via crontab (correct permisions have been set etc) I get the following error:

can't read "expect_out(buffer)": no such variable

    while executing

"set output $expect_out(buffer)"

    ("foreach" body line 6)

    invoked from within

"foreach cmd $commands {

        send "$cmd\r"

        expect -re $prompt

        #remove zeros from the cmd filename

        regsub -all {[ \r\t\n]+} ..."

    ("foreach" body line 20)

    invoked from within

"foreach device $device_list {

# Set each device's log file to be the name of the device...

    set file_name $device

# we initiate the SSH connection

Crontab is:

0 4 * * *          /usr/bin/expect  /<path of the script>/<script name>.exp

Script below:

#!/usr/bin/expect

# Here, we specify all our commands in a list, that we will issue one

# by one at a later time.

set commands [list "show ip route summary" "show interfaces" "show arp" "show ip ospf neighbor"  "show ip eigrp neighbor" "show cdp neighbors"]

# Set the date.

set date [timestamp -format %C%y%m%d]

# This variable is for a file called switches.txt that has the hostname/IP

# of all of the routers you are collecting information from.tepad

set device_list [read [open "/<path>/switches.txt"]]

# Specify the username and password, as well as what we expect the routers'

# prompt to be.

set pass "*******"

#set prompt "#"

set prompt {([#>]) ?$}

# This command tells expect not to echo the output to the console.

exp_log_user 0

#log_user 1

# We loop through each device in our list, one by one...

foreach device $device_list {

# Set each device's log file to be the name of the device...

    set file_name $device

# we initiate the SSH connection

    eval spawn ssh $device -l ********

    match_max [expr 32 * 1024]

#If we see a message asking about the device's host key, accept it.

    interact -o -nobuffer -re "assword: $" return

    send "$pass\r"

# Loop through each command that we specified earlier.

    expect -re $prompt

    send "term len 0\r"

    expect -re $prompt

    foreach cmd $commands {

        send "$cmd\r"

        expect -re $prompt

        #remove zeros from the cmd filename

        regsub -all {[ \r\t\n]+} $cmd "" correct_cmd

        set output $expect_out(buffer)

        set fd [open /<path>/$file_name-$date-$correct_cmd.txt w]

        puts $fd $output

        close $fd

    }

    expect -re $prompt

    send "exit\r"

    exp_close -i $spawn_id

    exp_wait

}

Not sure why this is the case. Anyone can recommend a solution?

Thanks

Pantelis

10 Replies 10

Joe Clarke
Cisco Employee
Cisco Employee

Could it be that you need to fully-qualified path to ssh?  I'd think it would fail earlier, though.  You may want to re-enable user logging and exp_internal to see what expect is doing when run from within cron.

hI Joseph

I have already done that and the problem is below:

can't read "expect_out(buffer)": no such variable as per my initial post

Thanks

Pantelis

But if you enable more debugging, you will see the what is being sent/received to/from the device.  If this variable isn't being set, there is something with the match criteria.  What is the full output when you have log_user and exp_internal enabled?

Hi Joseph

Even after enabling log_user 1 I am still not able to get any errors (to be honest I am not getting the buffer error either this time ). The relevant config is :

I have also edited the crontab to output the file as per below:

Crontab is:

0 4 * * *          /usr/bin/expect  //

Can you try fully-qualifying the ssh path.  For example:

spawn /usr/bin/ssh x.x.x.x -l ****

It performs exactly the same but this time produces :

spawn /usr/bin/ssh x.x.x.x -l ****

Sorry then.  I'm out of ideas.  I'm not seeing the debug I'd expect.  Maybe there's a problem with your cron implementation.  Could also be an environment variable you need to set or not set...

Hello Pantelis,

You need to declare the whole of expect_out global rather than just one element.

Thank you!

Hi Maher

Could you please elaborate on this?

Thanks

Pantelis

Pantelis,

Use the curly braces to avoid substitution.

1. interacting with a program on your local machine:

#!/usr/bin/expect -d

spawn "/bin/bash"

send "term len 0\r"

expect -re eof

puts $expect_out(buffer)

2. interacting with a remote program over ssh:

!/usr/bin/expect -d

spawn ssh user@hostname

set prompt ":|#|\\\$"

interact -o -nobuffer -re $prompt return

send "mypassword\r"

interact -o -nobuffer -re $prompt return

send $cmd

send "exit\r"

expect eof

puts $expect_out(buffer)

Hope this helps

Regards!