
.. _scripts:

Scripts
=======

Commands and SQL queries can be combined into scripts to automate tasks, like
finding log messages or creating reports. For example, **lnav** includes a
:file:`partition-by-boot` script that partitions the log view based on boot
messages from the Linux kernel. A script can have a mix of SQL and **lnav**
commands, as well as include other scripts. The type of statement to execute is
determined by the leading character on a line: a semi-colon begins a SQL
statement; a colon starts an **lnav** command; and a pipe :code:`|` denotes
another script to be executed. Lines beginning with a hash are treated as
comments.  Script files should be named with a :file:`.lnav` extension.

Scripts can be located anywhere in the file system and executed by giving
their full path in the :kbd:`|` prompt.  Or, scripts can be
:ref:`installed<installing_format_files>` in format directories so they can be
called by just their base name. You can also create :file:`.sql` files that
contain SQL statements to be executed on startup. A good use for SQL files is
creating a helper :code:`TABLE` or :code:`VIEW` to be used for other queries.

The following variables are defined in a script:

.. envvar:: #

   The number of arguments passed to the script.

.. envvar:: __all__

   A string containing all the arguments joined by a single space.

.. envvar:: 0

   The path to the script being executed.

.. envvar:: 1-N

   The arguments passed to the script.

.. envvar:: LNAV_HOME_DIR

   The path to the directory where the user's **lnav** configuration is stored.

.. envvar:: LNAV_WORK_DIR

   The path to the directory where **lnav** caches files, like archives that
   have been unpacked or piper captures.

Remember that you need to use the :ref:`:eval<eval>` command when referencing
variables in most **lnav** commands.  Scripts can provide help text to be
displayed during interactive usage by adding the following tags in a comment
header:

  :@synopsis: The synopsis should contain the name of the script and any
    parameters to be passed.  For example::

    # @synopsis: hello-world <name1> [<name2> ... <nameN>]

  :@description: A one-line description of what the script does.  For example::

    # @description: Say hello to the given names.

  :@output-format: The MIME type of the output generated by the script.
    When set to :code:`text/markdown` the :ref:`:write-table-to<write_table_to>`
    will generate Markdown tables.


.. tip::

   The :ref:`:eval<eval>` command can be used to do variable substitution for
   commands that do not natively support it.  For example, to substitute the
   variable, :code:`pattern`, in a :ref:`:filter-out<filter_out>` command:

   .. code-block:: lnav

      :eval :filter-out ${pattern}

VSCode Extension
----------------

The `lnav VSCode Extension <https://marketplace.visualstudio.com/items?itemName=lnav.lnav>`_
can be installed to add syntax highlighting to lnav scripts.

Builtin Scripts
---------------

The following scripts are built into lnav.

find-msg
^^^^^^^^

This script can help in finding log messages that are related to the focused
message.  lnav already provides hotkeys for finding messages based on common
fields, but this script can be used for arbitrary fields.

`find-msg source <https://github.com/tstack/lnav/blob/master/src/scripts/find-msg.lnav>`_

find-chained-msg
^^^^^^^^^^^^^^^^

This script is similar to :code:`find-msg`, except instead of matching a
single field in the focused and next/previous message, the matched value
can be in separate fields.

`find-chained-msg source <https://github.com/tstack/lnav/blob/master/src/scripts/find-chained-msg.lnav>`_

report-access-log
^^^^^^^^^^^^^^^^^

This script generates a report from the :code:`access_log` table that is
similar to the output of the `goaccess <https://goaccess.io>`_ tool.

`report-access-log souurce <https://github.com/tstack/lnav/blob/master/src/scripts/report-access-log.lnav>`_
