Bashing Cisco – Fun with IOS.sh

Standard

Today we’re going to go over a little known shell in IOS that gives us some bash like functionality! It is called IOS.sh

Note: This is a IOS 15 feature.

We can enable this little known functionality with the terminal shell command, like the rest of the terminal commands this only enables IOS.sh for the current terminal session.

R1#terminal shell

If you want to have the shell enabled permanently with the following global command

R1(config)#shell processing full

R1#show terminal | in Shell
Shell: enabled
Shell trace: off

Now IOS.sh is enabled! Awesome! But what does it do?

The simple answer is it makes IOS more like a Linux shell, it allows us to create variables, make loops, and use some linux utilities like grep or wc on the shell.

Using GREP

One of the neatest features of IOS.sh is the ability to use the grep utility to filter output. Let’s start by looking at the manpage for Grep, yes there are manpages!

R1#man grep
NAME
grep - get regular expression

SYNOPSIS
grep [OPTIONS] <Regular Expression> [<file>...]

DESCRIPTION
The 'grep' command matches lines in the given files
with the supplied regular expression, and prints matching
lines. There are lots of options

-b - match everything in a file after pattern
-c - print a count of lines instead of matched lines
-e <pat> - use <pat> as the pattern (it may have a leading minus)
-h - do not print filename for each match (default)
-H - print filename for each match
-i - ignore case
-l - print only files with match
-L - print only files without match
-m - match everything in a matching mode
-n - print line numbers along with matches
-q - quiet, only set status
-s - supress printing errors
-u - match everything in a file until pattern
-v - invert match, print non-matching lines

Part of the power of this command is  because you can be more flexible than the standard include pipe command because you can do things like combine include and exclude like statements in the same line.

R1#show ip route | grep (150) | grep (10003)     
O        150.1.2.2 [110/10003] via 155.1.146.4, 15:51:41, GigabitEthernet1.146
O        150.1.3.3 [110/10003] via 155.1.146.4, 15:51:41, GigabitEthernet1.146
O IA     150.1.22.22 [110/10003] via 155.1.146.4, 1d11h, GigabitEthernet1.146

R1#show ip route | grep (150) | grep -v (10003)
      150.1.0.0/32 is subnetted, 11 subnets
C        150.1.1.1 is directly connected, Loopback0
O        150.1.4.4 [110/2] via 155.1.146.4, 15:51:57, GigabitEthernet1.146
O        150.1.5.5 [110/3] via 155.1.146.4, 15:51:57, GigabitEthernet1.146
O        150.1.6.6 [110/2] via 155.1.146.6, 1d12h, GigabitEthernet1.146
O IA     150.1.7.7 [110/3] via 155.1.146.6, 1d12h, GigabitEthernet1.146
O IA     150.1.8.8 [110/4] via 155.1.146.4, 15:52:07, GigabitEthernet1.146
O IA     150.1.9.9 [110/4] via 155.1.146.6, 1d12h, GigabitEthernet1.146
O IA     150.1.10.10 [110/5] via 155.1.146.4, 15:52:07, GigabitEthernet1.146

 

WC

WC can be used to count the number of things in the output.

R1#man wc
NAME
wc

SYNOPSIS
wc [OPTION]... [FILE]...

DESCRIPTION
Print newline, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. Read pipe input if no files are given
-c print the byte counts
-m print the character counts
-l print the newline counts
-L print the length of the longest line
-w print the word counts,

R1#show run | wc -l
216

Heads and Tails

These commands can be used to show the top x or bottom x lines of output, this can be handy with trying to see the latest logs.

R1#man head
NAME
head - print the first lines in the input

SYNOPSIS
head [<n>]

DESCRIPTION
The 'head' program will print the first lines in
its input. If given a numeric argument, it will
print that many lines. The default number of lines
is 10.
R1#man tail
NAME
tail - print the last lines in the input

SYNOPSIS
tail [<n>]

DESCRIPTION
The 'tail' program will print the last lines
in its input. If given a numeric argument, it
will print that many lines. The default number
of lines is 10.
R1#

R1#show run | head 10
Building configuration...

