[comp.unix.questions] Another sed question.

gahooten@orion.arc.nasa.gov (Gregory A. Hooten) (12/02/89)

I ran across a shell script that had this as the first line of code.

-------------------------------------------------------------
#!/bin/sed d1

		Some bunch of text for several lines.



-------------------------------------------------------------

What it did was to delete the line starting with the # sign and display all
of the text that was in the file.  My questions are, why do it this way in-
stead of using echo?  Why is the # line considered line 1, when it was used
to start the command in the first space, it seems to me that the line would 
have already been sent to the terminal to start the sed, and so would not
be deleted?  Could someone explain the process of this part of the sed command
and script files?

Thanks


Greg Hooten
GAHOOTEN@ames.arc.nasa.gov

maart@cs.vu.nl (Maarten Litmaath) (12/02/89)

In article <37091@ames.arc.nasa.gov> gahooten@orion.arc.nasa.gov (Gregory A. Hooten) writes:
\I ran across a shell script that had this as the first line of code.
\
\-------------------------------------------------------------
\#!/bin/sed d1

Probably:

	#!/bin/sed 1d
	<the rest of the script>

When you try to execute this script, the kernel opens it to find out what kind
of executable it is.  The header of a *binary* includes the size of the text,
data and bss segments etc..  This file, however, isn't a binary: it's an
EXECUTABLE shell script.  The kernel discovers the `#!' MAGIC NUMBER and takes
the following word as the real executable to start.  There may be 1 option
specified.  Suppose the file is called `foo', then

	$ foo

is handled as if you had typed

	$ /bin/sed 1d foo

(See execl(3).)
As you noticed this command will delete the first line of `foo' and print the
rest of the script.  So the script is equivalent to:

	#!/bin/sh
	cat << \EOF
	<the rest of the script>
	EOF

The difference: the first form is faster, because there's no invocation of
/bin/sh.  (In the second form there's no need to use sed instead of cat.)
Here's another nice example (put it in your bin directory):
----------8<----------8<----------8<----------8<----------8<----------
#!/bin/sed 1d
          C operator precedence/associativity chart

Arity       Operator                                    Assoc
--------------------------------------------------------------
mixed     ()  []  ->  .                                 l -> r
unary     !   ~   ++  --  -  (type)  *  &  sizeof       r -> l
binary    *   /   %                                     l -> r
binary    +   -                                         l -> r
binary    <<  >>                                        l -> r
binary    <   <=  >   >=                                l -> r
binary    ==  !=                                        l -> r
binary    &                                             l -> r
binary    ^                                             l -> r
binary    |                                             l -> r
binary    &&                                            l -> r
binary    ||                                            l -> r
ternary   ?:                                            r -> l
binary    = += -= *= /= %= >>= <<= &= ^= |=             r -> l
binary    ,                                             l -> r
--------------------------------------------------------------
-- 
`Take John Berryhill: the guy is everywhere!  All because one day he typed "rn"
instead of [rm]'  (Richard Sexton)  | maart@cs.vu.nl, uunet!mcsun!botter!maart

cpcahil@virtech.uucp (Conor P. Cahill) (12/02/89)

In article <37091@ames.arc.nasa.gov>, gahooten@orion.arc.nasa.gov (Gregory A. Hooten) writes:
> #!/bin/sed d1

> What it did was to delete the line starting with the # sign and display all
> of the text that was in the file.  

> My questions are, why do it this way instead of using echo?

Because the programmer wanted to do it that way.  Lots of echos would have
been ugly, but a cat with here documents would have been just as clear and
probably as efficient.

> Why is the # line considered line 1, when it was used
> to start the command in the first space, it seems to me that the line would 
> have already been sent to the terminal to start the sed, and so would not
> be deleted?

Because nothing in the file is "sent to the terminal".  The kernel passes the
entire file to said program.



-- 
+-----------------------------------------------------------------------+
| Conor P. Cahill     uunet!virtech!cpcahil      	703-430-9247	!
| Virtual Technologies Inc.,    P. O. Box 876,   Sterling, VA 22170     |
+-----------------------------------------------------------------------+

merlyn@iwarp.intel.com (Randal Schwartz) (12/04/89)

In article <1989Dec2.134348.22524@virtech.uucp>, cpcahil@virtech (Conor P. Cahill) writes:
| Because the programmer wanted to do it that way.  Lots of echos would have
| been ugly, but a cat with here documents would have been just as clear and
| probably as efficient.

Just a nit... The "'cat' on a 'here' document method" must run over
the data twice... once to create the file in /tmp that serves as the
stdin, and once when cat reads that *as* stdin.  That's a lot of
overhead if the file is large.  Also, you must ensure that you don't
blow away the endmarker when you are editing the file, or the shell
gets a bit confused.

