home | help
XENV(1) 		     General Commands Manual			 XENV(1)

NAME
     xenv - expand shell variables and commands in input files

SYNOPSIS
     xenv [-hmnrsuvx?] [-e NAME] [-D NAME[=VALUE]] [-p COMMAND] [-t SECONDS] [-U
     NAME] [-W [no-]FEATURE] [FILE...]

DESCRIPTION
     Reads  input  from  FILEs (or the standard input, if none are supplied) and
     prints it on the standard output, expanding references to environment vari-
     ables with their actual values and substituting  shell  commands  with  the
     output they produce.

   Variable expansion
     A variable reference is one of the following constructs:

     $NAME  Expands to the value of the variable NAME, or to an empty string, if
	    it is unset.

     ${NAME}
	    Same as above.

     The  following  forms  are conditional expressions, that cause xenv to test
     for a variable that is unset or null and  act  accordingly.   Omitting  the
     colon results in a test only for a variable that is unset.

     ${variable:-word}
	    Use  Default Values.  If variable is unset or null, the expansion of
	    word is substituted.  Otherwise, the value of  variable  is  substi-
	    tuted.

     ${variable:=word}
	    Assign  Default Values.  If variable is unset or null, the expansion
	    of word is assigned to variable.  The value of variable is then sub-
	    stituted.

     ${variable:?word}
	    Display Error if Null or Unset.  If variable is null or  unset,  the
	    expansion  of  word  (or  a  message  to  that effect if word is not
	    present) is output to standard error.  Otherwise, the value of vari-
	    able is substituted.

     ${variable:+word}
	    Use Alternate Value.  If variable is null or unset, nothing is  sub-
	    stituted, otherwise the expansion of word is substituted.

     ${variable:|word1|word2}
	    Ternary operator.  Unless variable is null or unset, substitutes the
	    expansion of word1, otherwise the expansion of word2.

     The  above  notation  is  consistent  with  the POSIX shell, except for the
     ${variable:|word1|word2} form, which is an extension of xenv.

     In the above expansion forms the word part can contain variable expansions,
     command substitutions, single and double-quoted parts.  The latter two  are
     handled  exactly  as  in Bourne shell: the quotes are removed, the text be-
     tween double quotes is subject to variable expansion and command  substitu-
     tion,  whereas the test between single quotes is not.  Within double quoted
     part, a backslash can be used to escape the indirection character ($), dou-
     ble and single quote character and itself.

   Command substitution
     A construct $(command) is replaced with the output of command.   Xenv  per-
     forms substitution by running $SHELL -c command and replacing the construct
     with  the	standard  output  of the command, with any trailing newlines re-
     moved.  If the SHELL variable is not set, the default /bin/sh is assumed.

     command is passed to the shell verbatim.  This means, in  particular,  that
     variable  references  in  the command are expanded by shell, rather than by
     xenv and, as a consequence, that the options -u and -r don't work for  com-
     mand  substitutions.   The sequences $[...] and ${*...*} lose their special
     meaning as well.

     Nested command substitutions are processed by the shell.

     The -t N option sets the maximum time a command substitution is allowed  to
     run.  If the command runs longer than N seconds, it is terminated and a di-
     agnostic message to that effect is printed on the standard error.

     Command substitution can be disabled using the -Wno-command option.

   Comments
     Comments  are  multiline.	 They are introduced with the characters ${* and
     extend up to the nearest pair of characters *}.  Comments are removed  from
     the input.

     Comments can be disabled using the -Wno-comment option.

   Quoting and escaping
     To  deprive the $ character of its special meaning, precede it with a back-
     slash.  For example:

     \${NAME}

     Backslash followed by another backslash is replaced  by  single  backslash.
     Backslash followed by any other character is reproduced verbatim.

     To turn off this feature, use the -Wno-escape option.

     To  reproduce a portion of text verbatim, enclose it in $[ and ].	This has
     the same effect as the $$verbatim directive described below, except that it
     allows the verbatim portion to appear within a line.

     Newlines and balanced square brackets are allowed within the $[ ...  ] con-
     struct.

     Special meaning of the $[...] construct can be disabled by  the  -Wno-quote
     option.

   Environment meta-variable
     Environment meta-variable makes variable indirections more visible.  Use it
     if  your  input text can contain considerable number of indirection charac-
     ters ($s) that can be falsely identified as variable references.  The meta-
     variable is defined using the -e option:

     xenv -e ENV

     Once you define it, variable reference syntax becomes  $ENV{NAME},  instead
     of  just  $NAME.  Tests for variable that is unset or null are modified ac-
     cordingly.  Thus, e.g. $ENV{NAME:-text} substitutes "text" if the	variable
     NAME  is  unset or null.  The constructs for command substitution, verbatim
     quotations and comments become $ENV(...), $ENV[...],  and	$ENV{*	...  *},
     correspondingly.

     Any  sequence of characters can be used to name the meta-variable, provided
     that it is a valid variable name.

   Preprocessor directives
     The two $ characters appearing at the beginning of line (with optional pre-
     ceding whitespace) introduce special preprocessor directives.

     Preprocessor directives can be disabled using the -Wno-directive option.

     Inclusion
	    The constructs

	    $$source FILE
	    $$include FILE

	    cause FILE to be read and processed at the current point.  When  the
	    end of the file is reached, input is resumed from the previous input
	    file.

	    Unless FILE is an absolute file name, it will be searched in the in-
	    clude search path.	This path, initially empty, is initialized by -I
	    command line options.  The argument of each -I option is appended to
	    the include search path.

	    If	the  FILE  cannot be processed, xenv reports an error and exits.
	    The exit code is 66, if the file does not exist and cannot be  found
	    in the include file path, 77, if the program is denied permission to
	    open  it, and 72 if another error occurred.  If an attempt of recur-
	    sive inclusion is detected, the program reports the fact  and  exits
	    with the code 69.

	    The construct

	    $$sinclude FILE

	    is	similar  to  $$include, except that if the file is not found, it
	    silently ignores the fact.

     Diversion
	    Diversions are a way of directing output to a temporary storage  and
	    inserting  it  (undiverting) into the main output stream again, at a
	    later time.  Temporary storage used for each diversion is identified
	    by a unique identifier assigned to it when a diversion is declared.

	    A diversion is started by the $$divert directive:

	    $$divert NAME

	    The NAME gives the identifier of a temporary storage to divert  out-
	    put  to.   If this diversion does not exist, it will be created.  If
	    it already exists, output will be appended to it.  If NAME is  omit-
	    ted, initial output file is restored.

	    The output is appended to that diversion until the next $$divert di-
	    rective  or  end  of  input, whichever happens first.  The collected
	    text can be inserted anyplace by using the $$undivert directive:

	    $$undivert NAME

	    Undiverting the collected text does not  discard  it:  you	can  use
	    $$undivert	multiple  times to insert the same text again and again.
	    To actually destroy the diversion and free the resources  associated
	    with it, use this directive:

	    $$dropdivert NAME

	    After  dropping  a diversion, attempts to undivert from it result in
	    error.  You can however recreate the dropped diversion from  scratch
	    using the $$divert directive.

     Verbatim block
	    The following construct introduces verbatim text block:

	    $$verbatim
	    TEXT
	    $$end

	    It	expands  to  TEXT unchanged.  To insert verbatim text in a line,
	    use the $[ ... ] construct (see Quoting and escaping, above).

     The following conditional directives expand to a given fragment of text de-
     pending on whether an environment variable is defined.

     Expand if defined
	    The construct

	    $$ifdef NAME
	    TEXT1
	    $$else
	    TEXT2
	    $$endif

	    is replaced with the expansion of TEXT1 if the environment	variable
	    NAME is defined (including if it has a null value) and to TEXT2 oth-
	    erwise.

	    If the construct begins with $$ifndef, the sense is inverted.

     Expand if set
	    The construct

	    $$ifset NAME
	    TEXT1
	    $$else
	    TEXT2
	    $$endif

	    is	replaced with the expansion of TEXT1 if the environment variable
	    NAME is set and has a non-null value and to TEXT2 otherwise.

	    If the construct begins with $$ifnset, the sense is inverted.

     Expand if true
	    The following construct substitutes TEXT1 if the variable NAME eval-
	    uates to 1 (boolean true) and substitutes TEXT2 otherwise:

	    $$iftrue NAME
	    TEXT1
	    $$else
	    TEXT2
	    $$endif

     Expand if false
	    The following construct substitutes TEXT1 if the variable NAME eval-
	    uates to 0 (boolean false) and substitutes TEXT2 otherwise:

	    $$iffalse NAME
	    TEXT1
	    $$else
	    TEXT2
	    $$endif

     In the context of $$iftrue and iffalse, a variable that is unset is consid-
     ered to evaluate to false.  Textual values for false and true  are  config-
     urable  via  the  -Wbooleans  option.  If NAME does not evaluate to a valid
     boolean value, an error is reported and both constructs substitute TEXT2.

     In the conditional constructs above, the $$else part is optional.

     Optional whitespace is allowed between the beginning of the line and the $$
     marker, as well as between it and the keyword.  This allows  for  indenting
     the nested constructs in a more natural way, e.g.:

     $$ifdef LOG_HOST
     $$ ifdef LOG_PORT
       logger $LOG_HOST:$LOG_PORT;
     $$ else
       logger $LOG_HOST
     $$ endif
     $$endif

   Loops
     Two looping directives are provided.

     Foreach loop

	    $$loop VAR ARGS...
	    BODY
	    $$end

	    Current  value of the environment variable VAR is stashed away.  The
	    arguments (ARGS...) are subject to all normal expansions.  Words ob-
	    tained as a result of expansions are assigned to  VAR  sequentially.
	    After  each  assignment,  BODY is expanded.  When all expanded words
	    have been iterated over, initial value of VAR is restored.

	    For example, the following text:

	    $$loop X A B C
	    This is $X
	    $$end

	    expands to:

	    This is A
	    This is B
	    This is C

     For loop

	    $$range VAR START STOP [INCR]
	    BODY
	    $$end

	    Current value of the environment variable VAR is stashed away.   and
	    it	is  assigned  the  expansion  of START, which must be an integer
	    value.  BODY is expanded and VAR is incremented by the expansion  of
	    NCR until its value becomes greater than the expansion of STOP.

	    When iteration is over, original value of VAR is restored.

	    If	INCR is omitted, it defaults to +1 if STOP is greater than START
	    and to -1 otherwise.

	    For example

	    $$range X 1 4
	    Number $X
	    $$end

	    produces the following expansion:

	    Number 1
	    Number 2
	    Number 3
	    Number 4

   Setting and unsetting variables
     $$set NAME
	    Sets the variable NAME to empty string.

     $$set NAME "STRING"
	    Sets the variable NAME to STRING.  STRING can occupy multiple  lines
	    and is subject to variable expansion and command substitution.

     $$set NAME 'STRING'
	    Sets the variable NAME to STRING.  STRING can occupy multiple lines.
	    Neither  variable  expansion  nor  command	substitution  occurs  in
	    STRING.

     $$unset NAME
	    Unsets the variable NAME.

