coreutils: env invocation

1 
1 23.2 ‘env’: Run a command in a modified environment
1 ===================================================
1 
1 ‘env’ runs a command with a modified environment.  Synopses:
1 
1      env [OPTION]... [NAME=VALUE]... [COMMAND [ARGS]...]
1      env -[v]S'[OPTION]... [NAME=VALUE]... [COMMAND [ARGS]...]'
1      env
1 
1    ‘env’ is commonly used on first line of scripts (shebang line):
1      #!/usr/bin/env COMMAND
1      #!/usr/bin/env -[v]S[OPTION]... [NAME=VALUE]... COMMAND [ARGS]...
1 
1    Operands of the form ‘VARIABLE=VALUE’ set the environment variable
1 VARIABLE to value VALUE.  VALUE may be empty (‘VARIABLE=’).  Setting a
1 variable to an empty value is different from unsetting it.  These
1 operands are evaluated left-to-right, so if two operands mention the
1 same variable the earlier is ignored.
1 
1    Environment variable names can be empty, and can contain any
1 characters other than ‘=’ and ASCII NUL. However, it is wise to limit
1 yourself to names that consist solely of underscores, digits, and ASCII
1 letters, and that begin with a non-digit, as applications like the shell
1 do not work well with other names.
1 
1    The first operand that does not contain the character ‘=’ specifies
1 the program to invoke; it is searched for according to the ‘PATH’
1 environment variable.  Any remaining arguments are passed as arguments
1 to that program.  The program should not be a special built-in utility
1 (⇒Special built-in utilities).
1 
1    Modifications to ‘PATH’ take effect prior to searching for COMMAND.
1 Use caution when reducing ‘PATH’; behavior is not portable when ‘PATH’
1 is undefined or omits key directories such as ‘/bin’.
1 
1    In the rare case that a utility contains a ‘=’ in the name, the only
1 way to disambiguate it from a variable assignment is to use an
1 intermediate command for COMMAND, and pass the problematic program name
1 via ARGS.  For example, if ‘./prog=’ is an executable in the current
1 ‘PATH’:
1 
1      env prog= true # runs 'true', with prog= in environment
1      env ./prog= true # runs 'true', with ./prog= in environment
1      env -- prog= true # runs 'true', with prog= in environment
1      env sh -c '\prog= true' # runs 'prog=' with argument 'true'
1      env sh -c 'exec "$@"' sh prog= true # also runs 'prog='
1 
1    If no command name is specified following the environment
1 specifications, the resulting environment is printed.  This is like
1 specifying the ‘printenv’ program.
1 
1    For some examples, suppose the environment passed to ‘env’ contains
1 ‘LOGNAME=rms’, ‘EDITOR=emacs’, and ‘PATH=.:/gnubin:/hacks’:
1 
1    • Output the current environment.
1           $ env | LC_ALL=C sort
1           EDITOR=emacs
1           LOGNAME=rms
1           PATH=.:/gnubin:/hacks
1 
1    • Run ‘foo’ with a reduced environment, preserving only the original
1      ‘PATH’ to avoid problems in locating ‘foo’.
1           env - PATH="$PATH" foo
1 
1    • Run ‘foo’ with the environment containing ‘LOGNAME=rms’,
1      ‘EDITOR=emacs’, and ‘PATH=.:/gnubin:/hacks’, and guarantees that
1      ‘foo’ was found in the file system rather than as a shell built-in.
1           env foo
1 
1    • Run ‘nemacs’ with the environment containing ‘LOGNAME=foo’,
1      ‘EDITOR=emacs’, ‘PATH=.:/gnubin:/hacks’, and ‘DISPLAY=gnu:0’.
1           env DISPLAY=gnu:0 LOGNAME=foo nemacs
1 
1    • Attempt to run the program ‘/energy/--’ (as that is the only
1      possible path search result); if the command exists, the
1      environment will contain ‘LOGNAME=rms’ and ‘PATH=/energy’, and the
1      arguments will be ‘e=mc2’, ‘bar’, and ‘baz’.
1           env -u EDITOR PATH=/energy -- e=mc2 bar baz
1 
1 23.2.1 General options
1 ----------------------
1 
11 The program accepts the following options.  Also see ⇒Common
 options.  Options must precede operands.
