Displaying full output from router commands

159 views
Skip to first unread message

danper...@gmail.com

unread,
Sep 11, 2016, 8:19:55 PM9/11/16
to Yet another Expect for Java
I am trying to find a way to automatically send a space-bar key-press when the router is trying to show more information. For example when I do the show run command you need to hit the space-bar to continue to display the configuration.

DAN-NV3448#sh run
Building configuration...
!
!
! ADTRAN, Inc. OS version R11.9.0
! Boot ROM version 13.03.00.SB
! Platform: NetVanta 3448, part number 1200821E1
! Serial number XXXXXXXXXXXXXXX
!
!
hostname "DAN-NV3448"
enable password encrypted 3c18893193ef1cc8bfa
!
!
clock timezone -5-Eastern-Time
!
ip subnet-zero
ip classless
ip routing
no ipv6 unicast-routing
!
!
name-server 8.8.8.8 8.8.4.4
!
--MORE—

This is easy to do by inserting expect.sendline(" "); Problem is I can't hard code how many sendline commands to send. Each time you send that command it will display 24ish more lines. This must be repeated until the whole configuration is displayed.

I need to find a way to detect when it says "--MORE--" and continue sending the spacebar command until its back at DAN-NV3448#

My objective here is to store the entire config in a string to parse through later.

Ideally the solution wouldn't be specific to show run because other commands can also require space-bar key-presses.

Alexey Gavrilov

unread,
Sep 12, 2016, 3:51:29 PM9/12/16
to danper...@gmail.com, Yet another Expect for Java
Hi,


Basically, with ‘interact' you can program sending the space char every time ‘MORE’ string occurs in the input stream and exit the loop when the command prompt is received. 
Something like:

            expect.interact()
                    .when(contains(“MORE")).then(r -> expect.sendLine(“ “))
                    .until(contains("DAN-NV3448"));

Hope it helps,
-Alexey

--
You received this message because you are subscribed to the Google Groups "Yet another Expect for Java" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-expecti...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

danper...@gmail.com

unread,
Sep 12, 2016, 4:38:45 PM9/12/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Hello Alexey,

Thank you for the quick reply. That does look like it would do exactly what I want. However when I try to put it into my Method, Eclipse throws an unhandled IOexception error. The method is set up to handle IOExceptions and I tried to surround with a try/catch but eclipse keeps suggesting to surround with a try/catch regardless.

I have only been coding for a few months so I do not have much experiance in handing these situations.

Here is my full Method if it helps. Please excuse the sloppy code.

public static List<String> SSHConnect(List<String> commands, String IPAddress, String Username, String Password, String EnablePassword) throws JSchException, IOException, InterruptedException {
StringBuilder wholeBuffer = new StringBuilder();
List<String> Responses = new ArrayList<String>();
JSch jSch = new JSch();

Session session = jSch.getSession(Username, IPAddress, 22);


session.setPassword(Password);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);

//Attempt to connect. if unable catch exception and return response
try {
session.connect();
} catch (JSchException e) {
Responses.add("# Unable to connect to: " + IPAddress + "\n" );
//e.printStackTrace();
String error = e.toString();
if(error.contains("Auth fail")){
Responses.add("# Incorrect Username or Password\n");
}
return Responses;

}
Channel channel = session.openChannel("shell");
channel.connect();

Expect expect = new ExpectBuilder()
.withOutput(channel.getOutputStream())
.withInputs(channel.getInputStream(), channel.getExtInputStream())
.withEchoInput(wholeBuffer)
.withEchoOutput(System.err)

.withInputFilters(removeColors(), removeNonPrintable())
.withExceptionOnFailure()
.build();
try {


expect.expect(contains("."));
expect.sendLine("sh run");

expect.interact()
.when(contains("MORE"))
.then(r -> expect.sendLine(" "))
.until(contains("#"));



commands.add("exit");
commands.add("exit");
commands.add("sh sip trunk reg");
commands.add("sh voice users");
commands.add("wr");
for(int i = 0; i < commands.size(); ++i){
expect.sendLine(commands.get(i));
}
//Thread.sleep(8500);

//expect.expect(allOf(regexp("xyz"), regexp("abc.*def")));;

String response = wholeBuffer.toString();

//Make sure the enable password was correct
if(response.contains("% Incorrect password")){
Responses.add("# Incorrect Enable mode password");
return Responses;
}


System.out.println("wholebuffer: ");
System.out.println(response);

String UserReg = "";
String TrunkReg = "";

int begin = response.indexOf("sh sip trunk reg");
int end = response.indexOf("Total Displayed");
if (begin > 1){
TrunkReg = response.substring(begin - 16, end + 19);
System.out.println(TrunkReg);
}

begin = response.indexOf("sh voice users");
end = response.indexOf("Total number of configured voice users:");
if (begin > 1){
UserReg = response.substring(begin - 16, end + 43);
System.out.println(UserReg);
}
Responses.add(TrunkReg);
Responses.add(UserReg);

//expect.expect(allOf(regexp("xyz"), regexp("abc.*def")));

return Responses;
//expect.expect(contains(">"));
//expect.expect(times(5, contains("\n")))

} finally {
expect.close();
channel.disconnect();
session.disconnect();
}
}
}