I like the "#!/bin/sed 1d" hack, but only when I'm trying to impress
someone with another tricky use of #!, *or* I have to have a "program"
put out constant text ("blurfl is no longer available... use the
/etc/foobar/blurfl version instead!").

Just another UNIX hacker,
-- 
/== Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ====\
| on contract to Intel's iWarp project, Hillsboro, Oregon, USA, Sol III  |
| merlyn@iwarp.intel.com ...!uunet!iwarp.intel.com!merlyn	         |
\== Cute Quote: "Welcome to Oregon... Home of the California Raisins!" ==/

exspes@gdr.bath.ac.uk (P E Smee) (12/05/89)

In article <4694@pinas.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>Probably:
>
>	#!/bin/sed 1d
>	<the rest of the script>
>
>When you try to execute this script, the kernel opens it to find out what kind
>of executable it is.  The header of a *binary* includes the size of the text,
>data and bss segments etc..  This file, however, isn't a binary: it's an
>EXECUTABLE shell script.  The kernel discovers the `#!' MAGIC NUMBER and takes
>the following word as the real executable to start.  There may be 1 option

Question is, is this #! trick actually documented anywhere?  I certainly can't
find it in any obvious place in my FM's (mostly sysV and 4.2bsd).  If so,
where?  Is it a 4.3bsd feature, or something?  (I see a quick 'mention in
passing' in J.E.Lapin's 'Portable C and Unix System Programming', which
seems to imply that it isn't -- portable, that is.)
-- 
 Paul Smee, Univ. of Bristol Comp. Centre, Bristol BS8 1TW (Tel +44 272 303132)
 Smee@bristol.ac.uk   :-)   (..!uunet!ukc!gdr.bath.ac.uk!exspes if you HAVE to)

maart@cs.vu.nl (Maarten Litmaath) (12/07/89)

In article <1989Dec5.112101.15906@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
\...
\Question is, is this #! trick actually documented anywhere?  I certainly can't
\find it in any obvious place in my FM's (mostly sysV and 4.2bsd).  If so,
\where?  Is it a 4.3bsd feature, or something?  [...]

`man execve', since 4.1BSD.
-- 
`Take John Berryhill: the guy is everywhere!  All because one day he typed "rn"
instead of [rm]'  (Richard Sexton)  | maart@cs.vu.nl, uunet!mcsun!botter!maart

paulb@ttidca.TTI.COM (Paul Blumstein) (12/07/89)

In article <1989Dec5.112101.15906@gdt.bath.ac.uk> exspes@gdr.bath.ac.uk (P E Smee) writes:
+In article <4694@pinas.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
+>Probably:
+>
+>	#!/bin/sed 1d
+>	<the rest of the script>
+>
+>When you try to execute this script, the kernel opens it to find out what kind
+>of executable it is.  The header of a *binary* includes the size of the text,
+>data and bss segments etc..  This file, however, isn't a binary: it's an
+>EXECUTABLE shell script.  The kernel discovers the `#!' MAGIC NUMBER and takes
+>the following word as the real executable to start.  There may be 1 option
+
+Question is, is this #! trick actually documented anywhere?  I certainly can't
+find it in any obvious place in my FM's (mostly sysV and 4.2bsd).  If so,
+where?  Is it a 4.3bsd feature, or something?  (I see a quick 'mention in
+passing' in J.E.Lapin's 'Portable C and Unix System Programming', which
+seems to imply that it isn't -- portable, that is.)

Yes!  The documentation is hidden.  It is magic, isn't it?  While it is
tempting to say that a magician doesn't reveal secrets, I'll tell you if
you promise not to tell anyone else :-).  The man page for execve (section
2) is where to look.
=============================================================================
Paul Blumstein       | "The judicial system is very fast now that they've gotten
Citicorp/TTI         | rid of the lawyers" - Back to the Future 2 (in 2015 AD)
Santa Monica, CA     +-------------------------------------------------------
{philabs,csun,psivax}!ttidca!paulb  or  paulb@ttidca.TTI.COM
DISCLAIMER: Everything & everyone is hereby disclaimed!

guy@auspex.auspex.com (Guy Harris) (12/10/89)

>Because the programmer wanted to do it that way.  Lots of echos would have
>been ugly,

And unnecessary.  In the Bourne shell, you can do

	echo 'Now is the time for all good parties
	to come to the aid of man.'

and you can do it in the C shell if you put backslashes at the end of
all but the last line:

	echo 'Now is the time for all good parties\
	to come to the aid of man.'