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