Current configuration : 2844 bytes
!
! Last configuration change at 18:14:38 UTC Tue Nov 17 2015
!
version 15.5
no service timestamps debug uptime
no service timestamps log uptime
no platform punt-keepalive disable-kernel-core

R1#show run | tail 10
exec-timeout 0 0
privilege level 15
logging synchronous
stopbits 1
line vty 0 4
privilege level 15
no login
!
!
end

CAT!

Ok fine, we can use the cat command to view text files on the Cisco device.

R1#man cat
NAME
cat - write files or standard input to output

SYNOPSIS
cat [<file>...]

DESCRIPTION
The cat command writes whatever it sees to its output

R1#copy running-config flash:cat.test
Destination filename [cat.test]?
2844 bytes copied in 0.463 secs (6143 bytes/sec)
R1#cat flash:cat.test

!
! Last configuration change at 18:14:38 UTC Tue Nov 17 2015
!
version 15.5
no service timestamps debug uptime
no service timestamps log uptime
no platform punt-keepalive disable-kernel-core
platform console serial

Variables

Lets start with making variables by first looking at the variables

R1#man variables
NAME
variables - describe the usage of variables

DESCRIPTION
Variables can be used in any context except single quotes. Variables
can either be named, or numbered parameters to functions. Setting a
named variable can be accomplished using an assignment statement.
Assignment statments have a specific form, which is that the name of
the variable must be immediately followed by an '=' sign. There can be
no whitespace between the name and the '=':

router> MYVAR='abc'

The right side of the assignment is any string, but can also be the
result of execution of a backquote expression, or the evaluation of a
variable expansion.

Variables may be used anywhere in subsequent input lines. One could,
for example, create a shortcut for an interface name, and use it in
config mode, or create a variable containing a number, and increment
its value using arithmetic expression syntax (see man expressions).

The main issue here is that the variable introduction character may
conflict with existing usages, and so must be escaped in situations
where a compatibility issue may arise. Please see man compatibility
for more information.

To make a variable you simply have to enter VariableName=VariableValue

R1#VAR1=Value1
R1#VAR2=Value2

We can view the contents with the echo command

R1#echo $VAR1 $VAR2
Value1 Value2

You can also use variables in your commands

R2#var1=150.1.4.4
R2#ping $var1 
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.4.4, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 71/100/167 ms

Conditions and Loops

Following comparison operators can be used for working with integer values:

Operators Characteristics
-eq ==
-ne !=
-lt <
-gt >
-ge >=
-le =<

For working with files following conditions are available:

Operator Characteristics
-a or –e True if file exists
-d True if file exist and it is a directory
-f True if file exists and is a regular file
-r True if file exists and is readable
-s True if file exists and has a size greater than zero
-w True if file exists and is executable
-nt Test if file1 is newer than file2. The modification date on the file is used for this comparison
-ot Test if file1 is older than file2

Loops are very powerful (and dangerous if you don’t terminate them correctly) tools that allow you to carry out complex tasks.

R1#for x in 1 2 3 4 5 6 7 8 9
do..done>do
do..done>ping 150.1.$x.$x
do..done>done
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.1.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 5/13/39 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.2.2, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 64/140/228 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.3.3, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 52/91/186 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.4.4, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 31/61/117 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.5.5, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 42/73/117 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.6.6, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 34/51/93 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.7.7, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 53/73/97 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.8.8, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 67/98/116 ms
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.9.9, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 78/98/122 ms

Functions

Lastly for this blog entry, you can define functions to make repeated tasks easier.

R1#function test-r1() {
{..} >ping 150.1.4.4
{..} >}
R1#
R4#test-r1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 150.1.5.5, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 26/39/63 ms

You can see the functions defined on the system with show shell function

R4#show shell functions 
#User defined functions:

Function namespace: DEFAULT
function test-r1() 
{
 ping 150.1.5.5
}

5 thoughts on “Bashing Cisco – Fun with IOS.sh

  1. Bavarian

    Wow, that’s amazing! I love Linux shell!
    Are all of the Cisco commands still working after activating IOS.sh?

  2. george elef

    this is good, but the commands have very limited functionality compared to real linux commands.
    in addition I have noticed a few problems
    VAR1=`sh run int gi0/0.1 | grep address`
    echo $VAR1
    ip
    it just stored the first word and not the whole sentence

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.