Alexey Gavrilov

unread,
Sep 12, 2016, 4:53:38 PM9/12/16
to danper...@gmail.com, Yet another Expect for Java
Right, that’s because of the current version API limitation. I’ll fix this in the next release.

The workaround is to catch a checked exception inside the lambda function:

> expect.interact()
> .when(contains("MORE"))
> .then(r -> expect.sendLine(" "))
> .until(contains("#"));

expect.interact()
.when(contains("MORE"))
.then(r -> {
try {
expect.sendLine(" ");
} catch (IOException e) {
throw new RuntimeException(e);
}
})
.until(contains("#"));

Alexey

danper...@gmail.com

unread,
Sep 12, 2016, 5:20:44 PM9/12/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Thank you very much. Your help is greatly appreciated. That took care of the exception issue. However I am still having issues getting this to work. I rearranged the code a bit. The execution doesn't seem to terminate on its own, so it looks like it is waiting.

expect.expect(contains("."));
expect.sendLine("en");
expect.sendLine(enablepassword);


expect.sendLine("sh run");
expect.interact()

.when(contains("--MORE--"))

.then(r -> {
try {
expect.sendLine(" ");
} catch (IOException e) {
throw new RuntimeException(e);
}
})

.until(contains("VoIPLab-TA916e#"));

It still sits there, with the System.out showing:

VoIPLab-TA916e#sh run
Building configuration...
!
!
! ADTRAN, Inc. OS version R11.10.0.E
! Boot ROM version 14.05.00.SA
! Platform: Total Access 916e (2nd Gen), part number 4242916L1
! Serial number SN
!
!
hostname "VoIPLab-TA916e"
enable password encrypted 272c6dbc90ad8c576186a407084


!
!
clock timezone -5-Eastern-Time
!
ip subnet-zero
ip classless
ip routing

ipv6 unicast-routing
!
!
name-server 8.8.8.8

!
--MORE--

Alexey Gavrilov

unread,
Sep 12, 2016, 5:31:04 PM9/12/16
to danper...@gmail.com, Yet another Expect for Java
I don’t see immediately anything wrong with the code. Will take a deeper look tomorrow.
I’d recommend to wait for the prompt before existing the shell script to ensure that the script has actually started before the interact loop.

In a meanwhile, you try to debug your code by adding more ‘when’ statements with different matchers and actions to print to console.

danper...@gmail.com

unread,
Sep 12, 2016, 5:42:22 PM9/12/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Thank you. Sure thing. I have tested with "!" and "--" and have not gotten any matches. I did just do the matchall regex and that found matches. If I can fix this my self I will let you know

expect.expect(contains("."));
expect.sendLine("en");
expect.sendLine(enablepassword);
expect.sendLine("sh run");

expect.interact()

.when(contains("."))
.then(r -> {
System.out.println("Match was found");
})
.until(contains("VoIPLab-TA916e"));


Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
Match was found
VoIPLab-TA916e>en
Password:


VoIPLab-TA916e#sh run
Building configuration...
!
!
! ADTRAN, Inc. OS version R11.10.0.E
! Boot ROM version 14.05.00.SA
! Platform: Total Access 916e (2nd Gen), part number 4242916L1
! Serial number SN
!
!
hostname "VoIPLab-TA916e"

enable password encrypted 272c6dbca407084

danper...@gmail.com

unread,
Sep 13, 2016, 9:19:24 AM9/13/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Another test case. I am still trying to get more familiar with debugging but my skills are limited to show statements for the most part.

expect.expect(contains("."));
expect.sendLine("en");
expect.sendLine(enablepassword);
expect.sendLine("sh run");
//Thread.sleep(1000);
expect.interact()
.when(contains("[a-zA-Z]+"))
.then(r -> {
try {
expect.sendLine(" ");
System.out.println("Space was sent");

} catch (IOException e) {
throw new RuntimeException(e);
}
})
.until(contains("#"));
Thread.sleep(1000);
System.out.println("-------------SECOND EXPECT----------------------");
expect.interact()
.when(contains("."))
.then(r -> {
try {
expect.sendLine(" ");
System.out.println("Space was sent");

} catch (IOException e) {
throw new RuntimeException(e);
}
})
.until(contains("#"));


Produced the following output. I used regex to replace any numbers. I wanted to show you the full output so you can see where it is stopping. The match all regex gets me the most but still stops once it reaches about 3/4 of the way through my running config. I get about 385 lines of output.

VoIPLab-TAXe>en
Password:
VoIPLab-TAXe#sh run
Building configuration...
!
!
! ADTRAN, Inc. OS version RX.X.X.E
! Boot ROM version X.X.X.SA
! Platform: Total Access Xe (Xnd Gen), part number XLX
! Serial number CFGX
!
!
hostname "VoIPLab-TAXe"
enable password encrypted XcXdbcXaXfXaXadXcXaX
!
!
clock timezone -X-Eastern-Time
!
ip subnet-zero
ip classless
ip routing
ipvX unicast-routing
!
!
name-server X.X.X.X X.X.X.X X.X.X.X
!
--MORE---------------SECOND EXPECT----------------------

Space was sent

Space was sent

Space was sent
Space was sent


Space was sent

Space was sent

Space was sent

Space was sent

Space was sent

Space was sent

Space was sent

Space was sent

Space was sent

Space was sent
!
no auto-config
auto-config authname adtran encrypted password XbXdXddXaXaaXcXfcXceXeXeX
!
event-history on
no logging forwarding
no logging email
!
service password-encryption
!
username "XXXXXX" password encrypted "XfXcXcXbXdXdbdXcdX"
!
banner motd %
####################################################################################
NOTICE: Check with VoIPIT before making any changes to this device!

--MORE--
MANAGEMENT --X.X.X.X

