.\" Automatically generated by Pod::Man 4.09 (Pod::Simple 3.35) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .if !\nF .nr F 0 .if \nF>0 \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} .\} .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Net::CLI::Interact::Manual::Cookbook 3pm" .TH Net::CLI::Interact::Manual::Cookbook 3pm "2017-11-08" "perl v5.26.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Net::CLI::Interact::Manual::Cookbook \- Miscellaneous recipes .SH "Windows Support" .IX Header "Windows Support" The library works just fine under native windows (i.e use something like Strawberry Perl \- no need for cygwin), for Telnet, Serial and \s-1SSH\s0 connections. However one additional step is required for you to have success: .PP You \fBmust\fR download the \f(CW\*(C`plink.exe\*(C'\fR application, and pass its filesystem location in the \f(CW\*(C`app\*(C'\fR parameter to \f(CW\*(C`new()\*(C'\fR. Do not try to use any other Telnet or \s-1SSH\s0 programs (for instance the Windows bundled \f(CW\*(C`telnet\*(C'\fR) \- they \&\fIwill not work\fR. Here's an example, if \f(CW\*(C`plink.exe\*(C'\fR is on your Desktop: .PP .Vb 6 \& my $s = Net::CLI::Interact\->new( \& personality => "cisco", \& transport => "Telnet", \& (Net::CLI::Interact::Transport::is_win32() ? \& (app => "$ENV{HOMEPATH}\e\eDesktop\e\eplink.exe") : () ), \& ); .Ve .SH "Unix Support" .IX Header "Unix Support" The library works fine on most Unix platforms. It will try to use the native \&\f(CW\*(C`telnet\*(C'\fR, \f(CW\*(C`ssh\*(C'\fR (openssh) and \f(CW\*(C`cu\*(C'\fR programs for Telnet, \s-1SSH\s0 and Serial connections, respectively. If you want to use another application, pass it in the \f(CW\*(C`app\*(C'\fR parameter to \f(CW\*(C`new\*(C'\fR. .PP In some Unix environments there can be zombie child processes left around after running your script. If this happens, set the \f(CW\*(C`reap\*(C'\fR option, like so: .PP .Vb 7 \& my $s = Net::CLI::Interact\->new( \& personality => "cisco", \& transport => "Telnet", \& connect_options => { \& reap => 1, \& }, \& ); .Ve .SH "Running Commands" .IX Header "Running Commands" .SS "Simple Commands" .IX Subsection "Simple Commands" Simply send the command you wish to execute to the session. If not already done, a connection to the device will be established automatically: .PP .Vb 1 \& $s\->cmd(\*(Aqshow ip int br\*(Aq); .Ve .PP Normally this matches against a default prompt, which has been discovered automatically, or set by you: .PP .Vb 1 \& $s\->set_prompt(\*(Aquser_prompt\*(Aq); .Ve .PP It's also possible to pass in a custom prompt for this command only: .PP .Vb 1 \& $s\->cmd(\*(Aqshow ip int br\*(Aq, { match => qr/special prompt>$/ }); .Ve .PP However be aware that a side effect of this is that the custom prompt becomes the new default prompt for subsequent commands or macros. .SS "Macro Commands" .IX Subsection "Macro Commands" Call a predefined Macro from the phrasebook using this method: .PP .Vb 1 \& $s\->macro(\*(Aqwrite_mem\*(Aq); .Ve .PP Sometimes the Macro needs parameters: .PP .Vb 1 \& $s\->macro(\*(Aqto_priv_exec\*(Aq, { params => [\*(Aqmy_password\*(Aq] }); .Ve .PP You can't really create a Macro on the fly very easily, but with suitable use of \f(CW\*(C`cmd()\*(C'\fR, \f(CW\*(C`set_prompt()\*(C'\fR, and the \f(CW\*(C`match\*(C'\fR option to \f(CW\*(C`cmd()\*(C'\fR it's possible to achieve some simple flexibility. .SH "Reconfiguring On-the-Fly" .IX Header "Reconfiguring On-the-Fly" .SS "Phrasebook" .IX Subsection "Phrasebook" It's possible to load a new phrasebook by the following method, which must be passed at least the name of the personality: .PP .Vb 1 \& $s\->set_phrasebook({ personality => \*(Aqios\*(Aq }); .Ve .PP You can pass any options which the Phrasebook module itself would take. .SS "Prompt" .IX Subsection "Prompt" The current prompt can be changed by passing the name of the new Prompt as it is known by the phrasebook: .PP .Vb 1 \& $s\->set_prompt(\*(Aqname\*(Aq); .Ve .PP If you want to test whether the current prompt matches a different named Prompt from the phrasebook, this method can be used: .PP .Vb 1 \& $s\->prompt_looks_like(\*(Aqname\*(Aq); .Ve .SH "Logging" .IX Header "Logging" A generic logging service is available through the \f(CW\*(C`$session\->logger\*(C'\fR object, which is based on Log::Dispatch. You can configure the logger at startup quite easily. See the Net::CLI::Interact::Logger manual page for details of the interface (config for any option can simply be passed to \&\f(CW\*(C`Net::CLI::Interact\->new()\*(C'\fR). .SS "Destinations" .IX Subsection "Destinations" The default configuration sends logging messages to standard output. Let's say you also want to append them to a log file: .PP .Vb 10 \& my $s = Net::CLI::Interact\->new({ \& log_config => { \& dispatchers => [\*(Aqscreen\*(Aq,\*(Aqfile\*(Aq], \& screen => { \& class => \*(AqLog::Dispatch::Screen\*(Aq, \& min_level => \*(Aqwarning\*(Aq, \& }, \& file => { \& class => \*(AqLog::Dispatch::File\*(Aq, \& min_level => \*(Aqdebug\*(Aq, \& filename => \*(Aq/var/log/myapp.log\*(Aq, \& mode => \*(Aqappend\*(Aq, \& format => \*(Aq[%d] %m\*(Aq, \& }, \& }, \& # etc... \& }); .Ve .PP Note that some keys are required, such as the \f(CW\*(C`class\*(C'\fR and \f(CW\*(C`min_level\*(C'\fR but others depend on the particular class being used. See Log::Dispatch::Config for more details. .SS "Log Levels and Categories" .IX Subsection "Log Levels and Categories" Each log message has a standard log level (\f(CW\*(C`debug\*(C'\fR, \f(CW\*(C`warning\*(C'\fR, etc) but also a \fIcategory\fR which is a concept local to this module. Categories allow more filtering of what is logged. Each time a message is logged through \f(CW\*(C`$s\->logger\->log(...)\*(C'\fR it has a level and category. .PP Messages are only emitted if they pass the specific level set for that category. In this way we can suppress messages about the transport but, for example, show messages about prompt-matching at a debug level. .PP You can very easily set the log level for all categories using either the \&\f(CW\*(C`set_global_log_at\*(C'\fR option to \f(CW\*(C`new()\*(C'\fR, or the \f(CW\*(C`NCI_LOG_AT\*(C'\fR environment variable. .PP To configure these filters, use the \f(CW\*(C`log_flags\*(C'\fR option together with the list of default log categories used by \f(CW\*(C`Net::CLI::Interact\*(C'\fR. For example: .PP .Vb 7 \& my $s = Net::CLI::Interact\->new({ \& log_flags => { \& (map {$_ => \*(Aqnotice\*(Aq} Net::CLI::Interact\->default_log_categories()), \& dialogue => \*(Aqinfo\*(Aq, \& }, \& # etc... \& }); .Ve .PP This example would set all categories to \f(CW\*(C`notice\*(C'\fR level except for the \&\f(CW\*(C`dialogue\*(C'\fR category, which is set to \f(CW\*(C`info\*(C'\fR level to get more output (on what is sent and received by each command). .SH "Phrasebook Libraries" .IX Header "Phrasebook Libraries" You can override or add to the device command phrasebooks which ship with this distribution. To start with, check the shipped dictionary for your device's current level of support, at Net::CLI::Interact::Manual::Phasebook. .PP If you want to add either some prompts or macros, first read the documentation for these systems at Net::CLI::Interact::Phrasebook. .PP All phrasebooks can inherit from others, and this is based on their location in a filesystem tree. See the phrasebooks bundled with the Net::CLI::Interact distribution for an example of this in action. .PP If you wish to override a phrasebook entry, simply set \f(CW\*(C`add_library\*(C'\fR in your code, and then create a file at the same relative point beneath that library directory as the original version shipped with the \f(CW\*(C`Net::CLI::Interact\*(C'\fR module, for example "\f(CW\*(C`/cisco/pixos/pixos7/my_phrases\*(C'\fR". .PP The file itself (\f(CW\*(C`my_phrases\*(C'\fR) does not have to be the same name as the original, and you can have more than one file if it helps. Only the directory is matched against your chosen \f(CW\*(C`personality\*(C'\fR and then all files in there, and higher in the \f(CW\*(C`add_library\*(C'\fR tree, and distribution \f(CW\*(C`library\*(C'\fR tree, are loaded. .PP To check what phrasebooks and prompts/macros are loaded, run your script with debug level set to \f(CW\*(C`notice\*(C'\fR. The easiest way to do this is by setting the environment variable \f(CW\*(C`NCI_LOG_AT=notice\*(C'\fR. .SH "Phrasebook Entries" .IX Header "Phrasebook Entries" .SS "Prompts" .IX Subsection "Prompts" These are nothing more than named regular expressions: .PP .Vb 2 \& prompt configure \& match /\e(config[^)]*\e)# ?$/ .Ve .SS "Macros" .IX Subsection "Macros" This example waits for the device to ask \*(L"[startup\-config]?\*(R" and then responds with the text \f(CW\*(C`startup\-config\*(C'\fR. Remember, there is an implicit \f(CW\*(C`match\*(C'\fR statement added at the end, which is the current prompt. .PP .Vb 4 \& macro copy_run_start \& send copy running\-config startup\-config \& match /Destination filename \e[startup\-config\e]\e?$/ \& send startup\-config .Ve .PP To send instead a \*(L"press\*(R" of the Return key (\fIoutput record separator\fR), use: .PP .Vb 4 \& macro write_mem \& send copy running\-config startup\-config \& match /Destination filename \e[startup\-config\e]\e?$/ \& send \*(Aq\*(Aq .Ve .PP To instead allow the user to pass in the file name, use a \f(CW\*(C`sprintf\*(C'\fR format. .PP .Vb 4 \& macro save_to_file \& send copy running\-config startup\-config \& match /Destination filename \e[startup\-config\e]\e?$/ \& send %s .Ve .PP The user \fImust\fR then pass a parameter to the \f(CW\*(C`macro\*(C'\fR call, even if it's an empty string: .PP .Vb 3 \& $s\->macro(\*(Aqsave_to_file\*(Aq, { params => [\*(Aqfile_name\*(Aq] }); \& # or \& $s\->macro(\*(Aqsave_to_file\*(Aq, { params => [\*(Aq\*(Aq] }); .Ve .SS "Continuations" .IX Subsection "Continuations" These are Macros which start with a match instead of a send: .PP .Vb 3 \& macro more_pages \& match / \-\-More\-\- / \& send \*(Aq \*(Aq .Ve .PP Note that the parameter of the \f(CW\*(C`send\*(C'\fR is \fInot\fR sent with a Return character (\fIoutput record separator\fR) appended. .PP When included in a macro, the continuation can be in-line, like this: .PP .Vb 3 \& macro show_ip_route \& send show ip route \& follow / \-\-More\-\- / with \*(Aq \*(Aq .Ve