VanDyke Software Forums

VanDyke Software Forums (https://forums.vandyke.com/index.php)
-   Scripting (https://forums.vandyke.com/forumdisplay.php?f=14)
-   -   Wait for string then copy string (https://forums.vandyke.com/showthread.php?t=12039)

e2script 07-15-2015 01:23 AM

Wait for string then copy string
 
Hi,

I wonder what's the easiest way of creating a script that does the following:

1. Script runs a command that I specify in the script.
2. Host returns a string that looks like this: <number>:<number> <word that varies in number of digits> VL_<four digit number>_xxxxxxxx <letter> <letter> <number> <word>
3. Script understands that what we're looking for is the 4 digit number marked in bold above.
4. Script runs a new command that I specify based on that number. ex. sh vlan id <four digit number>

The word VL_ will always be put in front of the 4 digit number.

What's the best way to make a script like this?

Best regards,
e2script

rtb 07-15-2015 03:41 PM

Hi e2script,

You could use the script recorder to get the foundation of the script where you send a command. Then you would need to add your code for capturing the output of the command, parsing the data that is returned and sending the new command.

Some general concepts for parsing data can be found in the following thread:
https://forums.vandyke.com/showthread.php?t=11943

e2script 07-24-2015 08:54 AM

Hi Todd,

I have started working on a script now based on something that I found here.

My script looks like this:
Code:

#$language = "VBScript"
#$interface = "1.0"

crt.Screen.Synchronous = True

ClipText = crt.Clipboard.Text
Command = "sh port " & ClipText & " no | i " & ClipText

crt.Screen.Send Command & vbcr
crt.Screen.WaitForString vbcr
strResult = crt.Screen.ReadString(vbcrlf)

The information placed on the clipboard will be a port number so that when the script is run the command that will be sent is the following:
sh port <port number> no | i <port number>
Ex. sh port 1:71 no | i 1:71

The output the router will give me based on the command sh port 1:71 no | i 1:71 is 1:71 11001101_jdhasddVL_1111_11001101 E A 1000 FULL
The output the router will give me based on the command sh port 1:72 no | i 1:72 is 1:72 44551144_gnitsetVL_0001_44551144 E R
The output the router will give me based on the command sh port 1:73 no | i 1:73 is 1:73 98984477_dfegeerVL_8473_98984477 D R

Now the thing that I'm after is the 4digit numbers; 1111, 0001 and 8473.

The next command the script will then run is (not fixed in the script above because this is what I'm struggling with):
sh fdb VL_<4digit number found in the previous output from the router>
Ex. sh fdb VL_1111

How can I achieve this?

jdev 07-24-2015 04:37 PM

I'd use a regular expression, since the data you want seems to follow the pattern of VL_\d+_.
In the pattern above, \d+ means one or more digits

For example, since you have read the line of output into a strResults var...

Code:

' One example of your output - hardcoded for testing only
strResults = "1:73 98984477_dfegeerVL_8473_98984477 D R"

Set re = new RegExp
re.IgnoreCase = False
re.Pattern = "(VL_\d+)_"
'              |____|
'                ||
'  Data that matches pattern between
'  1st set of ()s will be known as:
'  ...Submatches(0)


If Not re.Test(strResults) Then
    crt.Dialog.MessageBox _
        "Pattern '" & re.Pattern & "' wasn't found: " & _
        vbcrlf & vbcrlf & strResults
    crt.Screen.SendSpecial("MENU_SCRIPT_CANCEL")
Else
    Set objMatches = re.Execute(strResults)
    strDataWeAreAfter = objMatches(0).Submatches(0)
    crt.Dialog.MessageBox "Here's what we extracted: " & strDataWeAreAfter
    '...
End If


More information about regular expressions can be found in the SecureCRT scripting guide (see chapter 4.3's sub-section titled, "Extracting Specific Information"), as well as in the MS VBScript documentation for the Regular Expression Object.

--Jake

e2script 07-28-2015 01:53 AM

Hi,

I tried the script you posted and it works perfect when strResult is hardcoded.
However I have a problem using the script when strResult isn't hardcoded.

This is the script I'm running now:
Code:

#$language = "VBScript"
#$interface = "1.0"

crt.Screen.Synchronous = True

ClipText = crt.Clipboard.Text
Command_show_port_no = "sh port " & ClipText & " no | i " & ClipText

crt.Screen.Send Command_show_port_no  & vbcr
crt.Screen.WaitForString vbcr
strResult = crt.Screen.ReadString(vbcrlf)

Set re = new RegExp
re.IgnoreCase = False
re.Pattern = "(VL_\d+)_"
'              |____|
'                ||
'  Data that matches pattern between
'  1st set of ()s will be known as:
'  ...Submatches(0)


If Not re.Test(strResults) Then
    crt.Dialog.MessageBox _
        "Pattern '" & re.Pattern & "' wasn't found: " & _
        vbcrlf & vbcrlf & strResults
    crt.Screen.SendSpecial("MENU_SCRIPT_CANCEL")
Else
    Set objMatches = re.Execute(strResults)
    strDataWeAreAfter = objMatches(0).Submatches(0)       
    crt.Dialog.MessageBox "Here's what we extracted: " & strDataWeAreAfter
    '...
End If

The script only gives me the error message "Pattern 'VL_\d+)_' wasn't found".
Can you please advise me on this?

jdev 08-03-2015 11:36 AM

You're issuing a command...
crt.Screen.Send Command_show_port_no & vbcr

...then waiting for the CR you sent to be echo'd back...
crt.Screen.WaitForString vbcr

...then reading all the data that appears/arrives up until the next CRLF that SecureCRT receives...
strResult = crt.Screen.ReadString(vbcrlf)

What follows afterwards is the regular expression testing on the data returned by ReadString().

The regexp test is saying that the pattern 'VL_\d+)_' isn't found in the results returned by ReadString().

You'll need to do some digging and investigation to find out where to go next.

Consider enabling raw logging to a file in SecureCRT before running the script. Then run the script. Once you see the message appear telling you that no matches were found, go look at the raw log file SecureCRT created. If you use a capable editor, you'll be able to see exactly what is being returned by the remote system after you run the command. You'll need to then adjust either what you're waiting for, or what you're telling ReadString() to trigger on, or both.

Also, if what you shared earlier (as examples of the output of the command) isn't accurate, the pattern you're trying to match/test on may need to be edited to match what is actually being returned.

e2script 01-13-2016 11:02 AM

I've put this thing on hold for a while, but now I'm ready to go back at it.

I've tried running the script again and this is the output from the terminal:
Quote:

aa1.ibli.2 # sh port 4 no | i 4
4 99999999_nom_praVL_1515_99999999 E A 1000 FULL
aa1.ibli.2 #
The script just says "Pattern '(VL_\d+)_' wasn't found:".

I tried changing the re.Pattern from re.Pattern = "(VL_\d+)_" to re.Pattern = "1515" to see if it would make any difference.
It doesn't work. I still receive the "Pattern '(VL_\d+)_' wasn't found:".-message.

Please help :)

jdev 01-13-2016 12:35 PM

Quote:

Originally Posted by e2script (Post 45061)
I tried changing the re.Pattern from re.Pattern = "(VL_\d+)_" to re.Pattern = "1515" to see if it would make any difference.
It doesn't work. I still receive the "Pattern '(VL_\d+)_' wasn't found:".-message.

If you still see that literal message, then the code you wrote to try and change re.Pattern's value didn't get put in the right place (or is getting undone somewhere else in your code).

Look for all the places where you're doing 're.Pattern = '... and make sure that between that line and the latter line on which you're testing the pattern, there aren't any additional 're.Pattern = '... statements undoing your change.

Also, you will likely need to introduce some MsgBox statements to show you what's currently in strResults... What's actually in there might not be what you expect, in which case you would need to perform more code inspection along with actual output from the remote to find out where your code is going wrong.

--Jake

jdev 01-13-2016 12:49 PM

Also, did you use a raw log as I suggested earlier?

It will help you better understand what's happening as data is sent from the remote device to SecureCRT.

Having a better understanding of the data that is being sent from the remote device to SecureCRT will help you know what your code should look like based on what you expect/know is coming from the remote.

--Jake

e2script 01-14-2016 07:13 AM

Quote:

Originally Posted by jdev (Post 45064)
If you still see that literal message, then the code you wrote to try and change re.Pattern's value didn't get put in the right place (or is getting undone somewhere else in your code).

Look for all the places where you're doing 're.Pattern = '... and make sure that between that line and the latter line on which you're testing the pattern, there aren't any additional 're.Pattern = '... statements undoing your change.

I'm using the excat code presented in post #5.
I've looked through the code and there's only one place where 're.Pattern = ' is present.

Quote:

Originally Posted by jdev (Post 45064)
Also, you will likely need to introduce some MsgBox statements to show you what's currently in strResults... What's actually in there might not be what you expect, in which case you would need to perform more code inspection along with actual output from the remote to find out where your code is going wrong.

--Jake

I'll try that.
Thanks for the suggestion.

Quote:

Originally Posted by jdev (Post 45065)
Also, did you use a raw log as I suggested earlier?

It will help you better understand what's happening as data is sent from the remote device to SecureCRT.

Having a better understanding of the data that is being sent from the remote device to SecureCRT will help you know what your code should look like based on what you expect/know is coming from the remote.

--Jake

I already have logging enabled.
I tried checking the box for "Raw log" under "Log File" in "Session Options"; couldn't see any difference on the data sent from the remote device to SecureCRT.

e2script 01-14-2016 07:21 AM

-----

I added this in the script:

crt.Dialog.MessageBox _
"This was returned by the remote deivce:" & strResults


The message returned in SecureCRT when I run the script is this.

Quote:

This was returned by the remote deivce:
So to me it doesn't look like the script is able to pull the data returned by the remote device.

rtb 01-14-2016 11:51 AM

Hi e2script,

Since your code is not capturing any data from the remote, you are going to need to investigate why.

If you aren't seeing any difference between the data in the raw log versus a regular log, the program you are using to view the contents of the files may not be able to or configured to display non-printing characters.

Ultimately, you are going to have to view the raw log in an editor that can display non-printing characters (including line ending characters). When you can see the non-printing characters, you will need to modify your script to match what you are seeing in the raw log.

e2script 01-15-2016 05:28 AM

Quote:

Originally Posted by rtb (Post 45069)
Hi e2script,

Since your code is not capturing any data from the remote, you are going to need to investigate why.

If you aren't seeing any difference between the data in the raw log versus a regular log, the program you are using to view the contents of the files may not be able to or configured to display non-printing characters.

Ultimately, you are going to have to view the raw log in an editor that can display non-printing characters (including line ending characters). When you can see the non-printing characters, you will need to modify your script to match what you are seeing in the raw log.

Hi,

I tried putting the raw log in Notepad++.
I can then see that there's 3 line breaks between the send command and the data received from the remote device.

So it looks like this:

aa1.ibli.2 # sh port 4 no | i 4



4 99999999_nom_praVL_1515_99999999 E A 1000 FULL
aa1.ibli.2 #


How can I fix the script so that it will search for 're.Pattern = ' in the 3rd line?

jdev 01-15-2016 11:05 AM

Since your output is several lines down, you'll need to write your script code to capture data beyond the first CRLF that appears.
This isn't any more complicated than telling ReadString() to capture up to your shell prompt, rather than only capturing data received up to the first CRLF it sees.

If you tell ReadString() to read up to your shell prompt, you'll get everything (not only the empty lines, but also the actual output you care about) placed into the strResults variable. The regular expression will then have the data to match against your pattern when re.Test(strResults) is called.

--Jake

e2script 01-18-2016 03:06 AM

Quote:

Originally Posted by jdev (Post 45072)
Since your output is several lines down, you'll need to write your script code to capture data beyond the first CRLF that appears.
This isn't any more complicated than telling ReadString() to capture up to your shell prompt, rather than only capturing data received up to the first CRLF it sees.

Can you explain more in detail how I go about fixing this?
I'm not experienced with visual basic scripting or scripting in general.


All times are GMT -6. The time now is 03:57 AM.