cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
5232
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!

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: