1*a4e61cf2Sjsg.\" $OpenBSD: script.7,v 1.9 2022/02/06 00:29:02 jsg Exp $ 26f6300c6Sjmc.\" 36f6300c6Sjmc.\" $NetBSD: script.7,v 1.1 2005/05/07 02:20:34 perry Exp $ 46f6300c6Sjmc.\" 56f6300c6Sjmc.\" Copyright (c) 2005 The NetBSD Foundation, Inc. 66f6300c6Sjmc.\" All rights reserved. 76f6300c6Sjmc.\" 86f6300c6Sjmc.\" This document was originally contributed to The NetBSD Foundation 96f6300c6Sjmc.\" by Perry E. Metzger of Metzger, Dowdeswell & Co. LLC. 106f6300c6Sjmc.\" 116f6300c6Sjmc.\" Redistribution and use in source and binary forms, with or without 126f6300c6Sjmc.\" modification, are permitted provided that the following conditions 136f6300c6Sjmc.\" are met: 146f6300c6Sjmc.\" 1. Redistributions of source code must retain the above copyright 156f6300c6Sjmc.\" notice, this list of conditions and the following disclaimer. 166f6300c6Sjmc.\" 2. Redistributions in binary form must reproduce the above copyright 176f6300c6Sjmc.\" notice, this list of conditions and the following disclaimer in the 186f6300c6Sjmc.\" documentation and/or other materials provided with the distribution. 196f6300c6Sjmc.\" 206f6300c6Sjmc.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 216f6300c6Sjmc.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 226f6300c6Sjmc.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 236f6300c6Sjmc.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 246f6300c6Sjmc.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 256f6300c6Sjmc.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 266f6300c6Sjmc.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 276f6300c6Sjmc.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 286f6300c6Sjmc.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 296f6300c6Sjmc.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 306f6300c6Sjmc.\" POSSIBILITY OF SUCH DAMAGE. 316f6300c6Sjmc.\" 32*a4e61cf2Sjsg.Dd $Mdocdate: February 6 2022 $ 336f6300c6Sjmc.Dt SCRIPT 7 346f6300c6Sjmc.Os 356f6300c6Sjmc.Sh NAME 366f6300c6Sjmc.Nm script 376f6300c6Sjmc.Nd interpreter script execution 386f6300c6Sjmc.Sh DESCRIPTION 396f6300c6SjmcThe system is capable of treating a text file containing commands 406f6300c6Sjmcintended for an interpreter, such as 416f6300c6Sjmc.Xr sh 1 426f6300c6Sjmcor 436f6300c6Sjmc.Xr awk 1 , 446f6300c6Sjmcas an executable program. 456f6300c6Sjmc.Pp 466f6300c6SjmcAn 476f6300c6Sjmc.Dq interpreter script 486f6300c6Sjmcis a file which has been set executable (see 496f6300c6Sjmc.Xr chmod 2 ) 506f6300c6Sjmcand which has a first line of the form: 516f6300c6Sjmc.Pp 526f6300c6Sjmc.D1 Li #! Ar pathname Op Ar argument 536f6300c6Sjmc.Pp 546f6300c6SjmcThe 556f6300c6Sjmc.Sq #! 566f6300c6Sjmcmust appear as the first two characters of the file. 576f6300c6SjmcA space between the 586f6300c6Sjmc.Sq #! 596f6300c6Sjmcand 606f6300c6Sjmc.Ar pathname 616f6300c6Sjmcis optional. 626f6300c6SjmcAt most one 636f6300c6Sjmc.Ar argument 646f6300c6Sjmcmay follow 656f6300c6Sjmc.Ar pathname , 666f6300c6Sjmcand the length of the entire line is limited (see below). 676f6300c6Sjmc.Pp 686f6300c6SjmcIf such a file is executed (such as via the 696f6300c6Sjmc.Xr execve 2 706f6300c6Sjmcsystem call), the interpreter specified by the 716f6300c6Sjmc.Ar pathname 726f6300c6Sjmcis executed by the system. 736f6300c6Sjmc(The 746f6300c6Sjmc.Ar pathname 756f6300c6Sjmcis executed without regard to the 766f6300c6Sjmc.Ev PATH 776f6300c6Sjmcvariable, so in general 786f6300c6Sjmc.Ar pathname 796f6300c6Sjmcshould be an absolute path.) 806f6300c6Sjmc.Pp 816f6300c6SjmcThe arguments passed to the interpreter will be as follows. 826f6300c6Sjmc.Va argv[0] 836f6300c6Sjmcwill be the path to the interpreter itself, as specified on the first 846f6300c6Sjmcline of the script. 856f6300c6SjmcIf there is an 866f6300c6Sjmc.Ar argument 876f6300c6Sjmcfollowing 886f6300c6Sjmc.Ar pathname 896f6300c6Sjmcon the first line of the script, it will be passed as 906f6300c6Sjmc.Va argv[1] . 916f6300c6SjmcThe subsequent elements of 926f6300c6Sjmc.Va argv 936f6300c6Sjmcwill be the path to the interpreter script file itself (i.e. the 946f6300c6Sjmcoriginal 956f6300c6Sjmc.Va argv[0] ) 966f6300c6Sjmcfollowed by any further arguments passed when 976f6300c6Sjmc.Xr execve 2 986f6300c6Sjmcwas invoked to execute the script file. 996f6300c6Sjmc.Pp 1006f6300c6SjmcBy convention, it is expected that an interpreter will open the script 1016f6300c6Sjmcfile passed as an argument and process the commands within it. 1026f6300c6SjmcTypical interpreters treat 1036f6300c6Sjmc.Sq # 1046f6300c6Sjmcas a comment character, and thus will ignore the initial line of the script 1056f6300c6Sjmcbecause it begins 1066f6300c6Sjmc.Sq #! , 1076f6300c6Sjmcbut there is no requirement for this per se. 1086f6300c6Sjmc.Pp 1096f6300c6SjmcOn 1106f6300c6Sjmc.Ox , 1115cf31938Sdjmthe length of the interpreter line following the 1126f6300c6Sjmc.Sq #! 1135cf31938Sdjmis limited to 1146f6300c6Sjmc.Dv MAXINTERP , 1156f6300c6Sjmcas defined in 116369bef3aSschwarze.In sys/param.h . 1176f6300c6SjmcOther operating systems impose different limits on the length of 1186f6300c6Sjmcthe 1196f6300c6Sjmc.Sq #! 1206f6300c6Sjmcline (see below). 1216f6300c6Sjmc.Pp 1226f6300c6SjmcNote that the interpreter may not itself be an interpreter script. 1236f6300c6SjmcIf 1246f6300c6Sjmc.Ar pathname 1256f6300c6Sjmcdoes not point to an executable binary, execution of the interpreter 1266f6300c6Sjmcscript will fail. 1276f6300c6Sjmc.Ss Trampolines and Portable Scripts 1286f6300c6SjmcDifferent operating systems often have interpreters located in 1296f6300c6Sjmcdifferent locations, and the kernel executes the passed interpreter 1306f6300c6Sjmcwithout regard to the setting of environment variables such as 1316f6300c6Sjmc.Ev PATH . 1326f6300c6SjmcThis makes it somewhat challenging to set the 1336f6300c6Sjmc.Sq #! 1346f6300c6Sjmcline of a script so that it will run identically on different systems. 1356f6300c6Sjmc.Pp 1366f6300c6SjmcSince the 1376f6300c6Sjmc.Xr env 1 1386f6300c6Sjmcutility executes a command passed to it on its command line, it is 1396f6300c6Sjmcoften used as a 1406f6300c6Sjmc.Dq trampoline 1416f6300c6Sjmcto render scripts portable. 1426f6300c6SjmcIf the leading line of a script reads 1436f6300c6Sjmc.Pp 1446f6300c6Sjmc.Dl #! /usr/bin/env interp 1456f6300c6Sjmc.Pp 1466f6300c6Sjmcthen the 1476f6300c6Sjmc.Xr env 1 1486f6300c6Sjmccommand will execute the 1496f6300c6Sjmc.Dq interp 1506f6300c6Sjmccommand it finds in its 1516f6300c6Sjmc.Ev PATH , 1526f6300c6Sjmcpassing on to it all subsequent arguments with which it itself was called. 1536f6300c6SjmcSince 1546f6300c6Sjmc.Pa /usr/bin/env 1556f6300c6Sjmcis found on almost all 1566f6300c6Sjmc.Tn POSIX 1576f6300c6Sjmcstyle systems, this trick is frequently exploited by authors who need 1586f6300c6Sjmca script to execute without change on multiple systems. 1596f6300c6Sjmc.Ss Historical Note: Scripts without `#!' 1606f6300c6SjmcShell scripts predate the invention of the 1616f6300c6Sjmc.Sq #! 1626f6300c6Sjmcconvention, which is implemented in the kernel. 1636f6300c6SjmcIn the days of 1646f6300c6Sjmc.At v7 , 1656f6300c6Sjmcthere was only one interpreter used on the system, 1666f6300c6Sjmc.Pa /bin/sh , 1676f6300c6Sjmcand the shell treated any file that failed to execute with an 1686f6300c6Sjmc.Er ENOEXEC 1696f6300c6Sjmcerror 1706f6300c6Sjmc(see 1716f6300c6Sjmc.Xr intro 2 ) 1726f6300c6Sjmcas a shell script. 1736f6300c6Sjmc.Pp 1746f6300c6SjmcMost shells (such as 1756f6300c6Sjmc.Xr sh 1 ) 1766f6300c6Sjmcand certain other facilities (including 1776f6300c6Sjmc.Xr execlp 3 1786f6300c6Sjmcand 179d4db6826Sderaadt.Xr execvp 3 ) 180d4db6826Sderaadtstill pass interpreter scripts that do not include the 1816f6300c6Sjmc.Sq #! 1826f6300c6Sjmc(and thus fail to execute with 1836f6300c6Sjmc.Er ENOEXEC ) 1846f6300c6Sjmcto 1856f6300c6Sjmc.Pa /bin/sh . 1866f6300c6Sjmc.Pp 1876f6300c6SjmcAs this behavior is implemented outside the kernel, there is no 1886f6300c6Sjmcmechanism that forces it to be respected by all programs that execute 1896f6300c6Sjmcother programs. 1906f6300c6SjmcIt is thus not completely reliable. 1916f6300c6SjmcIt is therefore important to always include 1926f6300c6Sjmc.Pp 1936f6300c6Sjmc.Dl #!/bin/sh 1946f6300c6Sjmc.Pp 1956f6300c6Sjmcin front of Bourne shell scripts, and to treat the traditional 1966f6300c6Sjmcbehavior as obsolete. 1976f6300c6Sjmc.Sh EXAMPLES 1986f6300c6SjmcSuppose that an executable binary exists in 1996f6300c6Sjmc.Pa /bin/interp 2006f6300c6Sjmcand that the file 2016f6300c6Sjmc.Pa /tmp/script 2026f6300c6Sjmccontains: 2036f6300c6Sjmc.Bd -literal -offset indent 2046f6300c6Sjmc#!/bin/interp -arg 2056f6300c6Sjmc 2066f6300c6Sjmc[...] 2076f6300c6Sjmc.Ed 2086f6300c6Sjmc.Pp 2096f6300c6Sjmcand that 2106f6300c6Sjmc.Pa /tmp/script 2116f6300c6Sjmcis set mode 755. 2126f6300c6Sjmc.Pp 2136f6300c6SjmcExecuting 2146f6300c6Sjmc.Pp 2156f6300c6Sjmc.Dl $ /tmp/script one two three 2166f6300c6Sjmc.Pp 2176f6300c6Sjmcat the shell will result in 2186f6300c6Sjmc.Pa /bin/interp 2196f6300c6Sjmcbeing executed, receiving the following arguments in 2206f6300c6Sjmc.Va argv 2216f6300c6Sjmc(numbered from 0): 2226f6300c6Sjmc.Bd -ragged -offset indent 2236f6300c6Sjmc.Qq /bin/interp , 2246f6300c6Sjmc.Qq "-arg" , 2256f6300c6Sjmc.Qq /tmp/script , 2266f6300c6Sjmc.Qq one , 2276f6300c6Sjmc.Qq two , 2286f6300c6Sjmc.Qq three 2296f6300c6Sjmc.Ed 2306f6300c6Sjmc.Ss Portability Note: Multiple arguments 2316f6300c6SjmcThe behavior of multiple arguments on the 2326f6300c6Sjmc.Sq #! 2336f6300c6Sjmcline is highly non-portable between different systems. 2346f6300c6SjmcIn general, only one argument can be assumed to work consistently. 2356f6300c6Sjmc.Pp 2366f6300c6SjmcConsider the following variation on the previous example. 2376f6300c6SjmcSuppose that an executable binary exists in 2386f6300c6Sjmc.Pa /bin/interp 2396f6300c6Sjmcand that the file 2406f6300c6Sjmc.Pa /tmp/script 2416f6300c6Sjmccontains: 2426f6300c6Sjmc.Bd -literal -offset indent 2436f6300c6Sjmc#!/bin/interp -x -y 2446f6300c6Sjmc 2456f6300c6Sjmc[...] 2466f6300c6Sjmc.Ed 2476f6300c6Sjmc.Pp 2486f6300c6Sjmcand that 2496f6300c6Sjmc.Pa /tmp/script 2506f6300c6Sjmcis set mode 755. 2516f6300c6Sjmc.Pp 2526f6300c6SjmcExecuting 2536f6300c6Sjmc.Pp 2546f6300c6Sjmc.Dl $ /tmp/script one two three 2556f6300c6Sjmc.Pp 2566f6300c6Sjmcat the shell will result in 2576f6300c6Sjmc.Pa /bin/interp 2586f6300c6Sjmcbeing executed, receiving the following arguments in 2596f6300c6Sjmc.Va argv 2606f6300c6Sjmc(numbered from 0): 2616f6300c6Sjmc.Bd -ragged -offset indent 2626f6300c6Sjmc.Qq /bin/interp , 2636f6300c6Sjmc.Qq "-x -y" , 2646f6300c6Sjmc.Qq /tmp/script , 2656f6300c6Sjmc.Qq one , 2666f6300c6Sjmc.Qq two , 2676f6300c6Sjmc.Qq three 2686f6300c6Sjmc.Ed 2696f6300c6Sjmc.Pp 2706f6300c6SjmcNote that 2716f6300c6Sjmc.Qq "-x -y" 2726f6300c6Sjmcwill be passed on 2736f6300c6Sjmc.Ox 2746f6300c6Sjmcas a single argument. 2756f6300c6Sjmc.Pp 2766f6300c6SjmcAlthough most 2776f6300c6Sjmc.Tn POSIX 2786f6300c6Sjmcstyle operating systems will pass only one 2796f6300c6Sjmc.Ar argument , 2805f7a33e3Sjaredythe behavior when multiple arguments are included is not 2816f6300c6Sjmcconsistent between platforms. 2826f6300c6SjmcSome, such as 2836f6300c6Sjmc.Ox , 2846f6300c6Sjmcwill concatenate multiple arguments into a single argument (as above), 2856f6300c6Sjmcsome will truncate them, and at least one will pass them as multiple 2866f6300c6Sjmcarguments. 2876f6300c6Sjmc.Pp 2886f6300c6SjmcThe 2896f6300c6Sjmc.Ox 2906f6300c6Sjmcbehavior is common but not universal. 2916f6300c6SjmcSun's 2926f6300c6Sjmc.Tn Solaris 2936f6300c6Sjmcwould present the above argument as 2946f6300c6Sjmc.Qq -x , 2956f6300c6Sjmcdropping the 2966f6300c6Sjmc.Qq " -y" 2976f6300c6Sjmcentirely. 2986f6300c6SjmcPerhaps uniquely, recent versions of Apple's 2996f6300c6Sjmc.Tn OS X 3006f6300c6Sjmcwill actually pass multiple arguments properly, i.e.: 3016f6300c6Sjmc.Bd -ragged -offset indent 3026f6300c6Sjmc.Qq /bin/interp , 3036f6300c6Sjmc.Qq -x , 3046f6300c6Sjmc.Qq -y , 3056f6300c6Sjmc.Qq /tmp/script , 3066f6300c6Sjmc.Qq one , 3076f6300c6Sjmc.Qq two , 3086f6300c6Sjmc.Qq three 3096f6300c6Sjmc.Ed 3106f6300c6Sjmc.Pp 3116f6300c6SjmcThe behavior of the system in the face of multiple arguments is thus 3126f6300c6Sjmcnot currently standardized, should not be relied on, and may be 3136f6300c6Sjmcchanged in future releases. 3146f6300c6SjmcIn general, pass at most one argument, and do not rely on multiple 3156f6300c6Sjmcarguments being concatenated. 3166f6300c6Sjmc.Sh SEE ALSO 3176f6300c6Sjmc.Xr awk 1 , 3186f6300c6Sjmc.Xr csh 1 , 3196f6300c6Sjmc.Xr ksh 1 , 3206f6300c6Sjmc.Xr sh 1 , 3216f6300c6Sjmc.Xr chmod 2 , 3226f6300c6Sjmc.Xr execve 2 , 3236f6300c6Sjmc.Xr intro 2 , 3246f6300c6Sjmc.Xr execlp 3 , 3256f6300c6Sjmc.Xr execvp 3 3266f6300c6Sjmc.Sh STANDARDS 3276f6300c6SjmcThe behavior of interpreter scripts is obliquely referred to, but 3286f6300c6Sjmcnever actually described in, 329af69310cSjmc.St -p1003.1-2004 . 3306f6300c6Sjmc.Pp 3316f6300c6SjmcThe behavior is partially (but not completely) described in the 3326f6300c6Sjmc.St -svid4 . 3336f6300c6Sjmc.Pp 3346f6300c6SjmcAlthough it has never been formally standardized, the behavior 3356f6300c6Sjmcdescribed is largely portable across 3366f6300c6Sjmc.Tn POSIX 3376f6300c6Sjmcstyle systems, with two significant exceptions: the maximum length of the 3386f6300c6Sjmc.Sq #! 3396f6300c6Sjmcline, and the behavior if multiple arguments are passed. 340*a4e61cf2SjsgBe aware that the behavior in the 3416f6300c6Sjmcface of multiple arguments is not consistent across systems. 3426f6300c6Sjmc.Sh HISTORY 3436f6300c6SjmcThe behavior of the kernel when encountering scripts that start in 3446f6300c6Sjmc.Sq #! 3456f6300c6Sjmcwas not present in 3466f6300c6Sjmc.At v7 . 3476f6300c6SjmcA Usenet posting to net.unix by Guy Harris on October 16, 1984 claims 3486f6300c6Sjmcthat the idea for the 3496f6300c6Sjmc.Sq #! 3506f6300c6Sjmcbehavior was first proposed by Dennis Ritchie but that the first 3516f6300c6Sjmcimplementation was on 3526f6300c6Sjmc.Bx . 3536f6300c6Sjmc.Pp 3546f6300c6SjmcHistorical manuals (specifically the exec man page) indicate that the 3556f6300c6Sjmcbehavior was present in 3566f6300c6Sjmc.Bx 4 3576f6300c6Sjmcat least as early as April, 1981. 3586f6300c6SjmcInformation on precisely when it was first implemented, and in which 3596f6300c6Sjmcversion of 3606f6300c6Sjmc.Ux , 3616f6300c6Sjmcis solicited. 3626f6300c6Sjmc.Sh CAVEATS 3636f6300c6SjmcNumerous security problems are associated with setuid interpreter 3646f6300c6Sjmcscripts. 3656f6300c6Sjmc.Pp 3666f6300c6SjmcIn addition to the fact that many interpreters (and scripts) are 3676f6300c6Sjmcsimply not designed to be robust in a setuid context, a race condition 3686f6300c6Sjmcexists between the moment that the kernel examines the interpreter 3696f6300c6Sjmcscript file and the moment that the newly invoked interpreter opens 3706f6300c6Sjmcthe file itself. 3716f6300c6Sjmc.Pp 3726f6300c6SjmcSubtle techniques can be used to subvert even seemingly well written scripts. 3736f6300c6SjmcScripts executed by Bourne type shells can be subverted in numerous 3746f6300c6Sjmcways, such as by setting the 3756f6300c6Sjmc.Ev IFS 3766f6300c6Sjmcvariable before executing the script. 3776f6300c6SjmcOther interpreters possess their own vulnerabilities. 3786f6300c6SjmcSetting the Set-user-ID on execution (SUID) bit 3796f6300c6Sjmcis therefore very dangerous, and should not be done lightly, if at all. 380