jmm@ski.UUCP (Joel M. Miller) (04/27/85)
There are at least 2 ways of indicating to csh that a Shell script should be interpreted by sh: begin the file with: #! /bin/sh or with any character other than "#", such as: : These two ways are not equivalent, but I can't characterize the difference. The first sometimes causes commands in the script to fail with the error message "restricted", and produces a funny command line in ps -f: file file These are cured by ":". But what's really happening here? -- Joel M Miller; Smith-Kettlewell Institute of Visual Sciences 2232 Webster St; San Francisco CA 94115; 415/561-1703 dual!ptsfa!ski!jmm OR {ucbvax,dual,sun}!twg!ski!jmm
tmb@talcott.UUCP (Thomas M. Breuel) (04/29/85)
[the following is valid for Berkley kernels 2.8 and up and 4.1 and up] > There are at least 2 ways of indicating to csh that a Shell script > should be interpreted by sh: begin the file with: > #! /bin/sh > or with any character other than "#", such as: > : Every executable begins with a magic number which identifies the type of the executable. '#!' is a magic number which indicates that a command interpreter should be invoked by the kernel (!) to execute this file. Sample uses are to invoke a shell on a shell file, or to invoke a Pascal p-code interpreter on a p-code file. Files beginning with '#!' can be exec'ed, they can even be suid (although that's not a good idea). The name of the file being executed is passed as a parameter to the command interpreter. On 4.1 and up, one (1) more argument can be handed to the command interpreter (e.g. a flag). Files beginning with '#!' behave practically like binary files. The shell just exec's them and never sees them. If, however, the exec fails (because the file to be executed has an invalid magic number), the shell (sh or csh) looks at the first character of the file. If it is a '#', it invokes a 'csh' to interpret it, otherwises an 'sh'. (Note that the 'csh' is the special case, not the 'sh'). Thomas.
guy@sun.uucp (Guy Harris) (04/30/85)
> There are at least 2 ways of indicating to csh that a Shell script > should be interpreted by sh: begin the file with: > > #! /bin/sh > > or with any character other than "#", such as: > > : > > These two ways are not equivalent, but I can't characterize the > difference. The first, on 4.xBSD systems, possibly 2.[89]BSD systems, other systems which have been modified to support the kernel detecting executable interpreter scripts (I think Masscomp's system does so), and systems where the C shell has been modified to recognize "#!" comments, causes the kernel (in most cases) to execute the program whose pathname is given after the "#!", with the zeroth argument (i.e., command name) and first argument which are both the pathname of the script. The second, on 4.xBSD systems, possibly 2.[89]BSD systems, and on most other systems running the C shell, causes the C shell to run "/bin/sh" on the script. WARNING: beginning with ':' is NOT a necessary condition for being a Bourne shell script. The 4.xBSD Bourne shell, and the System III and V Bourne shells (as well as, I presume, the Korn shell) permit "#" comments which are real comments, not no-op commands. > The first sometimes causes commands in the script to fail with the > error message "restricted" This is because some versions of the Bourne shell look at their zeroeth argument (which, in most cases, is their own path name) to see if it contains the letter 'r' anywhere, or in the better shells only in the last component of the path name (so being in "/usr/bin" won't confuse them). If it does, it considers itself a "restricted" shell and forbids all sorts of things, like commands with '/' in their name, changing PATH, redirecting output, etc.. > and produces a funny command line in ps -f: > > file file This is because, as mentioned, both the zeroth and first arguments to "/bin/sh" are the name of the file. Guy Harris
roger@rtech.ARPA (Roger Rohrbach) (05/11/85)
> But what's really happening here?
The "#!/bin/sh" trick only works on 4.2BSD and derivatives;
it's actually a magic number for the execve() system call, and is a
generalized way of invoking the correct interpreter for a file. In
other words, a Franz Lisp program in a file named "prog" which has
been made executable and which starts with the line:
#!/usr/ucb/lisp
can be run by typing "prog".
If you are running csh on a non-BSD Unix system, the way to
ensure that a file is interpreted by /bin/sh is to make certain that
its first character is not a '#'. Even a file beginning "#!/bin/sh"
will not be interpreted by sh on such a system, since this is simply
an ordinary comment. Alternatively, if you set the 'shell' variable
to "/bin/sh", all shell scripts will be interpreted by sh.
Roger Rohrbach
{ucbvax,decvax}!mtxinu!rtech!roger