####################################################################################
%
!
!
ip firewall
no ip firewall alg ftp
no ip firewall alg msn
no ip firewall alg mszone
no ip firewall alg pptp
no ip firewall alg irc
no ip firewall alg hX
no ip firewall alg rtsp
!
!
!
--MORE-- !
!
!
!
!
no dotXap access-point-control
!
!
!
!
!
!
ip dhcp excluded-address X.X.X.X X.X.X.X
ip dhcp excluded-address X.X.X.X X.X.X.X
ip dhcp excluded-address X.X.X.X X.X.X.X
!
ip dhcp pool "DATA"
network X.X.X.X X.X.X.X
dns-server X.X.X.X X.X.X.X X.X.X.X
default-router X.X.X.X
lease X
option X ascii PHONE_CONFIG_LINK
option X ascii PHONE_CONFIG_LINK
--MORE-- !
ip dhcp pool "VOICE"
network X.X.X.X X.X.X.X
dns-server X.X.X.X X.X.X.X X.X.X.X
default-router X.X.X.X
lease X
option X ascii PHONE_CONFIG_LINK
option X ascii PHONE_CONFIG_LINK
!
ip dhcp pool "LABVOICE"
network X.X.X.X X.X.X.X
dns-server X.X.X.X X.X.X.X X.X.X.X
default-router X.X.X.X
lease X
ntp-server X.X.X.X
option X ascii PHONE_CONFIG_LINK
option X ascii PHONE_CONFIG_LINK
!
!
!
!
!
!
--MORE-- !
!
!
!
!
qos map VOIP X
match dscp ef
priority percent X
qos map VOIP X
match dscp afX csX
set dscp csX
qos map VOIP X
match any
set dscp default
!
!
!
!
interface loop X
description // PUBLIC LOOPBACK IP //
ip address X.X.X.X X.X.X.X
no shutdown
!
--MORE-- interface eth X/X
no ip address
shutdown
!
!
interface eth X/X
description // PHYSICAL CONNECTION TO NVXP SWITCH //
encapsulation X.Xq
no shutdown
!
interface eth X/X.X
description // DATA VLAN //
vlan-id X
ip address X.X.X.X X.X.X.X
ip access-policy DATA
no shutdown
interface eth X/X.X
description // VOICE VLAN //
vlan-id X
ip address X.X.X.X X.X.X.X
ip access-policy VOICE
media-gateway ip primary
no shutdown
--MORE-- interface eth X/X.X
description // LABVOICE VLAN //
vlan-id X
ip address X.X.X.X X.X.X.X
ip access-policy LABVOICE
media-gateway ip primary
no shutdown
interface eth X/X.X
description // SWITCH MANAGEMENT VLAN //
vlan-id X
ip address X.X.X.X X.X.X.X
no shutdown
!
!
!
interface tX X/X
--MORE-- description // PHYSICAL WAN //
tdm-group X timeslots X-X speed X
no shutdown
!
interface tX X/X
tdm-group X timeslots X-X,X speed X
shutdown
!
interface tX X/X
tdm-group X timeslots X-X speed X
shutdown
!
interface tX X/X
tdm-group X timeslots X-X speed X
shutdown
!
!
interface pri X
shutdown
!
!
interface fxs X/X
description "X"
--MORE-- no shutdown
!
interface fxs X/X
description "X"
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
--MORE-- !
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
no shutdown
!
interface fxs X/X
--MORE-- no shutdown
!
!
interface fxo X/X
no shutdown
!
!
interface fr X point-to-point
frame-relay lmi-type ansi
no shutdown
cross-connect X tX X/X X frame-relay X
!
interface fr X.X point-to-point
frame-relay interface-dlci X
snmp trap link-status
no ip address
!
interface ppp X
description // PPP //
ip address negotiated
ip access-group BLOCK-BADDIES in
media-gateway ip loopback X
no fair-queue
--MORE-- ppp chap hostname X
ppp chap password encrypted XdXX
no shutdown
!
!
isdn-group X
!
!
!
!
timing-source tX X/X
!
router ospf X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
network X.X.X.X X.X.X.X area X
!
!
--MORE-- !
!
ip access-list standard CPEAccess
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit X.X.X.X X.X.X.X
permit host X.X.X.X
permit host X.X.X.X
deny any
!
!
ip access-list extended BLOCK-BADDIES
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
--MORE--
Space was sent

Space was sent
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
deny ip host X.X.X.X X.X.X.X X.X.X.X
permit ip any any
!
ip access-list extended XDATA
permit ip X.X.X.X X.X.X.X any
!
ip access-list extended XPHONES
permit ip X.X.X.X X.X.X.X any
!
ip access-list extended XVOIP
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
--MORE-- permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
permit ip any X.X.X.X X.X.X.X
!
ip access-list extended LABXPHONES
permit ip X.X.X.X X.X.X.X any
!
ip access-list extended self
permit ip any any
!
!
!
!
ip policy-class DATA
nat source list XDATA interface loop X overload
discard list MatchAll
!
ip policy-class LABVOICE
nat source list LABXPHONES interface loop X overload
discard list MatchAll
!
--MORE--



Alexey Gavrilov

unread,
Sep 13, 2016, 5:08:29 PM9/13/16
to danper...@gmail.com, Yet another Expect for Java
Note that contains(<string>) is for plain string matching, for regular expressions you should use regexp(<pattern>) or matches(<pattern>). Check javadoc for difference.

