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