OPTIONS
     -e NAME
	    Use NAME as the environment meta-variable.	See the section Environ-
	    ment meta-variable, above.

     -h or -?
	    Print a short command line summary and exit.

     -m     Pipe output to m4.	If -s option is also given, pass  it  to  m4  as
	    well.  See also -p.

     -n     Dry-run mode.  Process the input files without producing any output.
	    Report  any  errors.  Useful together with the -u option to discover
	    undefined variables.

     -p COMMAND
	    Pipe output to COMMAND.

     -r     Retain references to undefined variables in output.  By default,  an
	    undefined  variable  expands  to  an  empty string.  This option in-
	    structs xenv to reproduce the variable  reference  verbatim  in  the
	    output.  Naturally, this affects only $X and ${X} references.

     -s     Generate  synchronization  directives,  i.e. lines of the form #line
	    NUM "FILE", which mean that the following line  originated	at  line
	    NUM in file FILE.
	    Synchronization directives are emitted when variable or preprocessor
	    directive expansion causes removal or insertion of one or more lines
	    to	the  output.   Each  synchronization directive occupies a single
	    line by itself.  If a synchronization discrepancy occurs in the mid-
	    dle of an output line, emission of the synchronization directive  is
	    delayed  until the next newline that does not occur in the middle of
	    a quoted string (both single and double quotes are understood).

     -t SECONDS
	    Sets maximum execution time for a command substitution.

     -u     Treat unset variables as an error.

     -D NAME[=VALUE]
	    Define environment variable NAME to the VALUE, or an  empty  string,
	    if it is not given.

     -U NAME
	    Undefine the environment variable NAME.

     -v     Print program version and exit.

     -W [no-]FEATURE
	    Disable  (if  prefixed  with  no-)	or enable specific xenv feature.
	    Valid FEATURE names are:

	    booleans=T/F[,T/F]
		   Defines values that are considered booleans by  $$iftrue  and
		   $$iffalse.	Each T is registered as a boolean true, and each
		   F as a boolean false.

	    command
		   Controls command expansion.

	    comment
		   Controls ${* ... *} comments.

	    escape
		   Controls the use of backslash as escape character.

	    directive
		   Controls preprocessor  directives:  $$set,  $$ifset	and  the
		   like.

	    quote  Controls the use of quote ($[ ... ]) constructs.

	    minimal
		   Enables minimal mode.  Equivalent to: -Wno-command
		   -Wno-comment -Wno-directive -Wno-quote -Wno-escape -e ENV

     -x     Enable debugging output.

EXIT CODES
     0	    Successful termination.

     64     Usage error.

     65     Reference  to  undefined  variable	encountered and the -u option is
	    specified.

     66     Source file does not exist.

     69     Recursive inclusion has been prevented.

     70     Internal program error.  This probably indicates a bug.  Please, re-
	    port it.

     71     System error: file cannot be opened, fork failed, etc.

     77     Permission denied to open the source file.

BUGS
     The -r and -u options have no effect over command substitutions.

SEE ALSO
     dbe(1), m4env(1).

COPYRIGHT
     Copyright (C) 2021-2022 Sergey Poznyakoff <gray@gnu.org>
     License GPLv3+: GNU GPL version 3 or later <http://gnu.org/li-
     censes/gpl.html>
     This is free software: you are free to change and redistribute  it.   There
     is NO WARRANTY, to the extent permitted by law.

XENV				 August 15, 2022			 XENV(1)

home | help