随着这几年网络运维自动化技术的大热,思科的ccie ei考试中已经纳入了有关python的笔试和实验试题。去年我写了一篇《网络工程师的python之路 — 思科ios-xe内置python及其内置cli模块》的专栏文章,向大家介绍了怎么在思科ios-xe设备中使用其内置的python以及思科自家造的第三方模块:cli。

虽然由于一些政策性的原因,思科在国内的江湖地位大不如前,但是在我几千名读者中依然不乏有在日常工作中和思科设备打交道,以及有想法准备出国闯荡准备重拾思科技术的,还有正在准备ccie ei考试的。今天就带大家回顾一下目前在思科接入层设备里比较主流的ios-xe操作系统,以及顺便介绍一个大多数曾经或者正在和思科设备打交道的读者们不知道的干货:如何在ios-xe设备上启用并输入linux命令,帮助我们配合python更好的完成平时一些运维自动化需求。

众所周知,作为思科大名鼎鼎的ios操作系统的继承者,思科的ios-xe操作系统诞生至今已经有13年的历史了。ios-xe最早是搭配在思科asr 1000系列的路由器和catalyst 3850系列的交换机上发布的,后续的catalyst 9200, 9300, 9400, 9500,9600交换机以及isr 1000, isr 4000, asr 920等系列的路由器都沿用了ios-xe这款操作系统。

搭载ios-xe操作系统的思科catalyst 9000系列交换机家族

ios-xe(下面简称xe)和ios最大的区别有如下几点:

  1. xe采用的是一种分布式的软件架构,这和ios操作系统完全不同。在ios年代,ios process是整个网络设备最最核心的进程,ios process总览大权掌控着一切,一旦ios process出问题,那整个设备的操作系统就此瘫痪。而在xe中,所有重要的系统进程都被隔离开来,ios process只是xe里12个重要进程中的一个。举个例子,假如logger这个进程出了问题,那它不会影响到ios process。另外xe还支持在一个rp上同时运行两个ios process。
  2. ios诞生于上世纪80年代初,那时甭说netconf,restconf这些api,就连python这个语言都还没诞生,什么json,xml, yaml, yang之类的更是天方夜谭,更没有什么思科自己研发的dna, sdwan,streaming telemetry,devnet toolkit等等,所以ios设备对netdevops的支持是相当差的,xe则解决了ios的这一痛点(好在思科的ios设备确实老而弥坚,经典耐用,至今在现网中依然到处能看到使用ios作为操作系统的思科设备的身影,这点从ntc-templates,netmiko,nornir,napalm等一些主流的netdevops第三方库和工具对ios的支持程度上就知道了)。
  3. 最重要也是本文要讨论的一点:xe是用linux开发的也就是说在xe设备上我们是能直接输入一些常见的linux命令的来完成一些我们需要通过python才能完成的任务,甚至还能直接在xe上做一些简单的shell编程!知道xe这个特点的用户有,但是因为linux shell在xe里不是默认开启的,并且思科本身也没有大肆宣传过(相关的中文资料就更是稀缺了),因此真正上手用过这一特性,知道它”香”的国内网工很少很少。注:linux shell在ios里也有,但是是从版本15才被引入的,老版里是没有的。

本文就来介绍一下如何在xe设备里启用linux shell,来看如何通过一些常见的linux命令以及shell编程来给我们平日的网络运维自动化增光添彩。

在ios-xe上启用linux shell

前面讲了,xe默认状态下linux shell是关闭的,要启用它很简单,这里我以一台思科catalyst 9300交换机为例,进入特权模式后,直接输入命令terminal shell即可:

terminal shell不是永久开启的,每次ssh登陆设备开启一个新的ssh会话后必须重新手动开启,如果你想永久开启的话需要做如下配置:

注意:永久开启shell比较占内存和cpu,请谨慎使用。

使用man手册命令

敢问当年入坑linux的网工谁没用过man来查阅和学习各种linux命令及其参数?比如这里我们要在xe设备上通过man命令来查询grep命令相关的信息和参数,直接man grep就行了:

使用grep做过滤

如果你问我最有代表性的linux命令是什么?那grep肯定榜上有名。玩过思科设备的都知道,思科最常见的过滤命令就是管道符后面配上include, exclude, begin, section等基于正则表达式的命令,但是你试过在思科设备上用grep来做过滤吗?

首先我们来看一下在没有开启linux shell情况下,使用grep会怎样:

不出意外,默认状态下我们是用不了grep的,接下来看下在开启linux shell后怎么样:

如果你是linux老手的话,肯定知道grep能实现很多include, exclude, begin, section做不到的功能,比如在一台路由器上通过grep给出多个条件来过滤ospf的路由前缀:

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.14

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

使用nl给回显内容添加行数

当年考过ccie的思科老手们都知道show run这个命令后面可以接一个linenum来查看回显内容总共有多少行,以防止被考官tr,如下:

不过遗憾的是,linenum这个命令只能接在show run后面,在其他常见的show ip int brief, show version, show logging等命令后面你是享受不了这个“福利”的:

现在我们开启了linux shell后,可以用nl(number of line的简写)来实现这个目的:

不要小看这个功能,它能配合grep来完成一些我们需要通过python才能实现的功能,比如说以上图的show version的回显内容为例,如果我们只想根据排数指定过滤出其中的某一排内容,这个时候你用传统的include, exclude, begin, section等过滤方法就很难做到,比如说我们想过滤出show version回显内容的第128排的内容,可以这么操作:

使用uname来快速查看设备的型号

uname这个常见的linux命令是干什么的大家都懂,在开启了linux shell的xe中,uname只会返回一个内容,即交换机的设备型号,通常来说,要查看思科设备的pid要输入show inventory这个命令,但是show inventory命令的回显内容很多,我们用python的话还要配合re来做一些过滤,而使用uname的话就省事多了,因为它只给你返回一个值,方便我们快速通过python脚本获取设备的型号:

使用wc来统计回显内容有多少字节,多少个换行符,多少个字母,多少个词汇等等等等

这里就不一一解释了,自己配合man来理解:

head和tail命令来过滤回显内容排数

比如这里我只想看到show run回显内容的前10排和最后10排:

shell编程

既然是shell,那是不是可以直接编程?当然可以。

对shell编程熟悉的一看就懂,不熟的但是有python功底的也应该都懂:

创建变量、变量赋值、调用变量:

for循环:

函数:

怎么样?强不强大?是不是可以替代部分python功能了?