Monday, November 23, 2015

Cisco - Linux Commands on IOS


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

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 &lt;pat&gt; 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

R1#show ip route | grep 150 | grep -v 10003 | grep 6\.6
O 150.1.6.6 [110/2] via 155.1.146.6, 00:35:18, GigabitEthernet1.146
O IA 150.1.7.7 [110/3] via 155.1.146.6, 00:35:08, GigabitEthernet1.146
O IA 150.1.9.9 [110/4] via 155.1.146.6, 00:35:08, 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
    R1#function test-r1()
    {
     ping 150.1.5.5
    }

 

Taken From: