1 .\" $OpenBSD: script.7,v 1.8 2019/08/11 15:48:08 deraadt Exp $
3 .\" $NetBSD: script.7,v 1.6 2010/03/22 18:58:32 joerg Exp $
5 .\" Copyright (c) 2005 The NetBSD Foundation, Inc.
6 .\" All rights reserved.
8 .\" This document was originally contributed to The NetBSD Foundation
9 .\" by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC.
11 .\" Redistribution and use in source and binary forms, with or without
12 .\" modification, are permitted provided that the following conditions
14 .\" 1. Redistributions of source code must retain the above copyright
15 .\" notice, this list of conditions and the following disclaimer.
16 .\" 2. Redistributions in binary form must reproduce the above copyright
17 .\" notice, this list of conditions and the following disclaimer in the
18 .\" documentation and/or other materials provided with the distribution.
20 .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 .\" POSSIBILITY OF SUCH DAMAGE.
37 .Nd interpreter script execution
39 The system is capable of treating a text file containing commands
40 intended for an interpreter, such as
44 as an executable program.
47 .Dq interpreter script
48 is a file which has been set executable (see
50 and which has a first line of the form:
52 .D1 Li #! Ar pathname Op Ar argument
56 must appear as the first two characters of the file.
66 and the length of the entire line is limited (see below).
68 If such a file is executed (such as via the
70 system call), the interpreter specified by the
72 is executed by the system.
75 is executed without regard to the
77 variable, so in general
79 should be an absolute path.)
81 The arguments passed to the interpreter will be as follows.
83 will be the path to the interpreter itself, as specified on the first
89 on the first line of the script, it will be passed as
91 The subsequent elements of
93 will be the path to the interpreter script file itself (i.e. the
96 followed by any further arguments passed when
98 was invoked to execute the script file.
100 By convention, it is expected that an interpreter will open the script
101 file passed as an argument and process the commands within it.
102 Typical interpreters treat
104 as a comment character, and thus will ignore the initial line of the script
107 but there is no requirement for this per se.
115 itself, is limited to
119 Other operating systems impose different limits on the length of
124 Note that the interpreter may not itself be an interpreter script.
127 does not point to an executable binary, execution of the interpreter
129 .Ss Trampolines and Portable Scripts
130 Different operating systems often have interpreters located in
131 different locations, and the kernel executes the passed interpreter
132 without regard to the setting of environment variables such as
134 This makes it somewhat challenging to set the
136 line of a script so that it will run identically on different systems.
140 utility executes a command passed to it on its command line, it is
143 to render scripts portable.
144 If the leading line of a script reads
146 .Dl #! /usr/bin/env interp
150 command will execute the
152 command it finds in its
154 passing on to it all subsequent arguments with which it itself was called.
157 is found on almost all
159 style systems, this trick is frequently exploited by authors who need
160 a script to execute without change on multiple systems.
161 .Ss Historical Note: Scripts without `#!'
162 Shell scripts predate the invention of the
164 convention, which is implemented in the kernel.
167 there was only one interpreter used on the system,
169 and the shell treated any file that failed to execute with an
178 and certain other facilities (including
182 but not other types of
185 interpreter scripts that do not include the
187 (and thus fail to execute with
192 As this behavior is implemented outside the kernel, there is no
193 mechanism that forces it to be respected by all programs that execute
195 It is thus not completely reliable.
196 It is therefore important to always include
200 in front of Bourne shell scripts, and to treat the traditional
201 behavior as obsolete.
203 Suppose that an executable binary exists in
208 .Bd -literal -offset indent
220 .Dl $ /tmp/script one two three
222 at the shell will result in
224 being executed, receiving the following arguments in
227 .Bd -ragged -offset indent
235 .Ss Portability Note: Multiple arguments
236 The behavior of multiple arguments on the
238 line is highly non-portable between different systems.
239 In general, only one argument can be assumed to work consistently.
241 Consider the following variation on the previous example.
242 Suppose that an executable binary exists in
247 .Bd -literal -offset indent
259 .Dl $ /tmp/script one two three
261 at the shell will result in
263 being executed, receiving the following arguments in
266 .Bd -ragged -offset indent
279 as a single argument.
283 style operating systems will pass only one
285 the behavior when multiple arguments are included is not
286 consistent between platforms.
289 will concatenate multiple arguments into a single argument (as above),
290 some will truncate them, and at least one will pass them as multiple
295 behavior is common but not universal.
298 would present the above argument as
303 Perhaps uniquely, recent versions of Apple's
305 will actually pass multiple arguments properly, i.e.:
306 .Bd -ragged -offset indent
316 The behavior of the system in the face of multiple arguments is thus
317 not currently standardized, should not be relied on, and may be
318 changed in future releases.
319 In general, pass at most one argument, and do not rely on multiple
320 arguments being concatenated.
331 The behavior of interpreter scripts is obliquely referred to, but
332 never actually described in,
335 The behavior is partially (but not completely) described in the
338 Although it has never been formally standardized, the behavior
339 described is largely portable across
341 style systems, with two significant exceptions: the maximum length of the
343 line, and the behavior if multiple arguments are passed.
344 Please be aware that the behavior in the
345 face of multiple arguments is not consistent across systems.
347 The behavior of the kernel when encountering scripts that start in
351 A Usenet posting to net.unix by Guy Harris on October 16, 1984 claims
352 that the idea for the
354 behavior was first proposed by Dennis Ritchie but that the first
355 implementation was on
358 Historical manuals (specifically the exec man page) indicate that the
359 behavior was present in
361 at least as early as April, 1981.
362 Information on precisely when it was first implemented, and in which
367 Numerous security problems are associated with setuid interpreter
370 In addition to the fact that many interpreters (and scripts) are
371 simply not designed to be robust in a setuid context, a race condition
372 exists between the moment that the kernel examines the interpreter
373 script file and the moment that the newly invoked interpreter opens
376 Subtle techniques can be used to subvert even seemingly well written scripts.
377 Scripts executed by Bourne type shells can be subverted in numerous
378 ways, such as by setting the
380 variable before executing the script.
381 Other interpreters possess their own vulnerabilities.
382 Setting the Set-user-ID on execution (SUID) bit
383 is therefore very dangerous, and should not be done lightly, if at all.