1 
1 ‘-0’
1 ‘--null’
1      Output a zero byte (ASCII NUL) at the end of each line, rather than
1      a newline.  This option enables other programs to parse the output
1      even when that output would contain data with embedded newlines.
1 
1 ‘-u NAME’
1 ‘--unset=NAME’
1      Remove variable NAME from the environment, if it was in the
1      environment.
1 
1 ‘-’
1 ‘-i’
1 ‘--ignore-environment’
1      Start with an empty environment, ignoring the inherited
1      environment.
1 
1 ‘-C DIR’
1 ‘--chdir=DIR’
1      Change the working directory to DIR before invoking COMMAND.  This
1      differs from the shell built-in ‘cd’ in that it starts COMMAND as a
1      subprocess rather than altering the shell’s own working directory;
1      this allows it to be chained with other commands that run commands
1      in a different context.  For example:
1 
1           # Run 'true' with /chroot as its root directory and /srv as its working
1           # directory.
1           chroot /chroot env --chdir=/srv true
1           # Run 'true' with /build as its working directory, FOO=bar in its
1           # environment, and a time limit of five seconds.
1           env --chdir=/build FOO=bar timeout 5 true
1 
1 ‘-v’
1 ‘--debug’
1      Show verbose information for each processing step.
1 
1           $ env -v -uTERM A=B uname -s
1           unset:    TERM
1           setenv:   A=B
1           executing: uname
1              arg[0]= 'uname'
1              arg[1]= '-s'
1           Linux
1 
1      When combined with ‘-S’ it is recommended to list ‘-v’ first, e.g.
1      ‘env -vS'string'’.
1 
1 ‘-S STRING’
1 ‘--split-string=STRING’
1      process and split STRING into separate arguments used to pass
1      multiple arguments on shebang lines.  ‘env’ supports FreeBSD’s
1      syntax of several escape sequences and environment variable
1      expansions.  See below for details and examples.
1 
1    Exit status:
1 
1      0   if no COMMAND is specified and the environment is output
1      125 if ‘env’ itself fails
1      126 if COMMAND is found but cannot be invoked
1      127 if COMMAND cannot be found
1      the exit status of COMMAND otherwise
1 
1 23.2.2 ‘-S’/‘--split-string’ usage in scripts
1 ---------------------------------------------
1 
1 The ‘-S’/‘--split-string’ options enable using multiple arguments on the
1 first one of scripts (shebang line, ‘#!’).
1 
1    When a script’s interpreter is in a known location, scripts typically
1 contain the absolute file name in their first line:
1 
1 Shell script:         #!/bin/sh
1                       echo hello
1                  
1 Perl script:          #!/usr/bin/perl
1                       print "hello\n";
1                  
1 Python script:        #!/usr/bin/python3
1                       print("hello")
1                  
1 
1    When a script’s interpreter is in a non-standard location in the
1 ‘PATH’ environment variable, it is recommended to use ‘env’ on the first
1 line of the script to find the executable and run it:
1 
1 Shell script:         #!/usr/bin/env bash
1                       echo hello
1                  
1 Perl script:          #!/usr/bin/env perl
1                       print "hello\n";
1                  
1 Python script:        #!/usr/bin/env python3
1                       print("hello")
1                  
1 
1    Most operating systems (e.g.  GNU/Linux, BSDs) treat all text after
1 the first space as a single argument.  When using ‘env’ in a script it
1 is thus not possible to specify multiple arguments.
1 
1    In the following example:
1      #!/usr/bin/env perl -T -w
1      print "hello\n";
1 
1    The operating system treats ‘perl -T -w’ as one argument (the
1 program’s name), and executing the script fails with:
1 
1      /usr/bin/env: 'perl -T -w': No such file or directory
1 
1    The ‘-S’ option instructs ‘env’ to split the single string into
1 multiple arguments.  The following example works as expected:
1 
1      $ cat hello.pl
1      #!/usr/bin/env -S perl -T -w
1      print "hello\n";
1 
1      $ chmod a+x hello.pl
1      $ ./hello.pl
1      hello
1 
1    And is equivalent to running ‘perl -T -w hello.pl’ on the command
1 line prompt.
1 
1 Testing and troubleshooting
1 ...........................
1 
1 To test ‘env -S’ on the command line, use single quotes for the ‘-S’
1 string to emulate a single paramter.  Single quotes are not needed when
1 using ‘env -S’ in a shebang line on the first line of a script (the
1 operating system already treats it as one argument).
1 
1    The following command is equivalent to the ‘hello.pl’ script above:
1 
1      $ env -S'perl -T -w' hello.pl
1 
1    To troubleshoot ‘-S’ usage add the ‘-v’ as the first argument (before
1 ‘-S’).
1 
1    Using ‘-vS’ on a shebang line in a script:
1 
1      $ cat hello-debug.pl
1      #!/usr/bin/env -vS perl -T -w
1      print "hello\n";
1 
1      $ chmod a+x hello-debug.pl
1      $ ./hello-debug.pl
1      split -S:  'perl -T -w'
1       into:    'perl'
1           &    '-T'
1           &    '-w'
1      executing: perl
1         arg[0]= 'perl'
1         arg[1]= '-T'
1         arg[2]= '-w'
1         arg[3]= './hello-debug.pl'
1      hello
1 
1    Using ‘-vS’ on the command line prompt (adding single quotes):
1 
1      $ env -vS'perl -T -w' hello-debug.pl
1      split -S:  'perl -T -w'
1       into:    'perl'
1           &    '-T'
1           &    '-w'
1      executing: perl
1         arg[0]= 'perl'
1         arg[1]= '-T'
1         arg[2]= '-w'
1         arg[3]= 'hello-debug.pl'
1      hello
1 
1 23.2.3 ‘-S’/‘--split-string’ syntax
1 -----------------------------------
1 
1 Splitting arguments by whitespace
1 .................................
1 
1 Running ‘env -Sstring’ splits the STRING into arguments based on
1 unquoted spaces or tab characters.
1 
1    In the following contrived example the ‘awk’ variable ‘OFS’ will be
1 ‘<space>xyz<space>’ as these spaces are inside double quotes.  The other
1 space characters are used as argument separators:
1 
1      $ cat one.awk
1      #!/usr/bin/env -S awk -v OFS=" xyz " -f
1      BEGIN {print 1,2,3}
1 
1      $ chmod a+x one.awk
1      $ ./one.awk
1      1 xyz 2 xyz 3
1 
1    When using ‘-S’ on the command line prompt, remember to add single
1 quotes around the entire string:
1 
1      $ env -S'awk -v OFS=" xyz " -f' one.awk
1      1 xyz 2 xyz 3
1 
1 Escape sequences
1 ................
1 
1 ‘env’ supports several escape sequences.  These sequences are processed
1 when unquoted or inside double quotes (unless otherwise noted).  Single
1 quotes disable escape sequences except ‘\'’ and ‘\\’.
1 
1 ‘\c’    Ignore the remaining characters in the string.  Cannot be used
1         inside double quotes.
1         
1 ‘\f’    form-feed character (ASCII 0x0C)
1         
1 ‘\n’    new-line character (ASCII 0x0A)
1         
1 ‘\r’    carriage-return character (ASCII 0x0D)
1         
1 ‘\t’    tab character (ASCII 0x09)
1         
1 ‘\v’    vertical tab character (ASCII 0x0B)
1         
1 ‘\#’    A hash ‘#’ character.  Used when a ‘#’ character is needed as
1         the first character of an argument (see ’comments’ section
1         below).
1         
1 ‘\$’    A dollar-sign character ‘$’.  Unescaped ‘$’ characters are used
1         to expand environment variables (see ’variables’ section
1         below).
1         
1 ‘\_’    Inside double-quotes, replaced with a single space character.
1         Outside quotes, treated as an argument separator.  ‘\_’ can be
1         used to avoid space characters in a shebang line (see examples
1         below).
1         
1 ‘\"’    A double-quote character.
1         
1 ‘\'’    A single-quote character.  This escape sequence works inside
1         single-quoted strings.
1         
1 ‘\\’    A backslash character.  This escape sequence works inside
1         single-quoted strings.
1         
1 
1    The following ‘awk’ script will use tab character as input and output
1 field separator (instead of spaces and tabs):
1 
1      $ cat tabs.awk
1      #!/usr/bin/env -S awk -v FS="\t" -v OFS="\t" -f
1      ...
1 
1 Comments
1 ........
1 
1 The escape sequence ‘\c’ (used outside single/double quotes) causes
1 ‘env’ to ignore the rest of the string.
1 
1    The ‘#’ character causes ‘env’ to ignore the rest of the string when
1 it appears as the first character of an argument.  Use ‘\#’ to reverse
1 this behavior.
1 
1      $ env -S'printf %s\n A B C'
1      A
1      B
1      C
1 
1      $ env -S'printf %s\n A# B C'
1      A#
1      B
1      C
1 
1      $ env -S'printf %s\n A #B C'
1      A
1 
1      $ env -S'printf %s\n A \#B C'
1      A
1      #B
1      C
1 
1      $ env -S'printf %s\n A\cB C'
1      A
1 
1    NOTE: The above examples use single quotes as they are executed on
1 the command-line.
1 
1 Environment variable expansion
1 ..............................
1 
1 The pattern ‘${VARNAME}’ is used to substitute a value from the
1 environment variable.  The pattern must include the curly braces
1 (‘{’,‘}’).  Without them ‘env’ will reject the string.  Special shell
1 variables (such as ‘$@’, ‘$*’, ‘$$’) are not supported.
1 
1    If the environment variable is empty or not set, the pattern will be
1 replaced by an empty string.  The value of ‘${VARNAME}’ will be that of
1 the executed ‘env’, before any modifications using
1 ‘-i’/‘--ignore-environment’/‘-u’/‘--unset’ or setting new values using
1 ‘VAR=VALUE’.
1 
1    The following python script prepends ‘/opt/custom/modules’ to the
1 python module search path environment variable (‘PYTHONPATH’):
1 
1      $ cat custom.py
1      #!/usr/bin/env -S PYTHONPATH=/opt/custom/modules/:${PYTHONPATH} python
1      print "hello"
1      ...
1 
1    The expansion of ‘${PYTHONPATH}’ is performed by ‘env’, not by a
1 shell.  If the curly braces are omitted, ‘env’ will fail:
1 
1      $ cat custom.py
1      #!/usr/bin/env -S PYTHONPATH=/opt/custom/modules/:$PYTHONPATH python
1      print "hello"
1      ...
1 
1      $ chmod a+x custom.py
1      $ custom.py
1      /usr/bin/env: only ${VARNAME} expansion is supported, error at: $PYTHONPATH python
1 
1    Environment variable expansion happens before clearing the
1 environment (with ‘-i’) or unsetting specific variables (with ‘-u’):
1 
1      $ env -S'-i OLDUSER=${USER} env'
1      OLDUSER=gordon
1 
1    Use ‘-v’ to diagnose the operations step-by-step:
1 
1      $ env -vS'-i OLDUSER=${USER} env'
1      expanding ${USER} into 'gordon'
1      split -S:  '-i OLDUSER=${USER} env'
1       into:    '-i'
1           &    'OLDUSER=gordon'
1           &    'env'
1      cleaning environ
1      setenv:   OLDUSER=gordon
1      executing: env
1         arg[0]= 'env'
1      OLDUSER=gordon
1