|
@@ -0,0 +1,2483 @@
|
|
|
+# Klish 3
|
|
|
+
|
|
|
+
|
|
|
+## Overview
|
|
|
+
|
|
|
+The klish program is designed to organize the command line interface,
|
|
|
+in which only a strictly defined set of commands is available to the operator. This
|
|
|
+distinguishes klish from standard shell interpreters, where an operator can
|
|
|
+use any commands existing in the system and the ability to execute them
|
|
|
+depends only on access rights. The set of commands available in klish is defined on
|
|
|
+configuration step and can be set, in general, in a variety of ways,
|
|
|
+The main ones are XML configuration files. Commands in klish are not
|
|
|
+are system commands, and are fully defined in the configuration files,
|
|
|
+with all possible parameters, syntax, and actions that they
|
|
|
+fulfillment.
|
|
|
+
|
|
|
+The main application of klish is in embedded systems where the operator has access to
|
|
|
+only certain, device-specific commands, not
|
|
|
+arbitrary set of commands, as in general-purpose systems. In such embedded
|
|
|
+klish systems can replace the shell interpreter, which is not available to the
|
|
|
+of the operator.
|
|
|
+
|
|
|
+An example of embedded systems is managed networking equipment.
|
|
|
+Historically, there have been two main approaches to organization in this segment
|
|
|
+command line interface. Conventionally, they can be called the "Cisco" approach and the "Cisco" approach
|
|
|
+"Juniper. Both Cisco and Juniper have two modes of operation - command mode and
|
|
|
+configuration mode. In command mode, the entered commands are immediately
|
|
|
+are executed but do not affect the system configuration. These are view commands
|
|
|
+status, commands to control the device, but not to change its configuration.
|
|
|
+In configuration mode
|
|
|
+the hardware and services are being configured. In Cisco, the configuration commands also
|
|
|
+are executed immediately, changing the system configuration. In Juniper, the configuration
|
|
|
+can be conventionally represented as a text file, changes in which are
|
|
|
+are performed using standard editing commands. When editing
|
|
|
+the changes are not applied to the system. And only by special command the entire
|
|
|
+The accumulated set of changes is applied at once, thus ensuring that
|
|
|
+change consistency. With the Cisco approach, similar behavior can also be
|
|
|
+emulate by designing commands in a certain way, but for Cisco, it's less of a
|
|
|
+the natural way.
|
|
|
+
|
|
|
+Which approach is better and easier in a particular case is determined by the task.
|
|
|
+Klish is primarily designed for the Cisco approach, i.e., immediately executable
|
|
|
+teams. However, the project has a plugin system, which allows you to extend it
|
|
|
+capabilities. So the plugin klish-plugin-sysrepo, implemented by a separate project,
|
|
|
+Powered by sysrepo storage, it allows you to organize the Juniper approach.
|
|
|
+
|
|
|
+
|
|
|
+## Basic Information
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+The klish project uses a client-server model. Listening server klishd
|
|
|
+loads the command configuration and waits for requests from clients on the UNIX socket (1).
|
|
|
+On a connection from a client, the klishd listening server spawns (fork()) a separate
|
|
|
+process (2), which will be concerned with serving one particular customer.
|
|
|
+The spawned process is called the klishd serving server. Listening server
|
|
|
+klishd continues to expect new connections from clients. Interaction between
|
|
|
+clients and the serving server are carried out over UNIX sockets using the
|
|
|
+KTP (Klish Transfer Protocol), which is specially designed for this purpose
|
|
|
+(3).
|
|
|
+
|
|
|
+The client's task is to transmit input from the operator to the server and receive it from the server
|
|
|
+the result to be shown to the operator. The client does not know what commands exist,
|
|
|
+how to execute them. The execution is handled by the server side. Since the client has
|
|
|
+relatively simple code, it is not difficult to implement alternative programs -
|
|
|
+clients, such as a graphical client or a client for automated
|
|
|
+controls. Right now, there is only a text-based command line client called klish.
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+The basis of the klish project is the libklish library. The klish client is based on it
|
|
|
+and klishd server. The library implements all basic mechanisms of work and
|
|
|
+interactions. The library is part of the klish project.
|
|
|
+
|
|
|
+The text client uses another built-in library, the
|
|
|
+libtinyrl (Tiny ReadLine). The library provides interaction with the user
|
|
|
+when working on the command line.
|
|
|
+
|
|
|
+All executable files of the klish project, as well as all its built-in libraries
|
|
|
+use the libfaux (Library of Auxiliary Functions) library in their work -
|
|
|
+library of auxiliary functions. In previous versions of the project klish library
|
|
|
+was part of the klish source code, now it has been separated into a separate project and
|
|
|
+includes functions that make it easy to work with strings, files, networking, standard
|
|
|
+data structures, etc. The libfaux library is a mandatory external library
|
|
|
+a dependency for the klish project.
|
|
|
+
|
|
|
+In addition, klish plugins, discussed below, can also use the
|
|
|
+other libraries for their work.
|
|
|
+
|
|
|
+Klish has two types of plugins. Plugins for loading command configurations
|
|
|
+(let's call them database plugins) and plugins that implement actions to
|
|
|
+commands from the user (let's call them function plugins). Klish does not
|
|
|
+has built-in commands and means of loading configuration (except for a special
|
|
|
+ischeme cases). All this functionality is implemented in plugins. Several
|
|
|
+plug-ins with basic functionality are included in the source codes of klish and
|
|
|
+are located in the "dbs/" and "plugins/" directories.
|
|
|
+
|
|
|
+All necessary plugins are loaded by the klishd listening server at the beginning of its operation.
|
|
|
+What kind of plugins to load custom command configurations are needed
|
|
|
+use it learns from its base configuration file (a special file in the
|
|
|
+INI format). The klishd server then uses the database plugin to load the
|
|
|
+configuration of user commands (e.g. from XML files). From this
|
|
|
+configuration, it learns the list of required function plug-ins, and so loads the
|
|
|
+these plug-ins into memory. However, using functions from function plug-ins will
|
|
|
+only serving (not listening to) the klishd server on requests from the user.
|
|
|
+
|
|
|
+The configuration file is used to configure the klishd server parameters
|
|
|
+`/etc/klish/klishd.conf`. An alternate configuration file can be specified at
|
|
|
+to start the klishd server.
|
|
|
+
|
|
|
+The configuration file is used to configure the client parameters
|
|
|
+`/etc/klish/klish.conf`. An alternate configuration file can be specified at
|
|
|
+launching the klish client.
|
|
|
+
|
|
|
+
|
|
|
+## Loading command configuration
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+The internal representation of the command configuration in klish is kscheme. Kscheme is.
|
|
|
+is a set of C-structures representing the entire tree of commands available to the user,
|
|
|
+visibility areas, parameters, etc. It is by these structures that the
|
|
|
+all internal work - command search, autocompletion, generation of hints at
|
|
|
+user interaction.
|
|
|
+
|
|
|
+In klish there is an intermediate representation of the command configuration in the form of
|
|
|
+C-structures, called ischeme. This representation is similar to kscheme in general, but
|
|
|
+differs from it in that all configuration fields are represented in text form,
|
|
|
+all references to other objects are also text object names, on the
|
|
|
+that are referenced, rather than pointers as in kscheme. There are other differences as well.
|
|
|
+Thus ischeme can be called an "uncompiled schema" and kscheme can be called an
|
|
|
+"compiled". "Compilation", i.e. conversion of ischeme to kscheme
|
|
|
+is produced by the internal mechanisms of klish. Ischeme can be manually set
|
|
|
+by the user in the form of C-structures and assembled as a separate database plugin.
|
|
|
+In this case no other database plugins will be needed, the entire configuration is already
|
|
|
+ready to be converted to kscheme.
|
|
|
+
|
|
|
+As part of klish (see dbs/), the following database plugins exist for downloading
|
|
|
+command configurations, i.e., schematics:
|
|
|
+
|
|
|
+* expat - Uses the expat library to load configuration from XML.
|
|
|
+* libxml2 - Uses the libxml2 library to load configuration from XML.
|
|
|
+* roxml - Uses the roxml library to load configuration from XML.
|
|
|
+* ischeme - Uses the configuration built into C code (Internal Scheme).
|
|
|
+
|
|
|
+All database plugins translate an external configuration obtained e.g. from a
|
|
|
+XML files, to ischeme. In the case of ischeme, the additional conversion step is not
|
|
|
+is required, since the ischeme is already in place.
|
|
|
+
|
|
|
+The installed dbs plugins are located in `/usr/lib` (if configuring the
|
|
|
+assembly with --prefix=/usr). Their names are `libklish-db-<name>.so`, e.g.
|
|
|
+`/usr/lib/libklish-db-libxml2.so`.
|
|
|
+
|
|
|
+
|
|
|
+## Executable function plug-ins
|
|
|
+
|
|
|
+Each klish command performs an action or several actions at once.
|
|
|
+These actions need to be described somehow. If we look inside the implementation, klish
|
|
|
+can only run executable compiled code from the plugin. Plugins
|
|
|
+contain so-called symbols (symbol, sym), which, in fact, represent
|
|
|
+are functions with a single fixed API. These symbols can be referenced by
|
|
|
+klish commands. In turn, a symbol can execute complex code, e.g.
|
|
|
+run the shell interpreter with the script defined in the command description
|
|
|
+klish in the configuration file. Alternatively, another character can execute a Lua script.
|
|
|
+
|
|
|
+Klish only knows how to get symbols from plugins. Standard symbols are implemented
|
|
|
+in the plugins included in the klish project. The klish project includes the following
|
|
|
+plug-ins:
|
|
|
+
|
|
|
+* klish - Basic plugin. Navigation, data types (for parameters),
|
|
|
+auxiliary functions.
|
|
|
+* lua - Execution of Lua scripts. The mechanism is built into the plugin and does not use
|
|
|
+an external program for interpretation.
|
|
|
+* script - Execution of scripts. Takes shebang into account to determine
|
|
|
+which interpreter to use. In this way, not only
|
|
|
+shell scripts, but also scripts in other interpreted languages. By default
|
|
|
+the shell interpreter is used.
|
|
|
+
|
|
|
+Users can write their own plugins and use their own characters in the
|
|
|
+klish commands. Installed plugins are located in `/usr/lib`.
|
|
|
+(if configuring the build with --prefix=/usr). Their names are
|
|
|
+`libklish-plugin-<name>.so`, such as `/usr/lib/lib/libklish-plugin-script.so`.
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+Symbols are "synchronous" and "asynchronous". Synchronous characters are executed
|
|
|
+in the klishd address space, a separate process is spawned for asynchronous ones.
|
|
|
+
|
|
|
+Asynchronous symbols can accept user input (stdin) as input,
|
|
|
+received by the klishd server from the client via the KTP protocol and
|
|
|
+sent to the spawned process within which the asynchronous process is executed
|
|
|
+symbol. In turn, asynchronous symbol can write to stdout, stderr streams.
|
|
|
+The data from these streams is received by the serving server klishd and forwarded to the
|
|
|
+to the client via the KTP protocol.
|
|
|
+
|
|
|
+Synchronous characters (with output to stdout, stderr) cannot receive data through the
|
|
|
+stdin input stream, since they are executed within the serving server
|
|
|
+klishd and, for the duration of the symbol code execution, other server functions
|
|
|
+are temporarily stopped. Receiving data from the customer is stopped. The attendant
|
|
|
+klishd server is a single-threaded program, so synchronous characters must be
|
|
|
+use with caution. If the symbol takes too long to execute, then
|
|
|
+the server will hang for that time. In addition, synchronous characters are executed in the
|
|
|
+of the server's address space. This means that the execution of an unreconfigured
|
|
|
+character containing errors may cause the serving server to crash.
|
|
|
+Although a synchronous symbol does not have a stdin input stream, it can use the
|
|
|
+output streams stdout, stderr. To get data from these streams and
|
|
|
+The service server spawns a service server to send them to the client.
|
|
|
+A process that receives and temporarily stores data coming from a symbol. When
|
|
|
+when the symbol execution is completed, the service process forwards the saved data
|
|
|
+back to the serving server, which in turn sends them to the client.
|
|
|
+Synchronous characters are recommended only when the character changes the
|
|
|
+state of the serving server and therefore cannot be executed as part of the
|
|
|
+of another process. For example, section navigation (see Scopes)
|
|
|
+is realized by a synchronous symbol, because the user's position in the section tree
|
|
|
+is stored in the serving server.
|
|
|
+
|
|
|
+Lightweight synchronous symbols have no input and output data streams
|
|
|
+stdin, stdout, stderr. Due to this, execution of such a symbol does not require
|
|
|
+generation of new processes, as it is done in the case of ordinary synchronous
|
|
|
+symbol, or an asynchronous symbol. Thus a lightweight synchronous symbol
|
|
|
+is executed as quickly as possible. Although the lightweight synchronous symbol does not have a
|
|
|
+of the stdout stream, it can generate an output text string.
|
|
|
+The string is formed manually and, with the help of a special function, is passed to
|
|
|
+to the serving server, which can send it to the client as stdout.
|
|
|
+Otherwise, the lightweight synchronous symbol has the same features as the regular one
|
|
|
+synchronized character. It is recommended to use lightweight synchronous characters
|
|
|
+when the fastest possible execution is required. An example of such a task
|
|
|
+can serve as a prompt for the user. This is a service
|
|
|
+function that is executed every time the user presses the button
|
|
|
+Input. Another example of usage is the function to check whether the
|
|
|
+the argument entered by the user is valid (see PTYPE), as well as functions to
|
|
|
+formation of autocompletion and hints.
|
|
|
+
|
|
|
+A symbol, or, more correctly, a klish command, since a command may consist of a
|
|
|
+several consecutively executed characters, may be regular or
|
|
|
+to be a filter. For simplicity, let's assume that the command performs only one
|
|
|
+symbol, and so we will talk about symbols rather than commands. A common symbol
|
|
|
+performs some useful action and, often, produces some output
|
|
|
+text output. And the filter receives as input the result of work, i.e., in this case
|
|
|
+case, the text output of a regular character and processes it. To specify that
|
|
|
+a filter must be applied to an ordinary command, the user uses chains of
|
|
|
+commands separated by "|". In many ways it is similar to chains in the standard
|
|
|
+a custom shell.
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+Synchronous symbols have no stdin input stream, i.e., they do not receive an input of
|
|
|
+no data and therefore cannot be full-fledged filters, but can be
|
|
|
+be used only as the first command in a chain of commands. Lightweight
|
|
|
+synchronous characters do not have and output stream stdout, so they cannot be
|
|
|
+use not only as filters, but also as the first place team in the chain of command
|
|
|
+commands, because the filter will not be able to get any data from them. Typical
|
|
|
+the use of lightweight synchronous characters are service internal functions,
|
|
|
+that do not interact directly with the user and are not used in chains
|
|
|
+commands.
|
|
|
+
|
|
|
+The first command in the command chain receives stdin stream input data from
|
|
|
+user, if required. Let's call the stdin stream from the user -
|
|
|
+by the global stdin stream. Then the stdout stream of the previous character in the chain
|
|
|
+is received at the input of the stdin stream of the next character. Output stream stdout
|
|
|
+The last character in the chain is considered to be global and is sent to the servicer.
|
|
|
+to the server and then to the user.
|
|
|
+
|
|
|
+Any character in the chain has the ability to write to the stderr stream. The entire chain
|
|
|
+a single stderr stream, i.e. one for all symbols. This stream is considered to be global
|
|
|
+stderr and is sent to the serving server and then to the user.
|
|
|
+
|
|
|
+The number of commands in the command chain is unlimited. The klish command must be
|
|
|
+is declared as a filter so that it can be used after the "|" sign.
|
|
|
+
|
|
|
+
|
|
|
+## KTP Protocol
|
|
|
+
|
|
|
+KTP (Klish Transfer Protocol) is used for client interaction
|
|
|
+klish with service
|
|
|
+by the klishd server. The main task is to transfer commands and user input
|
|
|
+from the client to the server, transmitting the text output of the executed command and status
|
|
|
+of command execution - in the opposite direction. In addition, the protocol provides for
|
|
|
+means for the client to obtain autocomplete options from the server for the
|
|
|
+incomplete commands and hints for commands and parameters.
|
|
|
+
|
|
|
+The KTP protocol is implemented by means of the libfaux library, which simplifies the
|
|
|
+creation of a specialized network protocol on the basis of a generalized template
|
|
|
+network protocol. The protocol is built on top of a streaming socket. Currently in the project
|
|
|
+klish uses UNIX sockets for client-server communication.
|
|
|
+
|
|
|
+A KTP protocol packet consists of a fixed-length header and a set of
|
|
|
+"parameters". The number of parameters is stored in a special header field.
|
|
|
+Each parameter has its own little header that specifies the type of parameter and the
|
|
|
+its length. Thus, at the beginning of a KTP packet is the KTP header, followed by the KTP
|
|
|
+first parameter header, first parameter data, second parameter header
|
|
|
+parameter, data of the second parameter, etc. All fields in the headers are passed with
|
|
|
+using network (big-endian) byte order.
|
|
|
+
|
|
|
+KTP headline:
|
|
|
+
|
|
|
+|Size, bytes|Field name |Field value|
|
|
|
+|------------|---------------------------------|-------------|
|
|
|
+|4 |Magic number |0x4b545020 |
|
|
|
+|1 | Protocol version (major) |0x01 |
|
|
|
+|1 | Protocol version (minor) |0x00 |
|
|
|
+|2 | | Command code | |
|
|
|
+|4 |4 | | | |
|
|
|
+|4 | Not used |
|
|
|
+|4 |4 | Number of parameters | |
|
|
|
+|4 |The length of the entire packet (with header)| |
|
|
|
+
|
|
|
+Team Codes:
|
|
|
+
|
|
|
+| Code| Name | Direction| Description |
|
|
|
+|---|--------------|-----------|-----------------------------------------------|
|
|
|
+|'i'|STDIN |-> |stdin user input (PARAM_LINE) |
|
|
|
+|'o'|STDOUT |<- |stdout command output (PARAM_LINE) |
|
|
|
+|'e'|STDERR |<- |stderr command output (PARAM_LINE) |
|
|
|
+|'c'|CMD |-> | Execute command (PARAM_LINE) |
|
|
|
+|'C'|CMD_ACK |<- | The result of the command |
|
|
|
+|'v'|COMPLETION |-> | Request for autocompletion (PARAM_LINE) |
|
|
|
+|'V'|COMPLETION_ACK|<- |Possible additions (PARAM_PREFIX, PARAM_LINE)|
|
|
|
+|'h'|HELP |-> | Prompt (PARAM_LINE) |
|
|
|
+|'H'|HELP_ACK |<- | Hint (PARAM_PREFIX, PARAM_LINE) |
|
|
|
+|'n'|NOTIFICATION |<-> |Asynchronous message (PARAM_LINE) |
|
|
|
+|'a'|AUTH |-> | | Authentication Request |
|
|
|
+|'A'|AUTH_ACK |<- |AUTH_ACK |<- |Authentication Confirmation |
|
|
|
+|'I'|STDIN_CLOSE |-> |stdin was closed |
|
|
|
+|'O'|STDOUT_CLOSE |-> |stdout was closed |
|
|
|
+|'E'|STDERR_CLOSE |-> |stderr was closed |
|
|
|
+
|
|
|
+The "Direction" column shows in which direction the command is transmitted. Arrow
|
|
|
+right arrow means transfer from client to server, left arrow means transfer from server
|
|
|
+to the client. In the "Description" column in brackets are the names of parameters in which
|
|
|
+data is being transmitted.
|
|
|
+
|
|
|
+The status field in the KTP header is a 32-bit field. Bit values
|
|
|
+status fields:
|
|
|
+
|
|
|
+|Bit Mask|Bit Name |Value |
|
|
|
+|----------|------------------|-----------------------------------------------|
|
|
|
+|0x00000001|STATUS_ERROR | Error |
|
|
|
+|0x00000002|STATUS_INCOMPLETED|Command execution not completed |
|
|
|
+|0x00000100|STATUS_TTY_STDIN |stdin client is terminal |
|
|
|
+|0x00000200|STATUS_TTY_STDOUT |stdout client is terminal |
|
|
|
+|0x00000400|STATUS_TTY_STDERR |stderr client is a terminal |
|
|
|
+|0x00001000|STATUS_NEED_STDIN |Command accepts user input |
|
|
|
+|0x00002000|STATUS_INTERACTIVE|The output of the command is for the terminal |
|
|
|
+|0x00010000|STATUS_DRY_RUN | Idle start. The command does not need to be executed|
|
|
|
+|0x80000000|STATUS_EXIT | Ending session |
|
|
|
+
|
|
|
+Parameter Title:
|
|
|
+
|
|
|
+|Size, bytes|Field name |
|
|
|
+|------------|--------------------------------------|
|
|
|
+|2 |2 | Parameter type |
|
|
|
+|2 | Not used |
|
|
|
+|1 |Parameter data length (without header)|
|
|
|
+
|
|
|
+Parameter Types:
|
|
|
+
|
|
|
+| Code| Name | Direction| Description |
|
|
|
+|---|-------------|-----------|---------------------------------------------|
|
|
|
+|'L'|PARAM_LINE |<-> | String. Multifunctional |
|
|
|
+|'P'|PARAM_PREFIX |<- |String. For autocomplete and hint |
|
|
|
+|'$'|PARAM_PROMPT |<- |String. User prompt |
|
|
|
+|'H'|PARAM_HOTKEY |<- | Function key and its meaning |
|
|
|
+|'W'|PARAM_WINCH |-> | The size of the user window. When changing|
|
|
|
+|'E'|PARAM_ERROR |<- |String. Error message |
|
|
|
+|'R'|PARAM_RETCODE|<- | Return code of the executed command |
|
|
|
+
|
|
|
+From the server to the client, along with the command and the parameters corresponding to the command,
|
|
|
+can be passed additional parameters. For example, with the CMD_ACK command,
|
|
|
+that reports the completion of a user command can be sent to the
|
|
|
+PARAM_PROMPT parameter, which tells the client that the user's
|
|
|
+the invitation has changed.
|
|
|
+
|
|
|
+
|
|
|
+## XML configuration structure
|
|
|
+
|
|
|
+The main way to describe klish commands today is XML files.
|
|
|
+In this section, all examples will be based on XML elements.
|
|
|
+
|
|
|
+
|
|
|
+### Visibility areas
|
|
|
+
|
|
|
+Commands are organized into "scopes" called VIEWs. That is, each command
|
|
|
+belongs to a VIEW and is defined in it. When working in klish always
|
|
|
+there is a "current path". By default, when starting klish the current path is
|
|
|
+is assigned to a VIEW named "main". The current path determines which commands are currently
|
|
|
+are visible to the operator at the moment. The current path can be changed
|
|
|
+[navigation commands](#navigation). For example
|
|
|
+go to a "neighboring" VIEW, then the current path will be this neighboring VIEW,
|
|
|
+displacing the old one. Another possibility is to "go deep inside", i.e. to go into a nested
|
|
|
+VIEW. The current path will then become a two-level path, similar to how you can enter a
|
|
|
+subdirectory in the file system. When the current path has more than one
|
|
|
+level, the operator has access to the commands of the "deepest" VIEW, as well as commands of all the
|
|
|
+of the above levels. You can use navigation commands to exit from nested levels
|
|
|
+levels. When the current path is changed, the navigation command used determines whether the
|
|
|
+whether the VIEW of the current path is superseded by another VIEW at the same nesting level, or
|
|
|
+the new VIEW will become nested and another level will appear in the current path. The way
|
|
|
+VIEWs defined in XML files do not affect whether a VIEW can be nested.
|
|
|
+
|
|
|
+When defining VIEWs in XML files, some VIEWs can be nested within other VIEWs.
|
|
|
+This nesting should not be confused with the nesting when the current path is formed.
|
|
|
+A VIEW defined within another VIEW adds its commands to the commands of the
|
|
|
+of the parent VIEW, but can also be addressed separately from the parent VIEW.
|
|
|
+In addition to this, there are references to VIEWs. By declaring such a link inside a VIEW, we
|
|
|
+add the commands of the referenced VIEW to the commands of the current VIEW
|
|
|
+VIEW. You can define a VIEW with "standard" commands and include a reference to the
|
|
|
+this VIEW into other VIEWs that require these commands without redefining them.
|
|
|
+
|
|
|
+In XML configuration files, the `VIEW` tag is used to declare a VIEW.
|
|
|
+
|
|
|
+
|
|
|
+### Commands and parameters
|
|
|
+
|
|
|
+Commands (tag `COMMAND`) can have parameters (tag `PARAM`). A command is defined by
|
|
|
+within a VIEW and belongs to it. Parameters are defined within the command
|
|
|
+and, in turn, belong to it. A command can consist of only one word,
|
|
|
+unlike the commands in klish of previous versions. If you want to define a verbose
|
|
|
+command, then nested commands are created. I.e. within the command identified by
|
|
|
+the first word of a verbose command, a command identified by the
|
|
|
+to the second word of a verbose command, etc.
|
|
|
+
|
|
|
+Strictly speaking, a command differs from a parameter only in that its value can be
|
|
|
+can only be a predefined word, while the value of a parameter can be
|
|
|
+be anything. Only the type of the parameter determines its possible values. Thus
|
|
|
+so the command can be thought of as a parameter with a type that says
|
|
|
+that the valid value is the parameter name itself. Internal implementation
|
|
|
+teams are exactly like that.
|
|
|
+
|
|
|
+In general, a parameter can be defined directly in VIEW rather than internally
|
|
|
+teams, but this is more of an atypical case.
|
|
|
+
|
|
|
+Like VIEW, commands and parameters can be references. In this case, the reference can be
|
|
|
+consider it simply as a substitution of the object pointed to by the reference.
|
|
|
+
|
|
|
+Parameters can be mandatory, optional, or mandatory
|
|
|
+selection among several candidate parameters. Thus, when entering the command
|
|
|
+some parameters may be specified by the operator and some may not. When parsing
|
|
|
+The command line is used to compose a sequence of selected parameters.
|
|
|
+
|
|
|
+
|
|
|
+### Parameter type
|
|
|
+
|
|
|
+The type of a parameter defines the allowed values of that parameter. Usually types
|
|
|
+are defined separately using the `PTYPE` tag, and the parameter refers to a specific
|
|
|
+type by its name. The type can also be defined directly inside the parameter, but this is
|
|
|
+is not a typical case, since standard types can cover most of the
|
|
|
+Needs.
|
|
|
+
|
|
|
+The PTYPE type, like a command, performs a specific action specified by the tag
|
|
|
+`ACTION`. The action specified for the type checks the value entered by the operator
|
|
|
+parameter and returns the result - success or error.
|
|
|
+
|
|
|
+
|
|
|
+### Action
|
|
|
+
|
|
|
+Each command must define the action to be performed when that command is entered
|
|
|
+operator. The action can be a single action, or multiple actions for a single command.
|
|
|
+The action is declared with the `ACTION` tag inside the command. ACTION specifies a reference
|
|
|
+to the symbol (function) from the function plugin that will be executed in this case.
|
|
|
+All data inside the ACTION tag is available to the symbol. The symbol can at its own discretion
|
|
|
+use this information. As data, for example, it can be set to
|
|
|
+script to be executed by the symbol.
|
|
|
+
|
|
|
+The result of the action is a "return code". It defines the success
|
|
|
+or failure to execute the command as a whole. If a command is defined for one command
|
|
|
+more than one action, then calculating the return code becomes more complex
|
|
|
+Task. Each action has a flag that determines whether the return code affects the
|
|
|
+of the current action to a common return code. Actions also have settings,
|
|
|
+determining whether the action will be executed if the previous action is executed
|
|
|
+ended with an error. If several actions are performed sequentially,
|
|
|
+that have an influence flag on the common return code, then the common return code will be the code
|
|
|
+the return of the last such action.
|
|
|
+
|
|
|
+
|
|
|
+### Filters
|
|
|
+
|
|
|
+Filters are commands that process the output of other commands.
|
|
|
+The filter can be specified on the command line after the main command and the `|` sign.
|
|
|
+The filter cannot be a stand-alone command and can be used without the main
|
|
|
+commands. An example of a typical filter is the UNIX analog of the `grep` utility.
|
|
|
+Filters can be used one after the other, with a `|` separator like this
|
|
|
+is done in the shell.
|
|
|
+
|
|
|
+If the command is not a filter, it cannot be used after the character
|
|
|
+`|`.
|
|
|
+
|
|
|
+The filter is specified in the configuration files using the `FILTER` tag.
|
|
|
+
|
|
|
+
|
|
|
+### Parameter Containers
|
|
|
+
|
|
|
+SWITCH and SEQ containers are used to aggregate nested parameters and
|
|
|
+define the rules by which the command line is parsed with respect to
|
|
|
+of these parameters.
|
|
|
+
|
|
|
+By default, it is assumed that if a command is defined sequentially within a command
|
|
|
+several parameters, then all these parameters must also be consistently
|
|
|
+to be present on the command line. However, sometimes there is a need for
|
|
|
+the operator has entered only one parameter of his choice from the set of possible parameters.
|
|
|
+In such a case, the SWITCH container can be used. If, when parsing a command
|
|
|
+SWITCH container is found inside the command, then to match the
|
|
|
+only one parameter must be selected for the next word entered by the operator
|
|
|
+from the parameters nested in SWITCH. I.e. with the help of the SWITCH container there is
|
|
|
+branching parsing.
|
|
|
+
|
|
|
+The SEQ container defines a sequence of parameters. All of them must be
|
|
|
+are consistently mapped to the command line. Although, as noted earlier,
|
|
|
+The parameters nested in the command are already parsed sequentially, however
|
|
|
+The container may be useful in more complex designs. For example, a container
|
|
|
+The SEQ itself can be an element of a SWITCH container.
|
|
|
+
|
|
|
+
|
|
|
+### Command line invitations
|
|
|
+
|
|
|
+To generate the command line prompt that the operator sees,
|
|
|
+The `PROMPT` construct is used. The PROMPT tag must be nested inside a VIEW.
|
|
|
+Different VIEWs can have different invitations. I.e. depending on the current
|
|
|
+paths, the operator sees a different invitation. The invitation can be dynamic
|
|
|
+and generated by the `ACTION` actions specified within PROMPT.
|
|
|
+
|
|
|
+
|
|
|
+### Autocomplete and tips
|
|
|
+
|
|
|
+For operator convenience, commands and parameters can be realized for commands and parameters
|
|
|
+hints and autocomplete. Hints (help), which explain the purpose of and
|
|
|
+format of possible parameters, are displayed in the klish client by pressing the key
|
|
|
+`?`. The list of possible additions is printed when the operator presses the `Tab` key.
|
|
|
+
|
|
|
+To set hints and a list of possible add-ons in the configuration, the following are used
|
|
|
+`HELP` and `COMPL` tags. These tags must be nested relative to
|
|
|
+of the corresponding commands and parameters. For simplicity, the prompts for a parameter or
|
|
|
+commands can be specified by the main tag attribute if the hint is a
|
|
|
+is static text and does not need to be generated. If the tooltip is dynamic, then
|
|
|
+its contents are generated by ACTION actions nested inside HELP. For
|
|
|
+of COMPL additions of ACTION actions generate a list of possible values
|
|
|
+parameters separated by a line feed.
|
|
|
+
|
|
|
+
|
|
|
+### Conditional element
|
|
|
+
|
|
|
+Commands and parameters can be hidden from the operator based on dynamic
|
|
|
+conditions. A condition is specified using a `COND` tag nested inside a `COND` tag
|
|
|
+of the corresponding command or parameter. Within a COND are one or more
|
|
|
+ACTION actions. If the ACTION return code is `0`, i.e. success, the parameter is available
|
|
|
+operator. If ACTION returned an error, the element will be hidden.
|
|
|
+
|
|
|
+
|
|
|
+### Plugin
|
|
|
+
|
|
|
+The klishd process does not load all existing feature plugins in a row, but only the
|
|
|
+those specified in the configuration using the `PLUGIN` tag. Data inside the tag
|
|
|
+may be interpreted by the plugin initialization function as it sees fit,
|
|
|
+particularly as a configuration for a plugin.
|
|
|
+
|
|
|
+
|
|
|
+### Hotkeys
|
|
|
+
|
|
|
+For the operator's convenience, "hot keys" can be set in the klish command configuration.
|
|
|
+keys". The tag for specifying hotkeys is `HOTKEY`. List of hotkeys
|
|
|
+is passed by the klishd server to the client. It is at the discretion of the client to use this
|
|
|
+information or does not use it. For example, for an automated control client
|
|
|
+hotkey information is meaningless.
|
|
|
+
|
|
|
+When defining a hotkey, a text command is specified, which should
|
|
|
+be executed when a hotkey is pressed by the operator. This can be a quick
|
|
|
+display the current device configuration, exit the current VIEW, or any other
|
|
|
+command. The klish client "catches" hotkey presses and transmits them to the server
|
|
|
+command corresponding to the pressed hotkey.
|
|
|
+
|
|
|
+
|
|
|
+### Item references
|
|
|
+
|
|
|
+Some tags have attributes that are references to other tags that are defined
|
|
|
+In configuration files, elements. For example, `VIEW` has a `ref` attribute, with the help of the
|
|
|
+which creates a "copy" of the third-party `VIEW` at the current location in the schema. Or the tag
|
|
|
+`PARAM` has a `ptype` attribute, which is used to refer to `PTYPE`, defining the
|
|
|
+parameter type. Klish has its own "language" for organizing references. You can
|
|
|
+to say it is a highly simplified analog of file system paths or XPath.
|
|
|
+
|
|
|
+The path to an element in klish is typed by specifying all of its parent elements with the
|
|
|
+separator `/`. The name of an element is the value of its `name` attribute. Path
|
|
|
+also starts with the `/` character, indicating the root element.
|
|
|
+
|
|
|
+> Relative paths are not supported at this time
|
|
|
+
|
|
|
+```
|
|
|
+<KLISH>.
|
|
|
+
|
|
|
+<PTYPE name="PTYPE1">
|
|
|
+<ACTION sym="sym1"\>
|
|
|
+</PTYPE>.
|
|
|
+
|
|
|
+<VIEW name="view1">
|
|
|
+
|
|
|
+<VIEW name="view1_2">
|
|
|
+<COMMAND name="cmd1">
|
|
|
+<PARAM name="par1" ptype="/PTYPE1"/>
|
|
|
+</COMMAND>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view2">
|
|
|
+
|
|
|
+<VIEW ref="/view1/view1_2"/>
|
|
|
+
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+</KLISH>.
|
|
|
+```
|
|
|
+
|
|
|
+The "par1" parameter references `PTYPE` using the path `/PTYPE1`. Type names
|
|
|
+It is customary to designate types with capital letters to make it easier to distinguish them from other types.
|
|
|
+elements. Here the type is defined at the topmost level of the schema. Basic types
|
|
|
+are usually defined that way, but `PTYPE` does not have to be at the top level and
|
|
|
+can be nested in `VIEW` or even `PARAM`. In this case it will have
|
|
|
+a more difficult path.
|
|
|
+
|
|
|
+A `VIEW` named "view2" imports commands from a `VIEW` named "view1_2",
|
|
|
+Using the path `/view1/view1_2`.
|
|
|
+
|
|
|
+If, suppose, we need a reference to the parameter "par1", the path will look like this
|
|
|
+like this - `/view1/view1_2/cmd1/par1`.
|
|
|
+
|
|
|
+The following elements cannot be referenced. They do not have a path:
|
|
|
+
|
|
|
+* `KLISH
|
|
|
+* `PLUGIN`
|
|
|
+* `HOTKEY`
|
|
|
+* `ACTION`
|
|
|
+
|
|
|
+> Do not confuse [current session path](#visibility-areas) with the path to create a
|
|
|
+> links. The path uses the internal structure of the schema when creating links,
|
|
|
+> specified when the configuration files are written. This is the path of the element within the schematic,
|
|
|
+> uniquely identifying it. This is a static path. Nesting of elements
|
|
|
+> in defining the schema only generates the necessary instruction sets, this nesting
|
|
|
+> is not visible to the operator and is not a nesting in terms of its work with the
|
|
|
+> command line. It only sees ready-made line sets of commands.
|
|
|
+>
|
|
|
+> The current session path is dynamic. It
|
|
|
+> is formed by operator commands and implies the possibility to go deeper, i.e.
|
|
|
+> add another level of nesting to the path and access the
|
|
|
+> an additional set of commands, or go higher. With
|
|
|
+> the current path, you can combine the linear paths created at the schematic writing stage.
|
|
|
+> command sets. Navigation commands also allow you to completely replace the current
|
|
|
+> command set to another by changing `VIEW` at the current path level. Thus,
|
|
|
+> the existence of the current session path may create visibility for the operator
|
|
|
+> a branching tree of configuration.
|
|
|
+
|
|
|
+
|
|
|
+## Tags
|
|
|
+
|
|
|
+
|
|
|
+### KLISH
|
|
|
+
|
|
|
+Any klish configuration XML file must begin with an opening `KLISH` tag
|
|
|
+and end with a closing tag `KLISH`.
|
|
|
+
|
|
|
+```
|
|
|
+<?xml version="1.0" encoding="UTF-8"?
|
|
|
+<KLISH
|
|
|
+xmlns="https://klish.libcode.org/klish3"
|
|
|
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
|
+xsi:schemaLocation="https://src.libcode.org/pkun/klish/src/master/klish.xsd">
|
|
|
+
|
|
|
+<!-- There's any configuration for klish -->
|
|
|
+
|
|
|
+</KLISH>.
|
|
|
+```
|
|
|
+
|
|
|
+The header introduces its default XML namespace
|
|
|
+"https://klish.libcode.org/klish3". The header is standard and more often than not makes no sense
|
|
|
+to change it.
|
|
|
+
|
|
|
+
|
|
|
+### PLUGIN
|
|
|
+
|
|
|
+On its own, klish does not load any executable function plugins.
|
|
|
+Accordingly, no characters are available to the user for use in the
|
|
|
+ACTION. Plugin loading should be explicitly written in the files
|
|
|
+configurations. The `PLUGIN` tag is used for this purpose.
|
|
|
+
|
|
|
+Note that even the base plugin named "klish" also fails to load
|
|
|
+automatically and it must be specified in the configuration files. In this plugin, in
|
|
|
+In particular, navigation is implemented. A typical configuration will contain a string:
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="klish"/>
|
|
|
+```
|
|
|
+
|
|
|
+The `PLUGIN` tag cannot contain other nested tags.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `name`
|
|
|
+
|
|
|
+The attribute defines the name by which the plugin will be recognized within the files
|
|
|
+configurations. When `ACTION` refers to a character, it can be specified simply as follows
|
|
|
+symbol name, and can be specified in which plugin to look for the symbol.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="my_sym"\>
|
|
|
+
|
|
|
+<ACTION sym="my_sym@my_plugin"\>
|
|
|
+```
|
|
|
+
|
|
|
+In the first case, klish will search for "my_sym" in all plugins and use the first one
|
|
|
+found. In the second case the search will be performed only in the plugin
|
|
|
+"my_plugin". In addition, different plugins may contain the same characters and
|
|
|
+specifying the plugin will let you know which character was meant.
|
|
|
+
|
|
|
+If the `id` and `file` attributes are not specified, `name` is also used to
|
|
|
+formation of the plugin file name. The plugin must have the name `kplugin-<name>.so` and
|
|
|
+is located in the `/usr/lib/klish/plugins` directory (if klish has been configured with the
|
|
|
+with `--prefix=/usr`).
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `id`
|
|
|
+
|
|
|
+The attribute is used to form the plugin file name if no attribute is specified
|
|
|
+`file`. The plugin must have the name `kplugin-<id>.so` and be located in the directory
|
|
|
+`/usr/lib/klish/plugins` (if klish has been configured with
|
|
|
+with `--prefix=/usr`).
|
|
|
+
|
|
|
+If the `id` attribute is specified, `name` will not be used to generate the
|
|
|
+plugin file name, but only for identification within configuration files.
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="alias_for_klish" id="klish"\>
|
|
|
+
|
|
|
+<ACTION sym="nav@alias_for_klish"\>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `file`
|
|
|
+
|
|
|
+The full name of the plug-in (shared library) file can be specified explicitly
|
|
|
+Type. If the `file` attribute is specified, no other attributes will be specified
|
|
|
+will be used to form the plugin file name, and the value of
|
|
|
+`file` "as is" and passed to the dlopen() function. This means that there can be
|
|
|
+either an absolute path or just a file name, but in this case the file
|
|
|
+must be located along the standard paths used when searching for a shared
|
|
|
+libraries.
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="my_plugin" file="/home/ttt/my_plugin.so"/>
|
|
|
+
|
|
|
+<ACTION sym="my_sym@my_plugin"\>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+#### Data inside the tag
|
|
|
+
|
|
|
+The data inside the `PLUGIN` tag can be processed by the initialization function
|
|
|
+plugin. The format of the data is left to the discretion of the plugin itself. For example,
|
|
|
+settings for the plug-in can be specified as data.
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="sysrepo">
|
|
|
+JuniperLikeShow = y
|
|
|
+FirstKeyWithStatement = n
|
|
|
+MultiKeysWithStatement = y
|
|
|
+Colorize = y
|
|
|
+</PLUGIN>.
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+### HOTKEY
|
|
|
+
|
|
|
+To make it easier to work in the command line interface, for commonly used
|
|
|
+hotkeys can be set for commands. A hot key is defined with
|
|
|
+using the `HOTKEY' tag.
|
|
|
+
|
|
|
+Hotkeys require support in the client program to work, which is
|
|
|
+connects to the klishd server. The klish client has this support.
|
|
|
+
|
|
|
+The `HOTKEY` tag cannot have nested tags. Any additional data
|
|
|
+within the tag are not provided.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `key`
|
|
|
+
|
|
|
+The attribute defines what the operator must press to activate the hot
|
|
|
+keys. Combinations with the "Ctrl" key are supported. For example `^Z` means,
|
|
|
+that the "Ctrl" and "Z" key combination must be pressed.
|
|
|
+
|
|
|
+```
|
|
|
+<HOTKEY key="^Z" cmd="exit"\>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `cmd`
|
|
|
+
|
|
|
+The attribute defines what action will be performed when the operator is pressed
|
|
|
+hotkey. The `cmd` attribute value is parsed according to the same rules as
|
|
|
+any other command manually entered by the operator.
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="exit" help="Exit view or shell">
|
|
|
+<ACTION sym="nav">pop</ACTION>
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+<HOTKEY key="^Z" cmd="exit"\>
|
|
|
+```
|
|
|
+
|
|
|
+The command used as the value of the `cmd` attribute must be defined
|
|
|
+in the configuration files. This example will execute the previously defined command
|
|
|
+`exit` when the "Ctrl^Z" keyboard shortcut is pressed.
|
|
|
+
|
|
|
+
|
|
|
+### ACTION
|
|
|
+
|
|
|
+The `ACTION` tag specifies the action to be performed. Typical
|
|
|
+tag usage - inside the `COMMAND` command. When entering an operator
|
|
|
+of the corresponding command, the actions defined in `ACTION` will be executed.
|
|
|
+
|
|
|
+The basic attribute of `ACTION` is `sym`. An action can only be performed by
|
|
|
+symbols (functions) defined in plugins. The `sym` attribute refers to such a
|
|
|
+symbol.
|
|
|
+
|
|
|
+Actions can be performed by more than just a command. The following is a list of tags,
|
|
|
+within which `ACTION` may occur:
|
|
|
+
|
|
|
+* `ENTRY` - what `ACTION` will be used for is determined by the `ENTRY` parameters.
|
|
|
+* `COMMAND` - the action defined in `ACTION` is performed when an operator is entered
|
|
|
+of the appropriate command.
|
|
|
+* `PARAM` - same as for `COMMAND`.
|
|
|
+* `PTYPE` - `ACTION` defines actions to check the value of the entered
|
|
|
+by the operator of the parameter having the corresponding type.
|
|
|
+
|
|
|
+There can be several elements within the listed elements at the same time
|
|
|
+`ACTION`. Let's call it an `ACTION` element block. Actions are performed
|
|
|
+sequentially, one after the other, unless otherwise defined by the `exec_on` attribute.
|
|
|
+
|
|
|
+Multiple action blocks can be defined within a single command. These are
|
|
|
+is possible if the command has parameter branching or optional parameters.
|
|
|
+A block is defined as actions defined within a single element. Actions,
|
|
|
+defined in different elements, including nested elements, belong to different blocks.
|
|
|
+Only one block of actions is always performed.
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="cmd1">
|
|
|
+<ACTION sym="sym1"\>
|
|
|
+<SWITCH min="0">
|
|
|
+<COMMAND name="opt1">
|
|
|
+<ACTION sym="sym2"\>
|
|
|
+</COMMAND>.
|
|
|
+<COMMAND name="opt2"\>
|
|
|
+<PARAM name="opt3" ptype="/STRING">
|
|
|
+<ACTION sym="sym3"\>
|
|
|
+</PARAM>
|
|
|
+</SWITCH>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The example declares the command "cmd1", which has three alternatives (specified can be
|
|
|
+only one of three) optional parameters. The search for actions to be performed goes
|
|
|
+from end to beginning when parsing the entered command line.
|
|
|
+
|
|
|
+So if the operator entered
|
|
|
+command `cmd1`, the parsing engine will recognize the command named "cmd1" and will
|
|
|
+search for `ACTION` directly in this element. An `ACTION` with the character
|
|
|
+{ "sym1".
|
|
|
+
|
|
|
+If the operator entered the `cmd1 opt1` command, the string "opt1" will be recognized,
|
|
|
+as a parameter (aka subcommand) named "opt1". The search starts from the end, so
|
|
|
+`ACTION` with the symbol "sym2" will be found first. As soon as the action block is found,
|
|
|
+no more actions will be searched and "sym1" will not be found.
|
|
|
+
|
|
|
+If the operator entered the `cmd1 opt2` command, the action with the symbol will be found
|
|
|
+"sym1", since the "opt2" element has no nested actions of its own and the search
|
|
|
+goes upstairs to the parent elements.
|
|
|
+
|
|
|
+If the operator entered the `cmd1 arbitrary_string` command, an action with the
|
|
|
+with the symbol "sym3".
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `sym`
|
|
|
+
|
|
|
+The attribute refers to a symbol (function) from the plugin. This function will be executed when
|
|
|
+`ACTION` execution. The value can be a character name, e.g.
|
|
|
+`sym="my_sym"`. In this case, the search for the symbol will be performed over all the
|
|
|
+loaded plug-ins. If you specify a plugin in which you want to search for a symbol, e.g.
|
|
|
+`sym="my_sym@my_plugin"`, then other plugins will not be searched.
|
|
|
+
|
|
|
+Different situations may benefit from different approaches, relative to the
|
|
|
+whether to specify a plugin name for the symbol. On the one hand, several plugins
|
|
|
+can contain characters with the same name and for unambiguous identification
|
|
|
+symbol, specifying the plugin will be mandatory. In addition, when specifying a plugin
|
|
|
+the search for a symbol will be a little faster. On the other hand, you could write
|
|
|
+some universal commands that specify characters without belonging to the
|
|
|
+plugin. Then multiple plugins can implement an "interface", i.e. all the
|
|
|
+the symbols used, and their actual content will depend on which
|
|
|
+plug-in loaded.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `lock`
|
|
|
+
|
|
|
+> Attention: the attribute has not yet been implemented
|
|
|
+
|
|
|
+Some actions require atomicity and exclusive access to the resource. When
|
|
|
+This is not automatically ensured when working in klish. Two operators can
|
|
|
+independently, but run the same command at the same time. For
|
|
|
+ensuring atomicity or/and exclusive access to the resource may
|
|
|
+`lock` locks are used. The locks in klish are named.
|
|
|
+The `lock` attribute specifies the lock with which name the `ACTION` will capture when the
|
|
|
+fulfillment. For example `lock="my_lock"`, where "my_lock" is the name of the lock. Capture
|
|
|
+locks with one name have no effect on locks with another name. Thus
|
|
|
+Thus, not only one global blocking can be realized in the system, but also
|
|
|
+Several separate ones, based, for example, on which resource protects the
|
|
|
+lockdown.
|
|
|
+
|
|
|
+If the lock is captured by one process, another process, when attempting to
|
|
|
+capture the same blockage, will suspend its execution until the release of the
|
|
|
+lockdowns.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `in`
|
|
|
+
|
|
|
+The attribute indicates whether the action can accept data via standard input
|
|
|
+(stdin) from the user. Possible values are `true`, `false`, `tty`.
|
|
|
+The default value is `false`.
|
|
|
+A value of `false` means that the action does not accept data through the
|
|
|
+standard input. The value `true` means that the action accepts data through the
|
|
|
+standard input. The value `tty` means that the action accepts data through the
|
|
|
+standard input and, in this case, standard input is terminal.
|
|
|
+
|
|
|
+When an action is performed, the client is made aware of the status of the standardized
|
|
|
+input and, according to it, waits for input from the user or not.
|
|
|
+
|
|
|
+If the command involves sequentially performing several actions at once,
|
|
|
+and at least one action has an attribute with the value `tty`, it is considered that the entire
|
|
|
+command has the `tty` attribute. If there are no actions with the attribute value in the command
|
|
|
+`tty`, then an attribute with the value `true` is looked for. If any action has
|
|
|
+value of the `true` attribute, then the whole command has the `true` attribute. Otherwise
|
|
|
+case, the command has the `false` attribute.
|
|
|
+
|
|
|
+If the user has sent not just one command but a chain of commands for execution
|
|
|
+(via the `|` sign), then the following logic applies to notify the client,
|
|
|
+whether it is required to receive standard input. If any command in the chain has
|
|
|
+value of the `tty` attribute, then standard input is required. If the first command in
|
|
|
+chain has the `true` attribute, then standard input is required. Otherwise
|
|
|
+standard input is not required.
|
|
|
+
|
|
|
+When performing the action, the serving server can create a pseudo-terminal and
|
|
|
+provide it to the action as a standard input. Will the standard
|
|
|
+input by a pseudo-terminal or not is determined by whether the standard input on the
|
|
|
+to the client side by the terminal or not. This information is transmitted from the client
|
|
|
+to the server in the status word.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `out`
|
|
|
+
|
|
|
+The attribute indicates whether the action outputs data via standard output (stdout).
|
|
|
+Possible values are `true`, `false`, `tty`.
|
|
|
+The default value is `true`.
|
|
|
+A value of `false` means that the action does not output data through the
|
|
|
+standard output. A value of `true` means that the action outputs data through the
|
|
|
+standard output. The value `tty` means that the action outputs data via the
|
|
|
+standard output and, in doing so, the standard output is terminal.
|
|
|
+
|
|
|
+When an action is performed, the client is made aware of the status of the standardized
|
|
|
+output and, in accordance with it, puts the standard output into the mode
|
|
|
+raw terminal or not.
|
|
|
+
|
|
|
+Typically, a text client runs a pager on its side to process the output
|
|
|
+of each command. If the command attribute has the value `tty`, the pager does not
|
|
|
+is launched. It is assumed that an interactive command is being executed.
|
|
|
+
|
|
|
+If the command involves sequentially performing several actions at once,
|
|
|
+and at least one action has an attribute with the value `tty`, it is considered that the entire
|
|
|
+command has the `tty` attribute. If there are no actions with the attribute value in the command
|
|
|
+`tty`, then an attribute with the value `true` is looked for. If any action has
|
|
|
+value of the `true` attribute, then the whole command has the `true` attribute. Otherwise
|
|
|
+case, the command has the `false` attribute.
|
|
|
+
|
|
|
+If the user has sent not just one command but a chain of commands for execution
|
|
|
+(via the `|` sign), then the following logic applies to notify the client of the
|
|
|
+status of the standard output. If any command in the chain has
|
|
|
+value of the `tty` attribute, then the "interactivity" flag is passed to the client. В
|
|
|
+otherwise the client works as usual.
|
|
|
+
|
|
|
+When performing the action, the serving server can create a pseudo-terminal and
|
|
|
+provide its action as a standard output. Will the standard
|
|
|
+output by a pseudoterminal or not is determined by whether the standard output is a
|
|
|
+on the client side by the terminal and whether the command attribute is set to
|
|
|
+`tty`. Information about whether the standard client-side output is the following
|
|
|
+terminal is transmitted from the client to the server in a status word.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `permanent`
|
|
|
+
|
|
|
+The klish system can be run in "dry-run" mode, when all activities are not
|
|
|
+will actually be executed, and their return code will always have the value of
|
|
|
+"success". This mode can be used for testing, for checking
|
|
|
+correctness of incoming data, etc.
|
|
|
+
|
|
|
+However, some characters must always be executed, regardless of mode.
|
|
|
+An example of such a symbol is the navigation function. I.e. change
|
|
|
+the current session path is always needed, regardless of the mode of operation.
|
|
|
+
|
|
|
+The `permanent` flag can change the behavior of a dry-run action.
|
|
|
+The possible values of the attribute are `true` and `false`. The default is `false`, i.e.
|
|
|
+action is not "permanent" and will be disabled in dry-run mode.
|
|
|
+
|
|
|
+Symbols, when declared in a plugin, already have a persistence feature. Symbol
|
|
|
+may be involuntarily declared permanent, involuntarily declared
|
|
|
+non-permanent, or the plugin can leave the decision on permanence to the
|
|
|
+user. If the persistence flag is declared forcibly in the plugin, then
|
|
|
+setting the `permanent` attribute will not affect anything. It can't
|
|
|
+Override the persistence flag enforced within the plugin.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `sync`
|
|
|
+
|
|
|
+A character can be executed "synchronously" or "asynchronously". In synchronous mode the code
|
|
|
+symbol will be run directly in the context of the current process - the klishd server. В
|
|
|
+asynchronous mode, a separate (fork()) will be spawned to run the symbol code.
|
|
|
+Process. Running the symbol in asynchronous mode is safer, since
|
|
|
+errors in the code will not affect the klishd process. It is recommended to use
|
|
|
+asynchronous mode.
|
|
|
+
|
|
|
+The possible values of the attribute are `true` and `false`. The default is `false`, i.e.
|
|
|
+symbol will be executed asynchronously.
|
|
|
+
|
|
|
+Symbols, when declared in a plugin, already have a synchronicity feature. Symbol
|
|
|
+can be forced to be declared synchronous, asynchronous, or the plugin can
|
|
|
+leave the synchronization decision up to the user. If the consistency flag
|
|
|
+is declared forcibly in the plugin, then setting the `sync` attribute will have no effect
|
|
|
+on anything. It cannot override the synchronicity flag by forcing a
|
|
|
+defined within the plugin.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `update_retcode`
|
|
|
+
|
|
|
+A single command can contain multiple `ACTION` elements. This is called
|
|
|
+"action block." Each of the actions has its own code
|
|
|
+return code. However, the command as a whole must also have a return code and this code is
|
|
|
+must be a single value, not an array.
|
|
|
+
|
|
|
+By default, `ACTION` actions are executed sequentially and as soon as one of the
|
|
|
+actions will return an error, block execution will stop and the common return code will be
|
|
|
+is considered an error. If no action from the block has returned an error, the following code is used
|
|
|
+return code of the last action in the block is considered to be the return code of the last action in the block.
|
|
|
+
|
|
|
+Sometimes it is required that regardless of the return code of a particular action
|
|
|
+execution of the block continued. For this purpose the attribute
|
|
|
+`update_retcode`. The attribute can take the value `true` or `false`. By
|
|
|
+The default is `true`. This means that the return code of the current action
|
|
|
+affects the total return code. At this point, the total return code will be assigned to a
|
|
|
+value of the current return code. If the flag value is set to
|
|
|
+`false`, then the current return code is ignored and will have no effect on the
|
|
|
+formation of a common return code. Also the execution of the action block will not
|
|
|
+interrupted in case of an error at the stage of execution of the current action.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `exec_on`
|
|
|
+
|
|
|
+When performing a block of actions (multiple `ACTION` within one item),
|
|
|
+actions are performed sequentially until all actions have been performed,
|
|
|
+or until one of the actions returns an error. In this case the block execution
|
|
|
+is interrupted. However, this behavior can be controlled by the `exec_on` attribute.
|
|
|
+The attribute can take the following values:
|
|
|
+
|
|
|
+* `success` - the current action will be sent for execution if the value of
|
|
|
+of the total return code at this point is "success".
|
|
|
+* `fail` - the current action will be sent to execution if the value of
|
|
|
+the common return code at this point is "error".
|
|
|
+* `always` - the current action will be executed regardless of the common code
|
|
|
+refunds.
|
|
|
+* `never` - the action will not be performed under any conditions.
|
|
|
+
|
|
|
+The default value is `success`, i.e. actions are performed if
|
|
|
+there were no errors before.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="printl">1</ACTION>
|
|
|
+<ACTION sym="printl" exec_on="never">2</ACTION>
|
|
|
+<ACTION sym="printl">3</ACTION>
|
|
|
+<ACTION sym="printl" exec_on="fail">4</ACTION>
|
|
|
+<ACTION sym="script">/bin/false</ACTION>
|
|
|
+<ACTION sym="printl">6</ACTION>
|
|
|
+<ACTION sym="printl" exec_on="fail" update_retcode="false">7</ACTION>
|
|
|
+<ACTION sym="printl" exec_on="always">8</ACTION>
|
|
|
+<ACTION sym="printl" exec_on="fail">9</ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+This example will print to the screen:
|
|
|
+
|
|
|
+```
|
|
|
+1
|
|
|
+3
|
|
|
+7
|
|
|
+8
|
|
|
+```
|
|
|
+
|
|
|
+The string "1" will be printed because at the beginning of the action block execution the common code
|
|
|
+return is taken equal to the value "success", as well as the value of `exec_on` on the
|
|
|
+defaults to `success`.
|
|
|
+
|
|
|
+Line "2" will not be printed because `on_exec="never"`, i.e., do not execute at either
|
|
|
+under what conditions.
|
|
|
+
|
|
|
+Line "3" will be executed because the previous action (line "1") was executed
|
|
|
+successfully.
|
|
|
+
|
|
|
+Line "4" will not execute because the condition `on_exec="fail"` is present, and with this
|
|
|
+the previous action "3" was executed successfully and set the common return code to
|
|
|
+the meaning of "success."
|
|
|
+
|
|
|
+Line "5" will execute and set the total return code to "error".
|
|
|
+
|
|
|
+Line "6" will not execute because the current total return code is equal to the value of
|
|
|
+"error", and the line should only execute if the generic return code is successful.
|
|
|
+
|
|
|
+Line "7" is printed because the condition `on_exec="fail"` is set, the current generic code is
|
|
|
+return is indeed equal to "error". Note that although the action itself
|
|
|
+will be executed successfully, the total return code will not be changed, because the used
|
|
|
+`update_retcode="false"` attribute.
|
|
|
+
|
|
|
+Line "8" is printed because the condition `on_exec="always"` stands for
|
|
|
+execute the action regardless of the current total return code.
|
|
|
+
|
|
|
+Line "9" will not be output because line "8" changed the common return code to
|
|
|
+the meaning of "success."
|
|
|
+
|
|
|
+
|
|
|
+#### Data inside the tag
|
|
|
+
|
|
|
+The data inside the `ACTION` tag is used at the discretion of the symbol itself,
|
|
|
+specified by the `sym` attribute. An example is the `script` symbol from the plugin
|
|
|
+`script`. This character uses the data inside the tag as script code that
|
|
|
+he must fulfill.
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="ls" help="List root dir">
|
|
|
+<ACTION sym="script">
|
|
|
+ls /
|
|
|
+</ACTION>.
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+<COMMAND name="pytest" help="Test for Python script">
|
|
|
+<ACTION sym="script">#!/usr/bin/python
|
|
|
+import os
|
|
|
+print('ENV', os.getenv('KLISH_COMMAND')))
|
|
|
+</ACTION>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+Note that the shebang `#!/usr/bin/python` is specified in the "pytest" command,
|
|
|
+which specifies which interpreter to use to execute the script.
|
|
|
+
|
|
|
+
|
|
|
+### ENTRY
|
|
|
+
|
|
|
+> Normally, the `ENTRY` tag is not used explicitly in configuration files.
|
|
|
+> However, the tag is the base tag for most other tags and most of its
|
|
|
+> attributes are inherited.
|
|
|
+
|
|
|
+If you look at the internal realization of klish, you can't find the whole set there
|
|
|
+tags available when writing an XML configuration. There is actually a basic
|
|
|
+`ENTRY` element, which implements the functions of most other tags. Element
|
|
|
+"transforms" into other tags depending on the value of its attributes. The following
|
|
|
+tags by internal implementation are the `ENTRY` element:
|
|
|
+
|
|
|
+* [`VIEW`](#view)
|
|
|
+* [`COMMAND`](#command)
|
|
|
+* [`FILTER`](#filter)
|
|
|
+* [`PARAM`](#param)
|
|
|
+* [`PTYPE`](#ptype)
|
|
|
+* [`COND`](#cond)
|
|
|
+* [`HELP`](#help)
|
|
|
+* [`COMPL`](#compl)
|
|
|
+* [`PROMPT`](#prompt)
|
|
|
+* [`SWITCH`](#switch)
|
|
|
+* [`SEQ`](#seq)
|
|
|
+
|
|
|
+In this section, the attributes of the `ENTRY` element will be discussed in some detail,
|
|
|
+which are often attributes of other elements as well. The other elements will be
|
|
|
+refer to these descriptions in the `ENTRY` section. Configuration examples, when describing
|
|
|
+attributes, are not necessarily based on the `ENTRY` element, but use others,
|
|
|
+the most typical tags are "wrappers".
|
|
|
+
|
|
|
+The basis of the `ENTRY` element are the attributes that define the features of its behavior and the
|
|
|
+the ability to nest other `ENTRY` elements inside the `ENTRY` element. Thus
|
|
|
+This is how the entire configuration scheme is built.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `name`
|
|
|
+
|
|
|
+The `name` attribute is the element identifier. Among the elements of the current level
|
|
|
+nesting, the identifier must be unique. In different branches of the scheme can
|
|
|
+elements with the same name. It is important that the absolute
|
|
|
+element path, i.e. a combination of the name of the element itself and the names of all its "ancestors".
|
|
|
+
|
|
|
+For the `COMMAND` tag, the attribute also serves as a positional parameter value, if not a
|
|
|
+attribute `value` is defined. That is, the operator enters a string equal to the element name
|
|
|
+`COMMAND` to invoke this command.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `value`
|
|
|
+
|
|
|
+If the command identifier (`name` attribute) is different from the command name for a
|
|
|
+operator, then the `value` attribute contains the command name as it is presented
|
|
|
+to the operator.
|
|
|
+
|
|
|
+Used for the following tags:
|
|
|
+
|
|
|
+* `COMMAND`
|
|
|
+* `PARAM`
|
|
|
+* `PTYPE`
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="cmdid" value="next">
|
|
|
+```
|
|
|
+
|
|
|
+In the example, the command identifier is "cmdid". It will be used if
|
|
|
+you need to create a reference to this element inside the XML configs. But the user, in order to
|
|
|
+run the command to execute it, at the command line enters the text `next`.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `help`
|
|
|
+
|
|
|
+When using the command line, the operator can get a hint on possible
|
|
|
+commands, parameters and their purpose. In the klish client the tooltip will be displayed
|
|
|
+when the `?` key is pressed. The easiest way to set the tooltip text for an element
|
|
|
+- is to specify the value of the `help` attribute.
|
|
|
+
|
|
|
+The following tags support the `help` attribute:
|
|
|
+
|
|
|
+* `COMMAND`
|
|
|
+* `PARAM`
|
|
|
+* `PTYPE`
|
|
|
+
|
|
|
+The hint specified with the `help` attribute is static. The other
|
|
|
+The way to specify a hint for an element is to create a nested `HELP` element.
|
|
|
+The `HELP` element generates the hint text dynamically.
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="simple" help="Command with static help"/>
|
|
|
+
|
|
|
+<COMMAND name="dyn">
|
|
|
+<HELP>.
|
|
|
+<ACTION sym="script">
|
|
|
+ls -la "/etc/passwd"
|
|
|
+</ACTION>.
|
|
|
+<HELP>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+If both the `help` attribute and the nested element are specified for an element at the same time
|
|
|
+`HELP`, then the dynamic nested element `HELP` will be used, and the attribute
|
|
|
+will be ignored.
|
|
|
+
|
|
|
+The `PTYPE` element has its own hints. Both static attribute and dynamic attribute
|
|
|
+element. These hints will be used for the `PARAM` parameter using the
|
|
|
+this data type, in the case when neither an attribute nor an
|
|
|
+`HELP` dynamic element.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `container`
|
|
|
+
|
|
|
+"Container" in klish terms is an element that contains other
|
|
|
+elements, but is not visible to the operator. That is, this element is not
|
|
|
+is matched to no positional parameters when parsing the entered command line.
|
|
|
+lines. It only organizes other elements. Examples of containers are
|
|
|
+`VIEW`, `SWITCH`, `SEQ`. The `VIEW` tag organizes commands in the scope, but
|
|
|
+element itself is not a command or parameter for the operator. The operator cannot
|
|
|
+enter the name of this item on the command line, it can go straight to the
|
|
|
+elements nested in a container (if they are not containers themselves).
|
|
|
+
|
|
|
+The `SWITCH` and `SEQ` elements are also not visible to the operator. They define how the
|
|
|
+nested elements are processed.
|
|
|
+
|
|
|
+The `container` attribute can take the values `true` or `false`. By default
|
|
|
+is used `false`, i.e. the element is not a container. In this case it is necessary to
|
|
|
+note that for all elements - wrappers inherited from `ENTRY`, the value of
|
|
|
+of the attribute is pre-prescribed to the correct value. I.e. use the attribute in
|
|
|
+of real configs is usually not necessary. Only in specific cases does it
|
|
|
+is really required.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `mode`
|
|
|
+
|
|
|
+The `mode` attribute defines how the nested elements will be handled when the
|
|
|
+parsing the entered command line. Possible values:
|
|
|
+
|
|
|
+* `sequence` - nested elements will be matched by the entered operator
|
|
|
+"words" sequentially, one after the other. Thus, all nested elements
|
|
|
+can take on values when parsed.
|
|
|
+* `switch` - only one of the nested elements should be matched to the input from the
|
|
|
+an operator. It is a selection of one out of many. Items that have not been selected are not
|
|
|
+will get values.
|
|
|
+* `empty` - an element cannot have nested elements.
|
|
|
+
|
|
|
+So the `VIEW` element is forced to have the `mode="switch"` attribute, assuming that the
|
|
|
+it contains commands inside it and should not be possible in one line
|
|
|
+enter many commands at once one after another. The operator selects at the moment
|
|
|
+only one team.
|
|
|
+
|
|
|
+The `COMMAND` and `PARAM` elements have a default setting of `mode="sequence"`, so
|
|
|
+As most often inside them are placed parameters that must be entered in one
|
|
|
+after the other. However, it is possible to override the `mode` attribute in tags
|
|
|
+`COMMAND`, `PARAM`.
|
|
|
+
|
|
|
+The `SEQ` and `SWITCH` elements are containers and are created only to
|
|
|
+change the way nested elements are processed. The `SEQ` element has
|
|
|
+`mode="sequence"`, the `SWITCH` element has `mode="switch"`.
|
|
|
+
|
|
|
+The following are examples of branching within a command:
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 1 -->
|
|
|
+<COMMAND name="cmd1">
|
|
|
+<PARAM name="param1" ptype="/INT"/>
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The command defaults to `mod="sequence"`, so the operator would have to enter
|
|
|
+both parameters, one after the other.
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 2 -->
|
|
|
+<COMMAND name="cmd2" mode="switch">
|
|
|
+<PARAM name="param1" ptype="/INT"/>
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The value of the `mode` attribute is overridden, so the operator would have to enter
|
|
|
+only one of the parameters. Which of the parameters corresponds to the entered characters
|
|
|
+in this case will be determined as follows. First it is checked for
|
|
|
+correctness of the first parameter "param1". If the string corresponds to the integer format
|
|
|
+numbers, then the parameter takes its value and the second parameter is not checked on the
|
|
|
+correspondence, although it would also fit, since the `STRING` type can contain both the
|
|
|
+numbers. Thus, when selecting one parameter out of many, the order of specification is
|
|
|
+parameters are important.
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 3 -->
|
|
|
+<COMMAND name="cmd3">
|
|
|
+<SWITCH>.
|
|
|
+<PARAM name="param1" ptype="/INT"/>
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</SWITCH>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+This example is identical to example "2". Only instead of the `mode` attribute the following is used
|
|
|
+nested tag `SWITCH`. The entry in example "2" is shorter, in example "3" it is clearer.
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 4 -->
|
|
|
+<COMMAND name="cmd4">
|
|
|
+<SWITCH>.
|
|
|
+<PARAM name="param1" ptype="/INT">
|
|
|
+<PARAM name="param3" ptype="/STRING">
|
|
|
+<PARAM name="param4" ptype="/STRING">
|
|
|
+</PARAM>
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</SWITCH>.
|
|
|
+<PARAM name="param5" ptype="/STRING"/>
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+This demonstrates how command line arguments are parsed. When selected
|
|
|
+parameter "param1", then further its nested elements "param3" and
|
|
|
+"param4" and then only the `SWITCH` element following the `SWITCH` element "param5". Parameter
|
|
|
+"param2" is not used in any way.
|
|
|
+
|
|
|
+If "param2" was selected first, then "param5" is processed and the
|
|
|
+the process is complete.
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 5 -->
|
|
|
+<COMMAND name="cmd5">
|
|
|
+<SWITCH>.
|
|
|
+<SEQ>.
|
|
|
+<PARAM name="param1" ptype="/INT">
|
|
|
+<PARAM name="param3" ptype="/STRING">
|
|
|
+<PARAM name="param4" ptype="/STRING">
|
|
|
+</SEQ>.
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</SWITCH>.
|
|
|
+<PARAM name="param5" ptype="/STRING"/>
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The example is completely similar to the behavior of example "4". Only instead of nesting
|
|
|
+The `SEQ' tag is used, which says that if the first parameter has been selected.
|
|
|
+from the sequential parameter block, the other parameters must also be entered as one
|
|
|
+one after another.
|
|
|
+
|
|
|
+```
|
|
|
+<!-- Example 6 -->
|
|
|
+<COMMAND name="cmd6">
|
|
|
+<COMMAND name="cmd6_1">
|
|
|
+<PARAM name="param3" ptype="/STRING">
|
|
|
+</COMMAND>.
|
|
|
+<PARAM name="param1" ptype="/INT"/>
|
|
|
+<PARAM name="param2" ptype="/STRING"/>
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The example shows a nested "subcommand" named "cmd1_6". Here the subcommand
|
|
|
+is no different from a parameter, except that the comparison criterion is
|
|
|
+command line arguments to the `COMMAND' command is to make the entered
|
|
|
+argument matched the name of the command.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `purpose`
|
|
|
+
|
|
|
+Some nested elements must have a special value. For example, within
|
|
|
+`VIEW` can be defined an element that generates the invitation text for the
|
|
|
+operator. To separate the item to generate the prompt from nested commands,
|
|
|
+it is necessary to give it a special attribute. Later, when the klishd server should
|
|
|
+will get the user prompt for this `VIEW`, the code will look through the
|
|
|
+nested `VIEW` elements and will select an element that is specifically for this purpose
|
|
|
+intended.
|
|
|
+
|
|
|
+The `purpose` attribute sets the element to a special purpose. Possible
|
|
|
+Appointments:
|
|
|
+
|
|
|
+* `common` - there is no special purpose. This is what the normal tags have
|
|
|
+attribute value.
|
|
|
+* `ptype` - element defines the type of the parent parameter. Tag `PTYPE`.
|
|
|
+* `prompt` - the element is used to generate a user prompt for the
|
|
|
+of the parent element. Tag `PROMPT`. The parent element is `VIEW`.
|
|
|
+* `cond` - the element checks the condition and, if it fails, the parent element
|
|
|
+becomes unavailable to the operator. Tag `COND`. Not currently implemented.
|
|
|
+* `completion` - the element generates possible auto-completions for the parent one
|
|
|
+element. Tag `COMPL`.
|
|
|
+* `help` - the element generates a hint for the parent element. Tag `HELP`.
|
|
|
+
|
|
|
+Normally, the `purpose` attribute is not used directly in configuration files, so
|
|
|
+as each special purpose has its own tag, which is more visual.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `ref`
|
|
|
+
|
|
|
+A schema element can be a reference to another schema element. Creating element "#1",
|
|
|
+which is a reference to element "#2" is equivalent to the fact that element "#2" will be
|
|
|
+is declared in the place of the scheme where element "#1" is located. It would be more correct to say,
|
|
|
+that this is equivalent to creating a copy of element "#2" at the location where the defined
|
|
|
+element "#1".
|
|
|
+
|
|
|
+If the element is a reference, the `ref` attribute is defined in the element. The value of the attribute
|
|
|
+- reference to the target schema element.
|
|
|
+
|
|
|
+```
|
|
|
+<KLISH>.
|
|
|
+
|
|
|
+<PTYPE name="ptype1">
|
|
|
+<ACTION sym="INT"/>
|
|
|
+</PTYPE>.
|
|
|
+
|
|
|
+<VIEW name="view1">
|
|
|
+<COMMAND name="cmd1"/>
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view2">
|
|
|
+<VIEW ref="/view1"/>.
|
|
|
+<COMMAND name="cmd2">
|
|
|
+<PARAM name="param1" ptype="/ptype1"/>
|
|
|
+<PARAM name="param2">
|
|
|
+<PTYPE ref="/ptype1"/>
|
|
|
+</PARAM>
|
|
|
+</COMMAND>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view3">
|
|
|
+<COMMAND ref="/view2/cmd2"/>
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view4">
|
|
|
+<COMMAND name="do">
|
|
|
+<VIEW ref="/view1"/>.
|
|
|
+</COMMAND>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+</KLISH>.
|
|
|
+```
|
|
|
+
|
|
|
+In the example, "view2" contains a reference to "view1", which is equivalent to declaring a copy of the
|
|
|
+"view1" inside "view2." Which in turn means that "cmd1" will become
|
|
|
+is available in "view2".
|
|
|
+
|
|
|
+Another `VIEW` named "view3" declares a reference to the command "cmd2". Thus
|
|
|
+thus an individual command becomes available inside "view3".
|
|
|
+
|
|
|
+Parameters "param1" and "param2" have the same type `/ptype1`. Reference to type
|
|
|
+can be spelled out using the `ptype` attribute, or using the nested
|
|
|
+tag `PTYPE`, which is a reference to the previously declared `PTYPE`. As a result
|
|
|
+types of two declared parameters are completely equivalent.
|
|
|
+
|
|
|
+In the last example, the reference to `VIEW` is enclosed inside the `COMMAND` tag. In this
|
|
|
+In this case it will mean that if we work with "view4", the commands from the
|
|
|
+"view1" will be available with the "do" prefix. I.e. if the operator is in
|
|
|
+`VIEW` with the name "view4", then it should write `do cmd1` on the command line,
|
|
|
+to execute the "cmd1" command.
|
|
|
+
|
|
|
+With the help of references, you can organize code reuse. For example
|
|
|
+declare a block of "standard" parameters and then use the links to insert them
|
|
|
+this block into all commands where parameters are repeated.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `restore`
|
|
|
+
|
|
|
+Suppose the current path consists of several levels. I.e. the operator entered the
|
|
|
+nested `VIEW`. While in the nested `VIEW`, the operator has access to commands that are not
|
|
|
+only of the current `VIEW`, but also of all parent `VIEW`. The operator enters the command,
|
|
|
+defined in the parent `VIEW`. The `restore` attribute determines whether the
|
|
|
+changed the current path before executing the command.
|
|
|
+
|
|
|
+The possible values of the `restore` attribute are `true` or `false`. By default
|
|
|
+`false` is used. This means that the command will be executed and the current path will be
|
|
|
+will remain the same. If `restore="true"`, before the command is executed, the current
|
|
|
+the path will be changed. The nested path levels will be stripped down to the level of that `VIEW`, in the
|
|
|
+where the entered command is defined.
|
|
|
+
|
|
|
+The `restore` attribute is used in the `COMMAND` element.
|
|
|
+
|
|
|
+Behavior with recovery of the team's native path can be used in the
|
|
|
+system, where the configuration mode is implemented according to the principle of routers
|
|
|
+"Cisco". In this mode, it is not possible to switch to one configuration section.
|
|
|
+by exiting in advance from another - neighboring section. For this purpose it is necessary to
|
|
|
+change the current path, rise to the level of the command being entered, and then immediately
|
|
|
+move to a new section, but already on the basis of the current path corresponding to the
|
|
|
+the command to enter a new section.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `order`
|
|
|
+
|
|
|
+The `order` attribute determines whether the order is important when entering declared one after another
|
|
|
+optional parameters. Suppose three consecutive optional parameters are declared
|
|
|
+parameter. The default is `order="false"` and this means that the operator can
|
|
|
+enter these three parameters in any order. Let's say the third one first, then
|
|
|
+the first one, followed by the second one. If the `order="true"` flag is set on the second parameter, then
|
|
|
+Having entered the second parameter first, the operator will not be able to enter the first parameter after it.
|
|
|
+Only the third parameter will remain available to him.
|
|
|
+
|
|
|
+The `order` attribute is used in the `PARAM` element.
|
|
|
+
|
|
|
+
|
|
|
+#### Attribute `filter`
|
|
|
+
|
|
|
+> Attention: Filters are not working yet.
|
|
|
+
|
|
|
+Some commands are filters. This means that they cannot
|
|
|
+to be used independently. Filters only process the output of other commands.
|
|
|
+Filters are specified after the main command and the separator character `|`. Filter
|
|
|
+cannot be used before the first `|` character. In this case, a command that is not
|
|
|
+which is a filter cannot be used after the `|` symbol.
|
|
|
+
|
|
|
+The `filter` attribute can take the values `true` or `false`. By default
|
|
|
+`filter="false"` is used. This means that the command is not a filter.
|
|
|
+If `filter="true"`, the command is declared to be a filter.
|
|
|
+
|
|
|
+The `filter` attribute is rarely used explicitly in configs. The `FILTER` tag is introduced,
|
|
|
+which declares a command that is a filter. In addition to the above limitations on
|
|
|
+Using filters, filters are no different from regular commands.
|
|
|
+
|
|
|
+A typical example of a filter is the standard "grep" utility.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes `min` and `max`
|
|
|
+
|
|
|
+The `min` and `max` attributes are used in the `PARAM` element and determine how many
|
|
|
+arguments entered by the operator can be matched to the current parameter.
|
|
|
+
|
|
|
+The `min` attribute specifies the minimum number of arguments that must be
|
|
|
+correspond to the parameter, i.e. must pass the correctness check
|
|
|
+relative to the data type of this parameter. If `min="0"`, then the parameter
|
|
|
+becomes optional. That is, if it is not entered, it is not an error.
|
|
|
+The default is `min="1"`.
|
|
|
+
|
|
|
+The `max` attribute specifies the maximum number of arguments of the same type that are
|
|
|
+can be mapped to a parameter. If the operator enters more than
|
|
|
+arguments than specified in the `max` attribute, then these arguments will not be checked
|
|
|
+for compliance with the current parameter, but may be checked for compliance with the
|
|
|
+other parameters defined after the current one. The default setting is
|
|
|
+`max="1"`.
|
|
|
+
|
|
|
+The `min="0"` attribute can be used in the `COMMAND` element to declare a
|
|
|
+the subcommand is optional.
|
|
|
+
|
|
|
+```
|
|
|
+<PARAM name="param1" ptype="/INT" min="0"/>
|
|
|
+<PARAM name="param2" ptype="/INT" min="3" max="3"/>
|
|
|
+<PARAM name="param3" ptype="/INT" min="2" max="5"/>
|
|
|
+<COMMAND name="subcommand" min="0"/>
|
|
|
+```
|
|
|
+
|
|
|
+In the example, the parameter "param1" is declared optional. Parameter "param2" must
|
|
|
+correspond to exactly three arguments entered by the operator. Parameter "param3"
|
|
|
+can correspond from two to five arguments. Subcommand "subcommand"
|
|
|
+is declared optional.
|
|
|
+
|
|
|
+
|
|
|
+### VIEW
|
|
|
+
|
|
|
+`VIEW` are intended for organizing commands and other configuration items in the
|
|
|
+["visibility-areas"](#visibility-areas). When the operator works with klish,
|
|
|
+the current session path exists. The elements of the path are `VIEW` elements.
|
|
|
+You can change the current path using [navigation commands](#navigation).
|
|
|
+If the statement is in a nested `VIEW`, i.e., the current session path contains the
|
|
|
+several levels, like nested directories in a file system, then the operator
|
|
|
+all commands belonging not only to `VIEW`, which is located on the actual
|
|
|
+the top level of the path, but also all the "previous" `VIEW` that make up the path.
|
|
|
+
|
|
|
+You can create "shadow" `VIEWs that will never become elements of the current one
|
|
|
+paths. These `VIEWs` can be accessed by [links](#links-to-elements) and such a
|
|
|
+to add their contents to the place in the schema where the link is created.
|
|
|
+
|
|
|
+`VIEW` can be defined within the following elements:
|
|
|
+
|
|
|
+* `KLISH
|
|
|
+* `VIEW`
|
|
|
+* `COMMAND`
|
|
|
+* `PARAM`
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `VIEW` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `VIEW`.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<VIEW name="view1">
|
|
|
+<COMMAND name="cmd1"/>
|
|
|
+<VIEW name="view1_2">
|
|
|
+<COMMAND name="cmd2"/>
|
|
|
+</VIEW>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view2">
|
|
|
+<COMMAND name="cmd3"/>
|
|
|
+<VIEW ref="/view1"/>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view3">
|
|
|
+<COMMAND name="cmd4"/>
|
|
|
+<VIEW ref="/view1/view1_2"/>
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view4">
|
|
|
+<COMMAND name="cmd5"/>
|
|
|
+</VIEW>.
|
|
|
+```
|
|
|
+
|
|
|
+The example demonstrates how scopes work in relation to available scopes
|
|
|
+to the command operator.
|
|
|
+
|
|
|
+If the current session path is `/view1`, "cmd1" and "cmd2" are available to the operator.
|
|
|
+
|
|
|
+If the current session path is `/view2`, the commands "cmd1", "cmd2" are available to the operator,
|
|
|
+}, "cmd3".
|
|
|
+
|
|
|
+If the current session path is `/view3`, "cmd2" and "cmd4" are available to the operator.
|
|
|
+
|
|
|
+If the current session path is `/view4`, "cmd5" is available to the operator.
|
|
|
+
|
|
|
+If the current session path is `/view4/view1`, "cmd1" commands are available to the operator,
|
|
|
+"cmd2", "cmd5".
|
|
|
+
|
|
|
+If the current session path is `/view4/{/view1/view1_2}`, the commands available to the operator are
|
|
|
+"cmd2", "cmd5". The curly brackets here indicate the fact that the path element
|
|
|
+can be any `VIEW` and it does not matter if it is nested at the
|
|
|
+schema definition. Inside the curly braces is the unique path of the element
|
|
|
+In the schema. In ["Links not elements"](#links-to-elements), explain
|
|
|
+the difference between the path that uniquely identifies an element within the schema and the current path
|
|
|
+by way of a session.
|
|
|
+
|
|
|
+
|
|
|
+### COMMAND
|
|
|
+
|
|
|
+The `COMMAND` tag declares a command. Such a command can be executed by an operator.
|
|
|
+To map the argument entered by an operator to a command, the following is used
|
|
|
+attribute [`name`](#attribute-name). If the command identifier is required
|
|
|
+within the circuit was different from the name of the command as it appears to the operator,
|
|
|
+then `name` will contain the internal identifier, and the attribute
|
|
|
+[`value`](#attribute-value) "custom" team name. The attributes `name` and
|
|
|
+`value` can contain only one word, no spaces.
|
|
|
+
|
|
|
+A command is not much different from a [`PARAM`](#param) element. A command can
|
|
|
+contain subcommands. I.e. another command can be declared within one command
|
|
|
+command, which is actually the parameter of the first command, only this one
|
|
|
+parameter is identified by a fixed text string.
|
|
|
+
|
|
|
+A typical command contains the [`help`](#attribute-help) hint or
|
|
|
+[`HELP`](#HELP) and, if necessary, a set of nested parameters
|
|
|
+[`PARAM`](#param). The command must also specify the actions
|
|
|
+[`ACTION`](#action) that it performs.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `COMMAND` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`value`](#attribute-value) is a "custom" command name.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`mode`](#attribute-mode) - nested elements processing mode.
|
|
|
+* [`min`](#attributes-min-and-max) - minimum number of command arguments
|
|
|
+strings mapped to the command name.
|
|
|
+* [`max`](#attributes-min-and-max) - maximum number of command arguments
|
|
|
+strings matched to the command name.
|
|
|
+* [`restore`](#attribute-restore) - the restore native flag for the team
|
|
|
+level in the current session path.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `COMMAND`.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<PTYPE name="ptype1">
|
|
|
+<ACTION sym="INT"/>
|
|
|
+</PTYPE>.
|
|
|
+
|
|
|
+<VIEW name="view1">
|
|
|
+
|
|
|
+<COMMAND name="cmd1" help="First command">
|
|
|
+<PARAM name="param1" ptype="/ptype1"/>
|
|
|
+<ACTION sym="sym1"/>
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+<COMMAND name="cmd2">
|
|
|
+<HELP>.
|
|
|
+<ACTION sym="script">
|
|
|
+echo "Second command"
|
|
|
+</ACTION>.
|
|
|
+</HELP>.
|
|
|
+<COMMAND name="cmd2_1" value="sub2" min="0" help="Subcommand">
|
|
|
+<PARAM name="param1" ptype="ptype1" help="Par 1"/>
|
|
|
+</COMMAND>.
|
|
|
+<COMMAND ref="/view1/cmd1"/>
|
|
|
+<PARAM name="param2" ptype="ptype1" help="Par 2"/>
|
|
|
+<ACTION sym="sym2"/>
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+</VIEW>.
|
|
|
+```
|
|
|
+
|
|
|
+The command "cmd1" is the simplest version of the command with a hint, one mandatory
|
|
|
+parameter of type "ptype1" and the action to be performed.
|
|
|
+
|
|
|
+The "cmd2" command is more complex. The hint is generated dynamically. The first
|
|
|
+parameter is an optional subcommand with the "custom" name "sub2"
|
|
|
+and one mandatory nested parameter. I.e., the operator, wishing to use
|
|
|
+subcommand should start its command line this way `cmd2 sub2 ...`.
|
|
|
+If the optional "cmd2_1" subcommand is used, the statement must specify
|
|
|
+value of its mandatory parameter. The second subcommand is a reference to another subcommand
|
|
|
+command. To understand what this would mean, you only have to imagine that on the
|
|
|
+this place fully describes the command to which the link points, i.e. "cmd1".
|
|
|
+The subcommands are followed by a mandatory numeric parameter and the action to be taken
|
|
|
+by the team.
|
|
|
+
|
|
|
+
|
|
|
+### FILTER
|
|
|
+
|
|
|
+The filter is the [`COMMAND`](#command) command with the difference that the command
|
|
|
+filtering cannot be used on its own. It only processes the output
|
|
|
+other commands and can be used after the main command and the separating
|
|
|
+symbol `|`. For more details on how to use filters, see
|
|
|
+["Filters"](#filters).
|
|
|
+
|
|
|
+For the `FILTER` tag, the [`filter`](#attribute-filter) attribute is forced to be set to
|
|
|
+value `true`. Other attributes and features of operation coincide with the element
|
|
|
+[`COMMAND`](#command).
|
|
|
+
|
|
|
+
|
|
|
+### PARAM
|
|
|
+
|
|
|
+The `PARAM` element describes the parameter of the command. The parameter has a type that is specified by
|
|
|
+either by the `ptype` attribute or by the nested element [`PTYPE`](#ptype). When entering
|
|
|
+argument operator, its value is checked by the code of the corresponding `PTYPE` on the
|
|
|
+correctness.
|
|
|
+
|
|
|
+In general, the value for a parameter can be either a string with no spaces,
|
|
|
+or a string with spaces enclosed in quotation marks.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of `PARAM` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`value`](#attribute-value) is an arbitrary value that can
|
|
|
+be analyzed by the `PTYPE` code. For the `COMMAND` element, which is a
|
|
|
+a special case of a parameter, this field is used as the name of a "custom" field
|
|
|
+teams.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`mode`](#attribute-mode) - nested elements processing mode.
|
|
|
+* [`min`](#attributes-min-and-max) - minimum number of command arguments
|
|
|
+strings matched to the parameter.
|
|
|
+* [`max`](#attributes-min-and-max) - maximum number of command arguments
|
|
|
+strings matched to the parameter.
|
|
|
+* [`order`](#attribute-order) - mode of processing optional parameters.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `COMMAND`.
|
|
|
+* `ptype` - reference to the type of the parameter.
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<PTYPE name="ptype1">
|
|
|
+<ACTION sym="INT"/>
|
|
|
+</PTYPE>.
|
|
|
+
|
|
|
+<VIEW name="view1">
|
|
|
+
|
|
|
+<COMMAND name="cmd1" help="First command">
|
|
|
+
|
|
|
+<PARAM name="param1" ptype="/ptype1" help="Param 1"/>
|
|
|
+
|
|
|
+<PARAM name="param2" help="Param 2">
|
|
|
+<PTYPE ref="/ptype1"/>
|
|
|
+</PARAM>
|
|
|
+
|
|
|
+<PARAM name="param3" help="Param 3">
|
|
|
+<PTYPE>.
|
|
|
+<ACTION sym="INT"/>
|
|
|
+</PTYPE>.
|
|
|
+</PARAM>
|
|
|
+
|
|
|
+<PARAM name="param4" ptype="/ptype1" help="Param 4">
|
|
|
+<PARAM name="param5" ptype="/ptype1" help="Param 5"/>
|
|
|
+</PARAM>
|
|
|
+
|
|
|
+<ACTION sym="sym1"/>
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+</VIEW>.
|
|
|
+```
|
|
|
+
|
|
|
+Parameters "param1", "param2", "param3" are identical. In the first case the type is set
|
|
|
+by the `ptype` attribute. In the second, the nested `PTYPE` element, which is the
|
|
|
+reference to the same type "ptype1". In the third one, the type of the parameter is determined by
|
|
|
+"in place", i.e. a new type `PTYPE` is created. But in all three cases the type
|
|
|
+is an integer (see the `sym` attribute). Specify the type directly inside the parameter
|
|
|
+can be handy if this type is not needed anywhere else.
|
|
|
+
|
|
|
+The parameter "param4" has a nested parameter "param5". After entering the argument for
|
|
|
+parameter "param4", the operator will have to enter the argument for the nested
|
|
|
+parameter.
|
|
|
+
|
|
|
+
|
|
|
+### SWITCH
|
|
|
+
|
|
|
+The `SWITCH` element is a [container](#attribute-container). Its only
|
|
|
+task is to set the processing mode of nested elements. `SWITCH` specifies
|
|
|
+such a mode of processing of nested elements, when from many must be selected
|
|
|
+only one element.
|
|
|
+
|
|
|
+In the `SWITCH` element, the [`mode`](#attribute-mode) attribute is forced to be set to
|
|
|
+`switch` value.
|
|
|
+
|
|
|
+For more information about the processing modes of nested elements, see the section
|
|
|
+["Attribute `mode`"](#attribute-mode).
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `SWITCH` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+
|
|
|
+Normally, the `SWITCH` element is used without attributes.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="cmd1" help="First command">
|
|
|
+<SWITCH>.
|
|
|
+<COMMAND name="sub1"/>
|
|
|
+<COMMAND name="sub2"/>
|
|
|
+<COMMAND name="sub3"/>
|
|
|
+</SWITCH>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+By default, the `COMMAND` element has the `mode="sequence"` attribute. If the
|
|
|
+example did not have a `SWITCH` element, then the statement should have been sequential,
|
|
|
+set all subcommands one by one: `cmd1 sub1 sub2 sub3`. The `SWITCH` element
|
|
|
+changed the processing mode of nested elements and as a result the operator must select
|
|
|
+only one subcommand out of three. For example `cmd1 sub2`.
|
|
|
+
|
|
|
+
|
|
|
+### SEQ
|
|
|
+
|
|
|
+The `SEQ` element is a [container](#attribute-container). Its only
|
|
|
+task is to set the processing mode of nested elements. `SEQ` specifies
|
|
|
+such a mode of processing nested elements, when all nested elements must be
|
|
|
+to be set one after the other.
|
|
|
+
|
|
|
+In the `SEQ` element, the [`mode`](#attribute-mode) attribute is forced to be set to
|
|
|
+`sequence` value.
|
|
|
+
|
|
|
+For more information about the processing modes of nested elements, see the section
|
|
|
+["Attribute `mode`"](#attribute-mode).
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `SWITCH` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+
|
|
|
+Normally, the `SEQ` element is used without attributes.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<VIEW name="view1">
|
|
|
+<SEQ>.
|
|
|
+<PARAM name="param1" ptype="/ptype1"/>
|
|
|
+<PARAM name="param2" ptype="/ptype1"/>
|
|
|
+<PARAM name="param3" ptype="/ptype1"/>
|
|
|
+</SEQ>.
|
|
|
+</VIEW>.
|
|
|
+
|
|
|
+<VIEW name="view2">
|
|
|
+<COMMAND name="cmd1" help="First command">
|
|
|
+<VIEW ref="/view1">
|
|
|
+</COMMAND>.
|
|
|
+</VIEW>.
|
|
|
+```
|
|
|
+
|
|
|
+Suppose we have created an auxiliary `VIEW` containing a list of frequently
|
|
|
+parameters used and called it "view1". All parameters must
|
|
|
+to be used sequentially, one after the other. And then in another `VIEW` declared.
|
|
|
+command, which must contain all these parameters. To do this, inside the command
|
|
|
+a reference to "view1" is created and all parameters "fall" inside the command. However
|
|
|
+the `VIEW` element has the `mode="switch"` attribute by default and it turns out that
|
|
|
+operator will not enter all declared parameters, but must select only
|
|
|
+one of them. To change the order in which nested parameters are parsed, use
|
|
|
+element `SEQ`. It changes the order of parameter parsing to sequential.
|
|
|
+
|
|
|
+The same result could be achieved by adding the `mode="sequence"` attribute to the
|
|
|
+"view1" declaration. Attribute usage - shorter, element usage
|
|
|
+`SEQ' is more descriptive.
|
|
|
+
|
|
|
+
|
|
|
+### PTYPE
|
|
|
+
|
|
|
+The `PTYPE` element describes the data type for the parameters. Parameters
|
|
|
+[`PARAM`](#param) refer to a data type using the `ptype` attribute or
|
|
|
+contain a nested `PTYPE` element. The task of `PTYPE` is to check the passed
|
|
|
+operator argument for correctness and return the result as "success" or
|
|
|
+"error." More precisely, the result of the test can be expressed as
|
|
|
+"`fits' or `doesn't fit'. Within the `PTYPE` element the actions are specified
|
|
|
+[`ACTION`](#action), which performs the argument check against the
|
|
|
+of the declared data type.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `PTYPE` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `PTYPE`.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<PTYPE name="ptype1" help="Integer">
|
|
|
+<ACTION sym="INT"/>
|
|
|
+</PTYPE>.
|
|
|
+
|
|
|
+<PARAM name="param1" ptype="/ptype1" help="Param 1"/>
|
|
|
+```
|
|
|
+
|
|
|
+The example declares the data type "ptype1". This is an integer and the `INT` character from the
|
|
|
+The standard plugin "klish" checks that the entered argument is valid.
|
|
|
+is an integer.
|
|
|
+
|
|
|
+Other uses of the `PTYPE` tag and the `ptype` attribute are discussed in the
|
|
|
+[`PARAM`](#param) element example section.
|
|
|
+
|
|
|
+
|
|
|
+### PROMPT
|
|
|
+
|
|
|
+The `PROMPT` element has a special purpose and is nested to the element
|
|
|
+`VIEW`. The purpose of the element is to form a prompt for the user if
|
|
|
+parent `VIEW` is the current path of the session. If the current path
|
|
|
+multilevel, then failing to find a `PROMPT` element in the last element of the path,
|
|
|
+the search engine will go up a level and search for `PROMPT` there. And so
|
|
|
+down to the root element. If `PROMPT` is not found there, then
|
|
|
+standard invitation is used at the discretion of the klish client. By default
|
|
|
+klish client uses the `$` prompt.
|
|
|
+
|
|
|
+Within the `PROMPT` element, the [`ACTION`](#action) actions are specified, which are
|
|
|
+form the invitation text for the user.
|
|
|
+
|
|
|
+The `PROMPT` element is forcibly assigned the value of the `purpose="prompt"` attribute.
|
|
|
+Also, `PROMPT` is a container.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `PROMPT` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `PROMPT`.
|
|
|
+
|
|
|
+Normally, `PROMPT` is used without attributes.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<VIEW name="main">
|
|
|
+
|
|
|
+<PROMPT>.
|
|
|
+<ACTION sym="prompt">%u@%h> </ACTION>
|
|
|
+</PROMPT>.
|
|
|
+
|
|
|
+</VIEW>.
|
|
|
+```
|
|
|
+
|
|
|
+In the example for `VIEW` named "main", which is the current path on the
|
|
|
+The default when starting klish, the user prompt is defined. IN `ACTION`.
|
|
|
+The `prompt` symbol from the standard "klish" plugin is used, which helps to
|
|
|
+in forming the invitation, replacing the `%u` or `%h` constructs with substitutions.
|
|
|
+Specifically `%u` is replaced by the current user name and `%h` is replaced by the host name.
|
|
|
+
|
|
|
+
|
|
|
+### HELP
|
|
|
+
|
|
|
+The `HELP` element has a special purpose and is nested for elements
|
|
|
+`COMMAND`, `PARAM`, `PTYPE`. The purpose of the element is to form text
|
|
|
+"`help`, i.e. a hint for the parent element. Inside the `HELP` element
|
|
|
+specifies the [`ACTION`](#action) actions that form the tooltip text.
|
|
|
+
|
|
|
+The `HELP` element is forcibly assigned the value of the `purpose="help"` attribute.
|
|
|
+Also `HELP` is a container.
|
|
|
+
|
|
|
+The klish client shows hints on pressing the `?` key.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `HELP` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `HELP`.
|
|
|
+
|
|
|
+Normally, `HELP` is used without attributes.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<PARAM name="param1" ptype="/ptype1">
|
|
|
+<HELP>.
|
|
|
+<ACTION sym="sym1"/>
|
|
|
+</HELP>.
|
|
|
+</PARAM>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+### COMPL
|
|
|
+
|
|
|
+The `COMPL` element has a special purpose and is nested for elements
|
|
|
+`PARAM`, `PTYPE`. The purpose of the element is to form auto-complete variants,
|
|
|
+i.e. possible variants of values for the parent element. Within an element
|
|
|
+`COMPL` specifies the [`ACTION`](#action) actions that generate the output.
|
|
|
+The individual variants in the output are separated from each other by a line feed.
|
|
|
+
|
|
|
+The `COMPL` element is forcibly assigned the attribute value
|
|
|
+`purpose="completion"`. Also `COMPL` is a container.
|
|
|
+
|
|
|
+The klish client shows autocomplete options when the `Tab` key is pressed.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `COMPL` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `COMPL`.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<PARAM name="proto" ptype="/STRING" help="Protocol">
|
|
|
+<COMPL>.
|
|
|
+<ACTION sym="printl">tcp</ACTION>
|
|
|
+<ACTION sym="printl">udp</ACTION>
|
|
|
+<ACTION sym="printl">icmp</ACTION>
|
|
|
+</COMPL>.
|
|
|
+</PARAM>
|
|
|
+```
|
|
|
+
|
|
|
+The parameter specifying the protocol is of type `/STRING`, i.e. an arbitrary string.
|
|
|
+The operator can enter arbitrary text, but for convenience the parameter has a
|
|
|
+autocomplete options.
|
|
|
+
|
|
|
+
|
|
|
+### COND
|
|
|
+
|
|
|
+> The functionality of the `COND` element has not yet been implemented.
|
|
|
+
|
|
|
+The `COND` element has a special purpose and is nested for elements
|
|
|
+`VIEW`, `COMMAND`, `PARAM`. The purpose of the element is to hide the element from the operator in the
|
|
|
+if the condition specified in `COND` is not met. Within an element
|
|
|
+`COND` specifies the [`ACTION`](#action) actions that check the condition.
|
|
|
+
|
|
|
+The `COND` element is forcibly assigned the value of the attribute
|
|
|
+`purpose="cond"`. Also `COND` is a container.
|
|
|
+
|
|
|
+
|
|
|
+#### Attributes of the `COND` element
|
|
|
+
|
|
|
+* [`name`](#attribute-name) is the element identifier.
|
|
|
+* [`help`](#attribute-help) - element description.
|
|
|
+* [`ref`](#attribute-ref) - a reference to another `COND`.
|
|
|
+
|
|
|
+
|
|
|
+#### Examples
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="cmd1" help="Command 1">
|
|
|
+<COND>
|
|
|
+<ACTION sym="script">
|
|
|
+test -e /tmp/cond_file
|
|
|
+</ACTION>.
|
|
|
+</COND>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+If the `/tmp/cond_file` file exists, the "cmd1" command is available to the operator,
|
|
|
+if it does not exist, the command is hidden.
|
|
|
+
|
|
|
+
|
|
|
+## klish plugin ##
|
|
|
+
|
|
|
+The klish source tree includes the code for the standard "klish" plugin.
|
|
|
+The plugin contains basic data types, navigation command and other auxiliary data types
|
|
|
+characters. In the vast majority of cases, this plugin should be used.
|
|
|
+However, it is not automatically connected because in some rare specific
|
|
|
+you may need to be able to work without it.
|
|
|
+
|
|
|
+The standard way to connect the "klish" plugin is in the configuration files:
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="klish"/>
|
|
|
+```
|
|
|
+
|
|
|
+The plugin comes with the `ptypes.xml` file, where the basic data types are declared in the
|
|
|
+as [`PTYPE`](#ptype) elements. Declared data types use the characters
|
|
|
+plugin to check if the argument matches the data type.
|
|
|
+
|
|
|
+
|
|
|
+### Data Types
|
|
|
+
|
|
|
+All section characters are intended to be used in `PTYPE` elements if
|
|
|
+unless otherwise specified, and check that the entered argument matches the data type.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `COMMAND'
|
|
|
+
|
|
|
+The `COMMAND` character verifies that the entered argument matches the command name.
|
|
|
+That is, with the `name` or `value` attributes of the `COMMAND` or `PARAM` elements. If
|
|
|
+attribute `value` is set, then its value is used as the command name.
|
|
|
+If not specified, the value of the `name` attribute is used. Character case in
|
|
|
+the team name doesn't count.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `completion_COMMAND`
|
|
|
+
|
|
|
+The `completion_COMMAND` symbol is for the `COMPL` element nested in the
|
|
|
+`PTYPE`. The character is used to generate an autocomplete string for the
|
|
|
+team. The autocomplete for a team is the name of the team itself. If
|
|
|
+attribute `value` is set, then its value is used as the command name.
|
|
|
+If not specified, the value of the `name` attribute is used.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `help_COMMAND`
|
|
|
+
|
|
|
+The `help_COMMAND` symbol is for a `HELP` element nested in a
|
|
|
+`PTYPE`. The character is used to form a description (help) string for the
|
|
|
+commands. If the `value` attribute is specified, its value is used as a
|
|
|
+of the command name. If not specified, the value of the `name` attribute is used. В
|
|
|
+the value of the `help` attribute of the command is used as the hint itself.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `COMMAND_CASE`
|
|
|
+
|
|
|
+The `COMMAND_CASE` symbol is completely analogous to the [`COMMAND`](#symbol-command) symbol,
|
|
|
+except that it takes into account the case of the characters in the command name.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `INT`
|
|
|
+
|
|
|
+The `INT` character verifies that the entered argument is an integer.
|
|
|
+The digit capacity of the number corresponds to the `long long int` type in the C language.
|
|
|
+Within the [`ACTION`](#action) element, a valid range can be defined for the
|
|
|
+integer. Specifies the minimum and maximum values, separated by the
|
|
|
+with a space.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="INT">-30 80</ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+The number can take values between "-30" and "80".
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `UINT`
|
|
|
+
|
|
|
+The `UINT` character verifies that the entered argument is an unsigned integer
|
|
|
+number. The digit capacity of the number corresponds to the `unsigned long long int` type in the C language.
|
|
|
+Within the [`ACTION`](#action) element, a valid range can be defined for the
|
|
|
+numbers. The minimum and maximum values are specified, separated by a space.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="UINT">30 80</ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+The number can take values between "30" and "80".
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `STRING`
|
|
|
+
|
|
|
+The `STRING` character checks that the entered argument is a string. Now there is no
|
|
|
+no specific string requirements.
|
|
|
+
|
|
|
+
|
|
|
+### Navigation
|
|
|
+
|
|
|
+Using navigation commands, the operator changes the current path of the session.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `nav`
|
|
|
+
|
|
|
+The `nav` symbol is used for navigation. The `nav` subcommands can be used to
|
|
|
+change the current session path. All subcommands of the `nav` symbol are specified internally
|
|
|
+of the `ACTION` element - each command on a separate line.
|
|
|
+
|
|
|
+Subcommands of the symbol `nav`:
|
|
|
+
|
|
|
+* `push <view>` - enter the specified `VIEW`. To the current session path is added
|
|
|
+another level of nesting.
|
|
|
+* `pop [num]` - go to the specified number of nesting levels. I.e. exclude from
|
|
|
+the current session path `num` of the upper levels. The `num` argument is
|
|
|
+optional. The default is `num=1`. If we are already in the root `VIEW`, i.e.
|
|
|
+the current path contains only one level, then `pop` will end the session and exit the
|
|
|
+klish.
|
|
|
+* `top` - go to the root level of the current session path. I.e. exit from all
|
|
|
+nested `VIEW`.
|
|
|
+* `replace <view>` - replace `VIEW`, which is at the current nesting level
|
|
|
+to the specified `VIEW`. The number of nesting levels is not increased. Changes
|
|
|
+only the very last component of the path.
|
|
|
+* `exit` - end the session and exit klish.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="nav">
|
|
|
+pop
|
|
|
+push /view_name1
|
|
|
+</ACTION>.
|
|
|
+```
|
|
|
+
|
|
|
+The example shows how you can repeat the `replace` subcommand using other
|
|
|
+subcommands.
|
|
|
+
|
|
|
+
|
|
|
+### Auxiliary Functions
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `nop`
|
|
|
+
|
|
|
+Empty command. The symbol does nothing. Always returns the value
|
|
|
+`0` is "success".
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `print`
|
|
|
+
|
|
|
+Prints the text specified in the body of the `ACTION` element. At the end of the text, the translation
|
|
|
+of the string is not output.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="print">Text to print</ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `printl`
|
|
|
+
|
|
|
+Prints the text specified in the body of the `ACTION` element. At the end of the text is added
|
|
|
+string translation.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="printl">Text to print</ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+#### Symbol `pwd`
|
|
|
+
|
|
|
+Prints the current path of the session. Needed mainly for debugging.
|
|
|
+
|
|
|
+
|
|
|
+#### Symbol `prompt`
|
|
|
+
|
|
|
+The `prompt` symbol helps to generate the invitation text for the operator. In the body
|
|
|
+the `ACTION` element specifies the text of the invitation, which may contain
|
|
|
+substitutions of the form `%s`, where "s" is some printed character. Instead of this
|
|
|
+A certain string is substituted into the text. List of implemented
|
|
|
+substitutions:
|
|
|
+
|
|
|
+* `%%` is the `%` symbol itself.
|
|
|
+* `%h` is the hostname.
|
|
|
+* `%u` is the name of the current user.
|
|
|
+
|
|
|
+```
|
|
|
+<ACTION sym="prompt">%u@%h> </ACTION>
|
|
|
+```
|
|
|
+
|
|
|
+
|
|
|
+## "script" plugin
|
|
|
+
|
|
|
+The "script" plugin contains only one `script` character and is used to execute the
|
|
|
+scripts. The script is contained in the body of the `ACTION` element. A script can be written
|
|
|
+in different scripting programming languages. By default, a script is assumed to be
|
|
|
+is written for the shell interpreter and is run with `/bin/sh`. To
|
|
|
+to choose a different interpreter, shebang is used. Shebang is
|
|
|
+text of the form `#!/path/to/binary` located in the very first line of the script.
|
|
|
+The text `/path/to/binary` is the path where the script interpreter is located.
|
|
|
+
|
|
|
+The `script` plugin is included in the source code of the klish project, and it is possible to connect the
|
|
|
+plug-in can be used as follows:
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="script"/>
|
|
|
+```
|
|
|
+
|
|
|
+The name of the command to be executed and the parameter values are passed to the script using
|
|
|
+environment variables. The following environment variables are supported:
|
|
|
+
|
|
|
+* `KLISH_COMMAND` - name of the command to be executed.
|
|
|
+* `KLISH_PARAM_<name>` - value of the parameter named `<name>`.
|
|
|
+* `KLISH_PARAM_<name>_<index>` - one parameter can have many values if
|
|
|
+attribute `max` is set for it and the value of this attribute is greater than one. Then
|
|
|
+values can be obtained by index.
|
|
|
+
|
|
|
+Examples:
|
|
|
+
|
|
|
+```
|
|
|
+<COMMAND name="ls" help="List path">
|
|
|
+<PARAM name="path" ptype="/STRING" help="Path"/>
|
|
|
+<ACTION sym="script">
|
|
|
+echo "$KLISH_COMMAND"
|
|
|
+ls "$KLISH_PARAM_path"
|
|
|
+</ACTION>.
|
|
|
+</COMMAND>.
|
|
|
+
|
|
|
+<COMMAND name="pytest" help="Test for Python script">
|
|
|
+<ACTION sym="script">#!/usr/bin/python
|
|
|
+import os
|
|
|
+print('ENV', os.getenv('KLISH_COMMAND')))
|
|
|
+</ACTION>.
|
|
|
+</COMMAND>.
|
|
|
+```
|
|
|
+
|
|
|
+The "ls" command uses the shell interpreter and displays a list of files by
|
|
|
+to the path specified in the "path" parameter. Note that using shell
|
|
|
+may not be safe, due to the potential for the operator to introduce into the
|
|
|
+script arbitrary text and, accordingly, execute an arbitrary command.
|
|
|
+The use of shell is available but not recommended. It is very difficult to write
|
|
|
+a secure shell script.
|
|
|
+
|
|
|
+The "pytest" command executes a Python script. Note where
|
|
|
+shebang is defined. The first line of the script is the line that is located
|
|
|
+immediately following the `ACTION` element. A line following a line in which
|
|
|
+declared `ACTION` is considered to be the second one and it is not allowed to define shebang in it.
|
|
|
+
|
|
|
+
|
|
|
+## "lua" plugin
|
|
|
+
|
|
|
+The "lua" plugin contains just one `lua` character and is used to execute the
|
|
|
+scripts in the Lua language. The script is contained in the body of the `ACTION` element. Unlike
|
|
|
+from the `script` character from the ["script"](#plugin-script) plugin, the `lua` character does not
|
|
|
+calls an external interpreter program to execute scripts, and uses a
|
|
|
+internal mechanisms for doing so.
|
|
|
+
|
|
|
+The `lua` plugin is included in the source code of the klish project, and to plug in the
|
|
|
+plug-in can be used as follows:
|
|
|
+
|
|
|
+```
|
|
|
+<PLUGIN name="lua"/>
|
|
|
+```
|
|
|
+
|
|
|
+The contents of the tag can specify the configuration.
|
|
|
+
|
|
|
+### Configuration parameters
|
|
|
+
|
|
|
+Let's take a look at the plugin configuration parameters.
|
|
|
+
|
|
|
+#### autostart
|
|
|
+
|
|
|
+```
|
|
|
+autostart="/usr/share/lua/klish/autostart.lua"
|
|
|
+```
|
|
|
+
|
|
|
+When the plugin is initialized, it creates a Lua machine state that (after fork)
|
|
|
+and will be used to call the Lua `ACTION` code. If it is necessary to load
|
|
|
+It can be done by setting autostart file. Parameter
|
|
|
+there can only be one.
|
|
|
+
|
|
|
+
|
|
|
+#### package.path
|
|
|
+
|
|
|
+```
|
|
|
+package.path="/usr/lib/lua/clish/?.lua;/usr/lib/lua/?.lua".
|
|
|
+```
|
|
|
+
|
|
|
+Specifies the Lua package.path (the paths used to search for modules). The parameter can
|
|
|
+there can only be one.
|
|
|
+
|
|
|
+#### backtrace
|
|
|
+
|
|
|
+```
|
|
|
+backtrace=1
|
|
|
+```
|
|
|
+
|
|
|
+Whether to show backtrace when Lua code crashes. 0 or 1.
|
|
|
+
|
|
|
+### API
|
|
|
+
|
|
|
+When Lua `ACTION` is executed, the following functions are available:
|
|
|
+
|
|
|
+#### klish.pars()
|
|
|
+
|
|
|
+Returns information about the parameters. There are two possible uses for this
|
|
|
+functions.
|
|
|
+
|
|
|
+```
|
|
|
+local pars = klish.pars()
|
|
|
+for k, v in ipairs(pars) do
|
|
|
+for i, p in ipairs(pars[v]) do
|
|
|
+print(string.format("%s[%d] = %s", v, i, p))
|
|
|
+end
|
|
|
+end
|
|
|
+```
|
|
|
+
|
|
|
+Obtaining information about all parameters. In this case the function is called without
|
|
|
+arguments and returns a table of all parameters. The table contains a list of
|
|
|
+names, as well as an array of values for each name. The example above shows an iterator
|
|
|
+for all parameters with their values displayed.
|
|
|
+
|
|
|
+In addition, klish.pars can be called to take the values of a particular
|
|
|
+parameter, e.g.:
|
|
|
+
|
|
|
+```
|
|
|
+print("int_val = ", klish.pars('int_val')[1]))
|
|
|
+```
|
|
|
+
|
|
|
+#### klish.ppars()
|
|
|
+
|
|
|
+Works exactly the same as `klish.ppars()`, but only for the parent ones
|
|
|
+parameters, if there are any in this context.
|
|
|
+
|
|
|
+#### klish.par() and klish.ppar()
|
|
|
+
|
|
|
+Work the same as `klish.pars()`, `klish.ppars()` with the assignment of a specific
|
|
|
+parameters, but return a value rather than an array. If parameters with this name
|
|
|
+a few, the first one will come back.
|
|
|
+
|
|
|
+#### klish.path()
|
|
|
+
|
|
|
+Returns the current path as an array of strings. For example:
|
|
|
+
|
|
|
+```
|
|
|
+print(table.concat(klish.path(), "/"))
|
|
|
+```
|
|
|
+
|
|
|
+#### klish.context()
|
|
|
+
|
|
|
+Allows to get some parameters of the command context. Takes as input
|
|
|
+string -- the name of the context parameter:
|
|
|
+
|
|
|
+- val;
|
|
|
+- cmd;
|
|
|
+- pcmd;
|
|
|
+- uid;
|
|
|
+- pid;
|
|
|
+- user.
|
|
|
+
|
|
|
+Without parameter, returns a table with all available context parameters.
|