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