-
Notifications
You must be signed in to change notification settings - Fork 97
Expand file tree
/
Copy pathwatch.py
More file actions
152 lines (132 loc) · 5.47 KB
/
watch.py
File metadata and controls
152 lines (132 loc) · 5.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# watch.py
# usage: watch.py [-h] [-c COUNT] [-i INTERVAL] [-d] command
#
# This script displays the output of a specified CLI command every n seconds
# Example "run script watch.py "show port packet no-ref""
#
# positional arguments:
# command Command to iterate. Should be enclosed in quotes (i.e.
# "show l2stats vlan Mgmt")
#
# optional arguments:
# -h, --help show this help message and exit
# -c COUNT, --count COUNT
# Number of times to issue the command (default 3)
# -i INTERVAL, --interval INTERVAL
# Wait time between command iterations (default 5 sec)
# -d, --diff If numerical values have changed in an ouput print
# difference between previous and current command
# iteration
# Last updated: March 31, 2016
import argparse
import shlex
from exsh import clicmd
from time import sleep
import sys
import re
import signal
class ArgParser(argparse.ArgumentParser):
def error(self, message):
sys.stderr.write('error: %s\n' % message)
self.print_help()
sys.exit(2)
def try_cli(command):
"""Try CLI command and exit if invalid"""
try:
return clicmd(command, True)
except:
print 'Script Error: Check Command Syntax'
exit()
def version_check():
pimage = True
sh_switch = clicmd('show switch', True)
ver = ''
if 'Image Selected: secondary' in sh_switch:
pimage = False
sh_switch = sh_switch.splitlines()
for line in sh_switch:
if (pimage and ('Primary ver:' in line)) or (not pimage and ('Secondary ver:' in line)):
ver = line.split(':')
ver = ver[1].strip()
if ver == '':
print FMT_ERROR.format('Problem detecting software version')
exit()
elif ver.startswith('15.6') or ver.startswith('15.7'):
return True
else:
return False
def main():
parser = ArgParser(prog='watch.py', description = "This script displays the output of a "
"specified CLI command every n seconds "
"Example \"run script watch.py \"show port "
"packet no-ref\"\"")
parser.add_argument("command", help="Command to iterate. Should be enclosed in quotes "
"(i.e. \"show l2stats vlan Mgmt\")")
parser.add_argument('-c', '--count', help='Number of times to issue the command (default 3)', type=int, default=3)
parser.add_argument('-i', '--interval', help='Wait time between command iterations (default 5 sec)', type=int,
default=5)
parser.add_argument('-d', '--diff', help='If numerical values have changed in an ouput print difference between '
'previous and current command iteration', action="store_true")
args = parser.parse_args()
cmd = args.command
count = args.count
interval = args.interval
stat_diff = args.diff
cli_refresh = True
legacy_version = version_check()
# Create and register a hanlder for SIGINT so we handle ^C cleanly
def signal_handler(signal, frame):
if cli_refresh and not legacy_version:
# renable cli refresh, if we disabled it previously
clicmd('enable cli refresh')
sys.stdout.flush()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
# Handle Auto-refreshing Commands
if legacy_version:
print 'WARNING: Switch is running pre 16.1 code. Please be sure to not use auto-refreshing commands\n'
else:
# Check to see if cli refresh is disabled
cli_out = clicmd('show management | include "CLI refresh"', True)
if 'Disabled' in cli_out:
cli_refresh = False
if cli_refresh:
# Temporarily disable refreshing CLI commands to prevent script from hanging
clicmd('disable cli refresh')
if stat_diff:
prev_output = try_cli(cmd)
print prev_output
count -=1
prev_output = prev_output.split('\n')
while count != 0:
sleep(interval)
curr_output = try_cli(cmd).split('\n')
for index in range(len(prev_output)):
# Split current and prev command outputs into list divided based on numerical and non-numerical strings
prev = re.split(r'(\d+)', prev_output[index])
curr = re.split(r'(\d+)', curr_output[index])
for i in range(len(prev)):
if prev[i].isdigit() and curr[i] > prev[i]:
diff = int(curr[i]) - int(prev[i])
diff = '+' + str(diff)
FMT = '{0:>' + str(len(curr[i])) + '}'
sys.stdout.write(FMT.format(diff))
else:
sys.stdout.write(prev[i])
sys.stdout.flush()
print
count -= 1
prev_output = curr_output
else:
for i in range(count):
print try_cli(cmd)
sleep(interval)
if cli_refresh and not legacy_version:
# Restore CLI refresh
clicmd('enable cli refresh')
if __name__ == '__main__':
try:
main()
except SystemExit:
# catch SystemExit to prevent EXOS shell from exiting to the login prompt
pass