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