script man page on OpenBSD

Man page or keyword search:  
man Server   11362 pages
apropos Keyword Search (all sections)
Output format
OpenBSD logo
[printable version]

SCRIPT(7)		   OpenBSD Reference Manual		     SCRIPT(7)

NAME
     script - interpreter script execution

DESCRIPTION
     The system is capable of treating a text file containing commands
     intended for an interpreter, such as sh(1) or awk(1), as an executable
     program.

     An ``interpreter script'' is a file which has been set executable (see
     chmod(2)) and which has a first line of the form:

	   #! pathname [argument]

     The `#!' must appear as the first two characters of the file.  A space
     between the `#!' and pathname is optional.	 At most one argument may
     follow pathname, and the length of the entire line is limited (see
     below).

     If such a file is executed (such as via the execve(2) system call), the
     interpreter specified by the pathname is executed by the system.  (The
     pathname is executed without regard to the PATH variable, so in general
     pathname should be an absolute path.)

     The arguments passed to the interpreter will be as follows.  argv[0] will
     be the path to the interpreter itself, as specified on the first line of
     the script.  If there is an argument following pathname on the first line
     of the script, it will be passed as argv[1].  The subsequent elements of
     argv will be the path to the interpreter script file itself (i.e. the
     original argv[0]) followed by any further arguments passed when execve(2)
     was invoked to execute the script file.

     By convention, it is expected that an interpreter will open the script
     file passed as an argument and process the commands within it.  Typical
     interpreters treat `#' as a comment character, and thus will ignore the
     initial line of the script because it begins `#!', but there is no
     requirement for this per se.

     On OpenBSD, the length of the interpreter line following the `#!' is
     limited to MAXINTERP, as defined in <sys/param.h>.	 Other operating
     systems impose different limits on the length of the `#!' line (see
     below).

     Note that the interpreter may not itself be an interpreter script.	 If
     pathname does not point to an executable binary, execution of the
     interpreter script will fail.

   Trampolines and Portable Scripts
     Different operating systems often have interpreters located in different
     locations, and the kernel executes the passed interpreter without regard
     to the setting of environment variables such as PATH.  This makes it
     somewhat challenging to set the `#!' line of a script so that it will run
     identically on different systems.

     Since the env(1) utility executes a command passed to it on its command
     line, it is often used as a ``trampoline'' to render scripts portable.
     If the leading line of a script reads

	   #! /usr/bin/env interp

     then the env(1) command will execute the ``interp'' command it finds in
     its PATH, passing on to it all subsequent arguments with which it itself
     was called.  Since /usr/bin/env is found on almost all POSIX style
     systems, this trick is frequently exploited by authors who need a script
     to execute without change on multiple systems.

   Historical Note: Scripts without `#!'
     Shell scripts predate the invention of the `#!' convention, which is
     implemented in the kernel.	 In the days of Version 7 AT&T UNIX, there was
     only one interpreter used on the system, /bin/sh, and the shell treated
     any file that failed to execute with an ENOEXEC error (see intro(2)) as a
     shell script.

     Most shells (such as sh(1)) and certain other facilities (including
     execlp(3) and execvp(3) but not other types of exec(3) calls) still pass
     interpreter scripts that do not include the `#!' (and thus fail to
     execute with ENOEXEC) to /bin/sh.

     As this behavior is implemented outside the kernel, there is no mechanism
     that forces it to be respected by all programs that execute other
     programs.	It is thus not completely reliable.  It is therefore important
     to always include

	   #!/bin/sh

     in front of Bourne shell scripts, and to treat the traditional behavior
     as obsolete.

EXAMPLES
     Suppose that an executable binary exists in /bin/interp and that the file
     /tmp/script contains:

	   #!/bin/interp -arg

	   [...]

     and that /tmp/script is set mode 755.

     Executing

	   $ /tmp/script one two three

     at the shell will result in /bin/interp being executed, receiving the
     following arguments in argv (numbered from 0):

	   "/bin/interp", "-arg", "/tmp/script", "one", "two", "three"

   Portability Note: Multiple arguments
     The behavior of multiple arguments on the `#!' line is highly non-
     portable between different systems.  In general, only one argument can be
     assumed to work consistently.

     Consider the following variation on the previous example.	Suppose that
     an executable binary exists in /bin/interp and that the file /tmp/script
     contains:

	   #!/bin/interp -x -y

	   [...]

     and that /tmp/script is set mode 755.

     Executing

	   $ /tmp/script one two three

     at the shell will result in /bin/interp being executed, receiving the
     following arguments in argv (numbered from 0):

	   "/bin/interp", "-x -y", "/tmp/script", "one", "two", "three"

     Note that "-x -y" will be passed on OpenBSD as a single argument.

     Although most POSIX style operating systems will pass only one argument,
     the behavior when multiple arguments are included is not consistent
     between platforms.	 Some, such as OpenBSD, will concatenate multiple
     arguments into a single argument (as above), some will truncate them, and
     at least one will pass them as multiple arguments.

     The OpenBSD behavior is common but not universal.	Sun's Solaris would
     present the above argument as "-x", dropping the " -y" entirely.  Perhaps
     uniquely, recent versions of Apple's OS X will actually pass multiple
     arguments properly, i.e.:

	   "/bin/interp", "-x", "-y", "/tmp/script", "one", "two", "three"

     The behavior of the system in the face of multiple arguments is thus not
     currently standardized, should not be relied on, and may be changed in
     future releases.  In general, pass at most one argument, and do not rely
     on multiple arguments being concatenated.

SEE ALSO
     awk(1), csh(1), ksh(1), sh(1), chmod(2), execve(2), intro(2), execlp(3),
     execvp(3)

STANDARDS
     The behavior of interpreter scripts is obliquely referred to, but never
     actually described in, IEEE Std 1003.1-2004 (``POSIX'').

     The behavior is partially (but not completely) described in the System V
     Interface Definition, Fourth Edition (``SVID4'').

     Although it has never been formally standardized, the behavior described
     is largely portable across POSIX style systems, with two significant
     exceptions: the maximum length of the `#!' line, and the behavior if
     multiple arguments are passed.  Please be aware that the behavior in the
     face of multiple arguments is not consistent across systems.

HISTORY
     The behavior of the kernel when encountering scripts that start in `#!'
     was not present in Version 7 AT&T UNIX.  A Usenet posting to net.unix by
     Guy Harris on October 16, 1984 claims that the idea for the `#!' behavior
     was first proposed by Dennis Ritchie but that the first implementation
     was on BSD.

     Historical manuals (specifically the exec man page) indicate that the
     behavior was present in 4BSD at least as early as April, 1981.
     Information on precisely when it was first implemented, and in which
     version of UNIX, is solicited.

CAVEATS
     Numerous security problems are associated with setuid interpreter
     scripts.

     In addition to the fact that many interpreters (and scripts) are simply
     not designed to be robust in a setuid context, a race condition exists
     between the moment that the kernel examines the interpreter script file
     and the moment that the newly invoked interpreter opens the file itself.

     Subtle techniques can be used to subvert even seemingly well written
     scripts.  Scripts executed by Bourne type shells can be subverted in
     numerous ways, such as by setting the IFS variable before executing the
     script.  Other interpreters possess their own vulnerabilities.  Setting
     the Set-user-ID on execution (SUID) bit is therefore very dangerous, and
     should not be done lightly, if at all.

OpenBSD 4.9		      September 19, 2008		   OpenBSD 4.9
[top]

List of man pages available for OpenBSD

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net