chris@umcp-cs.UUCP (Chris Torek) (08/14/86)
In article <1361@ulysses.UUCP> dgk@ulysses.UUCP (David Korn) writes: >The #! /bin/sh on the first line is interpretted by the kernel in BSD 4.2. >This has two unfortunate consequences. First of all it execs a new copy >of the shell to run the shell procedure even if you are already running >the Bourne shell. This is a lot slower than just letting the exec >fail and letting the shell read the procedure directly. This is the second time I have seen this assertion. I did not believe it earlier, so this time I set out to test it. The base form of my test scripts are appended below. I ran the commands time sh doit.sh and time csh doit.csh and edited doit.sh and doit.csh to run `x1.sh' or `x2.sh' as appropriate. Results (on a Vax 8600 running 4.3BSD-beta-plus): doit.sh doit.csh -------------------------- #! | 1.4u 4.7s 1.6u 5.6s direct | 1.1u 4.0s 1.4u 5.9s In both cases, using `#!' is somewhat less efficient: .01 seconds per script invocation when using `sh', and .001 seconds per invocation when using `csh'. (The csh results look a bit anomalous, but I am ready to believe almost anything regarding efficiency, or lack thereof, within the C shell.) I imagine that most shell scripts are rather more complex than `x1.sh' and `x2.sh' (both of which do nothing), and that the hundredth-second difference gets lost quite quickly in practise. In any case the extra time is, in my opinion, more than offset by the ability to run the scripts via the various `exec' calls. In addition, `#!' can run things other than sh and csh: #! /bin/awk NR > 2 { print } # this file prints the rest of itself to stdout try it and see. >Secondly, this allows for a very insecure implementation of setuid shell >procedures. Setuid shell scripts are quite dangerous. I believe it is possible to write a `secure' setuid script, but there are enough bugs with setuid and shells that I recommend against such scripts purely on priciple. However, that #! allows this is not necessarily a point against it. ---test scripts: : Run this shell script with "sh" not "csh" PATH=/bin:/usr/bin:/usr/ucb:/etc:$PATH export PATH echo Extracting doit.csh sed 's/^X//' <<'//go.sysin dd *' >doit.csh foreach i (0 1 2 3 4 5 6 7 8 9) foreach j (0 1 2 3 4 5 6 7 8 9) x1.sh end end //go.sysin dd * chmod 644 doit.csh echo -n ' '; ls -ld doit.csh echo Extracting doit.sh sed 's/^X//' <<'//go.sysin dd *' >doit.sh for i in 0 1 2 3 4 5 6 7 8 9; do for j in 0 1 2 3 4 5 6 7 8 9; do x1.sh done done //go.sysin dd * chmod 644 doit.sh echo -n ' '; ls -ld doit.sh echo Extracting x1.sh sed 's/^X//' <<'//go.sysin dd *' >x1.sh : sh file : does nothing #! /bin/sh //go.sysin dd * chmod 755 x1.sh echo -n ' '; ls -ld x1.sh echo Extracting x2.sh sed 's/^X//' <<'//go.sysin dd *' >x2.sh #! /bin/sh : sh file : does nothing //go.sysin dd * chmod 755 x2.sh echo -n ' '; ls -ld x2.sh -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516) UUCP: seismo!umcp-cs!chris CSNet: chris@umcp-cs ARPA: chris@mimsy.umd.edu