xref: /openbsd-src/share/man/man7/script.7 (revision af69310cb425c54a06a1d26d10c264a1f0cf37b3)
1.\"	$OpenBSD: script.7,v 1.2 2005/06/05 19:40:22 jmc Exp $
2.\"
3.\"	$NetBSD: script.7,v 1.1 2005/05/07 02:20:34 perry Exp $
4.\"
5.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
6.\" All rights reserved.
7.\"
8.\" This document was originally contributed to The NetBSD Foundation
9.\" by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC.
10.\"
11.\" Redistribution and use in source and binary forms, with or without
12.\" modification, are permitted provided that the following conditions
13.\" are met:
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.
19.\" 3. All advertising materials mentioning features or use of this software
20.\"    must display the following acknowledgement:
21.\"        This product includes software developed by the NetBSD
22.\"        Foundation, Inc. and its contributors.
23.\" 4. Neither the name of The NetBSD Foundation nor the names of its
24.\"    contributors may be used to endorse or promote products derived
25.\"    from this software without specific prior written permission.
26.\"
27.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
28.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
29.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
31.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37.\" POSSIBILITY OF SUCH DAMAGE.
38.\"
39.Dd May 6, 2005
40.Dt SCRIPT 7
41.Os
42.Sh NAME
43.Nm script
44.Nd interpreter script execution
45.Sh DESCRIPTION
46The system is capable of treating a text file containing commands
47intended for an interpreter, such as
48.Xr sh 1
49or
50.Xr awk 1 ,
51as an executable program.
52.Pp
53An
54.Dq interpreter script
55is a file which has been set executable (see
56.Xr chmod 2 )
57and which has a first line of the form:
58.Pp
59.D1 Li #! Ar pathname Op Ar argument
60.Pp
61The
62.Sq #!
63must appear as the first two characters of the file.
64A space between the
65.Sq #!
66and
67.Ar pathname
68is optional.
69At most one
70.Ar argument
71may follow
72.Ar pathname ,
73and the length of the entire line is limited (see below).
74.Pp
75If such a file is executed (such as via the
76.Xr execve 2
77system call), the interpreter specified by the
78.Ar pathname
79is executed by the system.
80(The
81.Ar pathname
82is executed without regard to the
83.Ev PATH
84variable, so in general
85.Ar pathname
86should be an absolute path.)
87.Pp
88The arguments passed to the interpreter will be as follows.
89.Va argv[0]
90will be the path to the interpreter itself, as specified on the first
91line of the script.
92If there is an
93.Ar argument
94following
95.Ar pathname
96on the first line of the script, it will be passed as
97.Va argv[1] .
98The subsequent elements of
99.Va argv
100will be the path to the interpreter script file itself (i.e. the
101original
102.Va argv[0] )
103followed by any further arguments passed when
104.Xr execve 2
105was invoked to execute the script file.
106.Pp
107By convention, it is expected that an interpreter will open the script
108file passed as an argument and process the commands within it.
109Typical interpreters treat
110.Sq #
111as a comment character, and thus will ignore the initial line of the script
112because it begins
113.Sq #! ,
114but there is no requirement for this per se.
115.Pp
116On
117.Ox ,
118the length of the
119.Sq #!
120line is limited to
121.Dv MAXINTERP ,
122as defined in
123.Aq Pa sys/param.h .
124Other operating systems impose different limits on the length of
125the
126.Sq #!
127line (see below).
128.Pp
129Note that the interpreter may not itself be an interpreter script.
130If
131.Ar pathname
132does not point to an executable binary, execution of the interpreter
133script will fail.
134.Ss Trampolines and Portable Scripts
135Different operating systems often have interpreters located in
136different locations, and the kernel executes the passed interpreter
137without regard to the setting of environment variables such as
138.Ev PATH .
139This makes it somewhat challenging to set the
140.Sq #!
141line of a script so that it will run identically on different systems.
142.Pp
143Since the
144.Xr env 1
145utility executes a command passed to it on its command line, it is
146often used as a
147.Dq trampoline
148to render scripts portable.
149If the leading line of a script reads
150.Pp
151.Dl #! /usr/bin/env interp
152.Pp
153then the
154.Xr env 1
155command will execute the
156.Dq interp
157command it finds in its
158.Ev PATH ,
159passing on to it all subsequent arguments with which it itself was called.
160Since
161.Pa /usr/bin/env
162is found on almost all
163.Tn POSIX
164style systems, this trick is frequently exploited by authors who need
165a script to execute without change on multiple systems.
166.Ss Historical Note: Scripts without `#!'
167Shell scripts predate the invention of the
168.Sq #!
169convention, which is implemented in the kernel.
170In the days of
171.At v7 ,
172there was only one interpreter used on the system,
173.Pa /bin/sh ,
174and the shell treated any file that failed to execute with an
175.Er ENOEXEC
176error
177(see
178.Xr intro 2 )
179as a shell script.
180.Pp
181Most shells (such as
182.Xr sh 1 )
183and certain other facilities (including
184.Xr execlp 3
185and
186.Xr execvp 3
187but not other types of
188.Xr exec 3
189calls) still pass
190interpreter scripts that do not include the
191.Sq #!
192(and thus fail to execute with
193.Er ENOEXEC )
194to
195.Pa /bin/sh .
196.Pp
197As this behavior is implemented outside the kernel, there is no
198mechanism that forces it to be respected by all programs that execute
199other programs.
200It is thus not completely reliable.
201It is therefore important to always include
202.Pp
203.Dl #!/bin/sh
204.Pp
205in front of Bourne shell scripts, and to treat the traditional
206behavior as obsolete.
207.Sh EXAMPLES
208Suppose that an executable binary exists in
209.Pa /bin/interp
210and that the file
211.Pa /tmp/script
212contains:
213.Bd -literal -offset indent
214#!/bin/interp -arg
215
216[...]
217.Ed
218.Pp
219and that
220.Pa /tmp/script
221is set mode 755.
222.Pp
223Executing
224.Pp
225.Dl $ /tmp/script one two three
226.Pp
227at the shell will result in
228.Pa /bin/interp
229being executed, receiving the following arguments in
230.Va argv
231(numbered from 0):
232.Bd -ragged -offset indent
233.Qq /bin/interp ,
234.Qq "-arg" ,
235.Qq /tmp/script ,
236.Qq one ,
237.Qq two ,
238.Qq three
239.Ed
240.Ss Portability Note: Multiple arguments
241The behavior of multiple arguments on the
242.Sq #!
243line is highly non-portable between different systems.
244In general, only one argument can be assumed to work consistently.
245.Pp
246Consider the following variation on the previous example.
247Suppose that an executable binary exists in
248.Pa /bin/interp
249and that the file
250.Pa /tmp/script
251contains:
252.Bd -literal -offset indent
253#!/bin/interp -x -y
254
255[...]
256.Ed
257.Pp
258and that
259.Pa /tmp/script
260is set mode 755.
261.Pp
262Executing
263.Pp
264.Dl $ /tmp/script one two three
265.Pp
266at the shell will result in
267.Pa /bin/interp
268being executed, receiving the following arguments in
269.Va argv
270(numbered from 0):
271.Bd -ragged -offset indent
272.Qq /bin/interp ,
273.Qq "-x -y" ,
274.Qq /tmp/script ,
275.Qq one ,
276.Qq two ,
277.Qq three
278.Ed
279.Pp
280Note that
281.Qq "-x -y"
282will be passed on
283.Ox
284as a single argument.
285.Pp
286Although most
287.Tn POSIX
288style operating systems will pass only one
289.Ar argument ,
290the behavior when with multiple arguments are included is not
291consistent between platforms.
292Some, such as
293.Ox ,
294will concatenate multiple arguments into a single argument (as above),
295some will truncate them, and at least one will pass them as multiple
296arguments.
297.Pp
298The
299.Ox
300behavior is common but not universal.
301Sun's
302.Tn Solaris
303would present the above argument as
304.Qq -x ,
305dropping the
306.Qq " -y"
307entirely.
308Perhaps uniquely, recent versions of Apple's
309.Tn OS X
310will actually pass multiple arguments properly, i.e.:
311.Bd -ragged -offset indent
312.Qq /bin/interp ,
313.Qq -x ,
314.Qq -y ,
315.Qq /tmp/script ,
316.Qq one ,
317.Qq two ,
318.Qq three
319.Ed
320.Pp
321The behavior of the system in the face of multiple arguments is thus
322not currently standardized, should not be relied on, and may be
323changed in future releases.
324In general, pass at most one argument, and do not rely on multiple
325arguments being concatenated.
326.Sh SEE ALSO
327.Xr awk 1 ,
328.Xr csh 1 ,
329.Xr ksh 1 ,
330.Xr sh 1 ,
331.Xr chmod 2 ,
332.Xr execve 2 ,
333.Xr intro 2 ,
334.Xr execlp 3 ,
335.Xr execvp 3
336.Sh STANDARDS
337The behavior of interpreter scripts is obliquely referred to, but
338never actually described in,
339.St -p1003.1-2004 .
340.Pp
341The behavior is partially (but not completely) described in the
342.St -svid4 .
343.Pp
344Although it has never been formally standardized, the behavior
345described is largely portable across
346.Tn POSIX
347style systems, with two significant exceptions: the maximum length of the
348.Sq #!
349line, and the behavior if multiple arguments are passed.
350Please be aware that the behavior in the
351face of multiple arguments is not consistent across systems.
352.Sh HISTORY
353The behavior of the kernel when encountering scripts that start in
354.Sq #!
355was not present in
356.At v7 .
357A Usenet posting to net.unix by Guy Harris on October 16, 1984 claims
358that the idea for the
359.Sq #!
360behavior was first proposed by Dennis Ritchie but that the first
361implementation was on
362.Bx .
363.Pp
364Historical manuals (specifically the exec man page) indicate that the
365behavior was present in
366.Bx 4
367at least as early as April, 1981.
368Information on precisely when it was first implemented, and in which
369version of
370.Ux ,
371is solicited.
372.Sh CAVEATS
373Numerous security problems are associated with setuid interpreter
374scripts.
375.Pp
376In addition to the fact that many interpreters (and scripts) are
377simply not designed to be robust in a setuid context, a race condition
378exists between the moment that the kernel examines the interpreter
379script file and the moment that the newly invoked interpreter opens
380the file itself.
381.Pp
382Subtle techniques can be used to subvert even seemingly well written scripts.
383Scripts executed by Bourne type shells can be subverted in numerous
384ways, such as by setting the
385.Ev IFS
386variable before executing the script.
387Other interpreters possess their own vulnerabilities.
388Setting the Set-user-ID on execution (SUID) bit
389is therefore very dangerous, and should not be done lightly, if at all.
390