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