1

I am making an expect script to check memory usage and can only proceed to the next steps if the mem usage is less than 65%.

#!/usr/bin/expect -f
spawn telnet $serverip
send "show performance\r"
expect {
    timeout { send_user "\nCPU Usage is too high.\n";exit 1}
    "0-65%" # i need to expect 0-65%
    }

then proceed to other commands.

output is :

CPU used MEM used  RX(Kbps)  TX(Kbps)  RX(Kbps)  TX(Kbps)
1.0%    51.2%      0.000     0.000     1.620     2.426

i need to make sure that mem used is less than 65%. How can i do this in EXPECT SCRIPT?

Thanks for the help. Its been killing me.

Avinash Raj
  • 172,303
  • 28
  • 230
  • 274

1 Answers1

0

You have to use regular expression in the expect itself with the help of -re flag.

There can be two ways to get this done.

  1. Match all the show performance command output till the prompt and then apply the tcl's legacy regexp in that output

  2. Match only the required value (i.e. the mem used % value) alone directly.

I assume your device's prompt will be #. But, there are some devices whose prompt may vary. So, in order to handle this, we can come up with generalized prompt pattern as

set prompt "#|>|\\\$";

If your device's prompt is not available in this, then please include the same.

#!/usr/bin/expect -f

#This is a common approach for few known prompts
#If your device's prompt is missing here, then you can add the same.
set prompt "#|>|\\\$"; # We escaped the `$` symbol with backslash to match literal '$'

spawn telnet $serverip

# Add code for login here

expect -re $prompt;  # Using '-re' flag here to match one one of the prompt.    

# Your some other code here to something if any

# This is to clean up the previous expect_out(buffer) content
# So that, we can get the exact output what we need.
expect *;    

send "show performance\r"; # '\r' used here to type 'return' .i.e new line
expect -re $prompt; # Matching the prompt with regexp

#Now, the content of 'expect_out(buffer)' has what we need
set output $expect_out(buffer);

# Applying the tcl's regexp here
if {[regexp {%\s+([^%]+)} $output ignore mem]} {
    puts "Memory used : $mem"
}

I have used the pattern as {%\s+([^%]+)}. In your output, we have 2 percentage symbols. The first one corresponds to the CPU used and second one is for the memory used. So, basically I am trying to match the text % 51.2%

Let me decode the pattern.

% - to match the first percentage sign

\s+ - to match the more than one spaces.

[^%]+ - Match anything other than % (This is where we are getting the required value i.e. the value 51.2)

Then what is the need of parenthesis here ? Well ,that is for grouping. Expect will save the matched output into expect_out(0,string). For the nth sub match, it will be saved on expect_out(n, string). i.e. For 1st sub match expect_out(1,string) and for 2nd sub match expect_out(2,string) and so on. Expect will store all the matched and unmatched input to a variable called expect_out(buffer). So, that is the short story. One more thing might bother you. What is this expect *` doing here ? You can have a look at here to know more about the same.

That's all about the 1st way. Now, what about the second approach which I have described above ? That is bit more easy.

send "show performance\r"; 
expect {
        -re {%\s+([^%]+)} { set mem $expect_out(1,string); puts "Memory used : $mem" }
        timeout { puts timeout_happened }
}

This looks more comfortable and no need of applying separate regexp additionally. That is one advantage of it. You can use whichever you find it comfortable and whichever is much needed as per your requirement.

Once your get the value, you can simply compare it with a if loop if it is less than 65%.

Community
  • 1
  • 1
Dinesh
  • 16,014
  • 23
  • 80
  • 122