> .when(contains("[a-zA-Z]+"))
So that would never work.

I suggest you to check if you can make it work by matching ‘MORE’ string several times. Something like:

expect.expect(contains(“#”));
expect.sendLine(“sh run”)
expect.expect(contains(“MORE”))
… // repeat several times
expect.expect(contains(“MORE”))
// exit
expect.expect(contains(“#”))

Then it should be easier to make the same thing work with interact.

tc1...@gmail.com

unread,
Sep 13, 2016, 10:29:55 PM9/13/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
I'm attempting to use this library for very similar things and am wondering why you don't initially send "term length 0" when you initially connect to the device? with paging tuned off wont that remove all the MORE lines? you can then just collect the whole config and parse.

danper...@gmail.com

unread,
Sep 14, 2016, 8:45:03 AM9/14/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
I am not sure what you mean by "term length 0" I basically have no idea what I am doing and try different things until they work. I was able to accomplish my goal. I do pretty much what you said and throw it all into a string and return it to a parent function for parsing. All I had to do was add a second seondline and a short wait timer to give the stringbuilder time to get everything together. Without the wait I wasn't getting all the output.

expect.sendLine("en");
expect.sendLine(EnablePassword);
expect.sendLine("sh run");


//INTERACT EXAMPLE
expect.interact()
.when(contains("."))
.then(r -> {
try {
expect.sendLine(" ");
expect.sendLine(" ");

} catch (IOException e) {
throw new RuntimeException(e);
}
})
.until(contains("VoIPLab-TA916e"));

expect.expect(contains("#"));

Thread.sleep(3800);

danper...@gmail.com

unread,
Sep 14, 2016, 9:10:21 AM9/14/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com

Alexey,

Thank you for your guidance on this. I was able to get this to work thanks to your explanation.

For whatever reason I could not get expect.expect(contains("MORE")); to accurately trigger

Using regexp to match string works perfectly

expect.interact()
.when(regexp("\\bMORE\\b"))

.then(r -> {
try {
expect.sendLine(" ");

//expect.sendLine(" ");


} catch (IOException e) {
throw new RuntimeException(e);
}
})

.until(regexp("\\bend\\b"));

Thomas Campion

unread,
Sep 14, 2016, 10:03:44 AM9/14/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
if you expect.sendLine("term length 0"); just before you do the sho run command paging on the device you're connecting to will be turned off. You will no longer get "--MORE--" in the output. The "sho run" command will retrieve all of the output without any terminal page break. That --MORE-- you're seeing is the device sending a page break so the output doesn't scroll off your screen. Most network devices have paging in one form or another, and most have a command for turning it off.

Alexey Gavrilov

unread,
Sep 14, 2016, 3:22:15 PM9/14/16
to danper...@gmail.com, Yet another Expect for Java
> .when(regexp("\\bMORE\\b"))

Before and after MORE can be special non-printable characters. Does it work with just MORE ?

Thomas Campion

unread,
Sep 14, 2016, 3:53:54 PM9/14/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
I can tell you from my experience more/MORE can exist in network device config and cause false positive match for regex. I encourage following my earlier post and disable output paging on the device (send an initial "term len 0"). The full command is "terminal length 0" and sets paging on device to be deactivated. You could use a number other than 0 to get page breaks and whatever the number of lines you specify. If you set it to 0 and do your show run command and capture and parse everything once you get device prompt back. You will not have to worry about the (MORE) paging prompt at all because it will not be there.

danper...@gmail.com

unread,
Sep 15, 2016, 11:23:26 AM9/15/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Thomas,

Thank you. I have thrown that command and everything now works flawlessly.

Alexey,

I have not had any issues with the regex MORE matching. It correctly disengages the interact loop when "end" is observed. The method I created is only for show run and I haven't tested how it would respond if I was doing more than just a show run

Thomas Campion

unread,
Sep 15, 2016, 12:13:42 PM9/15/16
to Yet another Expect for Java, danper...@gmail.com, Alexey1....@gmail.com
Glad I could help!
Reply all
Reply to author
Forward
0 new messages