in scripting?
Starting with # has always seemed counter-intuitive.
Yes, somebody knows.
> Starting with # has always seemed counter-intuitive.
This, I don't get. # is a comment line. This idiom means that, when
the shell is invoked on the file, the initial line doesn't cause a syntax
error.
-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.
> Does anybody know the origin of using #!/path/shell
> in scripting?
http://en.wikipedia.org/wiki/Shebang_(Unix) discusses what is known of
the history.
> Does anybody know the origin of using #!/path/shell
>
> in scripting?
It depends on what you mean by origin.
Do you want to know the motivations? They can be inferred, since they're
much the same today.
Or do you want to know the specific events that led to what we now have?
Much of that is probably lost in unrecorded history.
> Starting with # has always seemed counter-intuitive.
How so? It's a good way to have something the kernel can look for,
without the shell getting confused by it. What is the intuition that you
find countered by this?
--
\ “We now have access to so much information that we can find |
`\ support for any prejudice or opinion.” —David Suzuki, 2008-06-27 |
_o__) |
Ben Finney
>> Does anybody know the origin of using #!/path/shell
>>
>> in scripting?
>>
>> Starting with # has always seemed counter-intuitive.
>
> http://www.in-ulm.de/~mascheck/various/shebang/
...says:
| So this mechanism was invented between Version 7 and Version 8. It was
| then available in 4.0BSD but not activated per default until 4.2BSD.
In fact it's there in 2.8BSD.
kakajou:sys richard$ pwd
/Volumes/www/software/csrg/CD1/2.8/usr/kernel/sys/sys
kakajou:sys richard$ sed '70,100p;d' < sys1.c
# ifdef MENLO_SCRIPT
/*moved this from getxfile()*/
u.u_base = (caddr_t)&u.u_exdata;
u.u_count = sizeof u.u_exdata;
u.u_offset = 0;
u.u_segflg = 1;
readi(ip);
u.u_segflg = 0;
if( u.u_error )
goto bad;
/*check if script. one lvl only*/
if( indir==0
&& u.u_exdata.ux_mag==SCRMAG
&& u.u_count<sizeof u.u_exdata-sizeof u.u_exdata.ux_mag )
{
indir++;
cp = (char*)&u.u_exdata+sizeof u.u_exdata.ux_mag;
while( *cp==' ' && cp<(char*)&u.u_exdata+sizeof u.u_exdata-1 )
cp++;
u.u_dirp = cp;
while( cp<(char*)&u.u_exdata+sizeof u.u_exdata-1
&& *cp!='\n' )
cp++;
*cp = 000;
iput(ip);
if( (ip = namei(schar,0))==NULL )
return;
goto again;
}
/*other magic numbers are described in getxfile()*/
# endif
> | So this mechanism was invented between Version 7 and Version 8. It was
> | then available in 4.0BSD but not activated per default until 4.2BSD.
>
> In fact it's there in 2.8BSD.
4.0BSD was released in '80, 2.8 BSD was released in '81.
The number is smaller, but it's just an independent development line.
See also http://www.levenez.com/unix/
4.xBSD is emphasized, because it's about how the feature
became commonly available at all. But 2.x BSD should be
also mentioned to avoid this misunderstanding (just done).
Maybe not. Ever hear of "magic number"?
http://en.wikipedia.org/wiki/Magic_number_(programming)
Think of it as a human-readable magic number.
Jonesy
--
Marvin L Jones | jonz | W3DHJ | linux
38.24N 104.55W | @ config.com | Jonesy | OS/2
* Killfiling google & XXXXbanter.com: jonz.net/ng.htm
> Cydrome Leader <pres...@MUNGEpanix.com> writes:
>
> > Does anybody know the origin of using #!/path/shell
> >
> > in scripting?
>
> It depends on what you mean by origin.
>
> Do you want to know the motivations? They can be inferred, since they're
> much the same today.
>
> Or do you want to know the specific events that led to what we now have?
> Much of that is probably lost in unrecorded history.
I think he's just asking why the specific character sequence "#!".
--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
> On Wed, 12 Jan 2011 20:11:25 +0000 (UTC), Cydrome Leader wrote:
>> Does anybody know the origin of using #!/path/shell
>> in scripting?
>> Starting with # has always seemed counter-intuitive.
> Think of it as a human-readable magic number.
It's also overrideable, as it's a comment that will be ignored
by the actual script interpreter. Consider trying to run a script
with "#!/bin/bash", on a system where bash is not installed there.
I can run "/usr/local/bin/bash /path/scriptname", and it will run,
with that comment ignored by bash. If it's compatible, I could run
it under ksh in a similar way.
Regards, Dave Hodgins
--
Change nomail.afraid.org to ody.ca to reply by email.
(nomail.afraid.org has been set up specifically for
use in usenet. Feel free to use it yourself.)
> I think he's just asking why the specific character sequence "#!".
Yes, and I'm asking what he means by “why” :-) i.e.: “how did it come
about in its history?” or “what justification is there now?”
We can guess, but I'd prefer to know what the OP means.
--
\ “I busted a mirror and got seven years bad luck, but my lawyer |
`\ thinks he can get me five.” —Steven Wright |
_o__) |
Ben Finney
a # anywhere else is a comment and ignored. I can't think of any other
place commands are defined or values are set after any sort of comment
notation.
Even inside a shell, you can't just type something like
#!/bin/ksh
ls -la
exit
That first like is ignored.
> Ben Finney <ben+...@benfinney.id.au> wrote:
> > How so? It's a good way to have something the kernel can look for,
> > without the shell getting confused by it. What is the intuition that
> > you find countered by this?
>
> a # anywhere else is a comment and ignored.
Yes, that's precisely the point. The shebang line is deliberately formed
as a shell comment and hence is ignored by the shell.
Have you read the references people have posted elsewhere in this
thread? The shebang line is constructed to give the *kernel*
information, that the *shell* will ignore when it reads the file.
--
\ “[The MPAA] have the patience to keep stomping. They're playing |
`\ whack-a-mole with an infinite supply of tokens.” —kennon, |
_o__) http://kuro5hin.org/ |
Ben Finney
You should really read all the postings carefully; all relevant
information has already been provided.
> a # anywhere else is a comment and ignored. I can't think of any other
> place commands are defined or values are set after any sort of comment
> notation.
Of course there are; see for example modelines in vi and descendants.
Or pragmas in various programming languages.
>
> Even inside a shell, you can't just type something like
Of course you can...
>
> #!/bin/ksh
> ls -la
> exit
>
> That first like is ignored.
...it's just not executed by the shell - and why should it?!
For the shell the first line is a comment.
Ask yourself; why should a shell be interested in a
#!/bin/any_interpreter
line? - Only the interpreter is interested in the script below
and only the kernel is interested in invoking the specified
interpreter to run the program text.
I am sure the upthread provided links explain it thoroughly.
Janis
>> | So this mechanism was invented between Version 7 and Version 8. It was
>> | then available in 4.0BSD but not activated per default until 4.2BSD.
>>
>> In fact it's there in 2.8BSD.
>
> 4.0BSD was released in '80, 2.8 BSD was released in '81.
> The number is smaller, but it's just an independent development line.
> See also http://www.levenez.com/unix/
Ah! Thankyou for the clarification!
> 4.xBSD is emphasized, because it's about how the feature
> became commonly available at all. But 2.x BSD should be
> also mentioned to avoid this misunderstanding (just done).
That's why it's a good place to put something that's not *for* the shell.
> I can't think of any other
> place commands are defined or values are set after any sort of comment
> notation.
http://www.gnu.org/software/emacs/manual/html_node/emacs/Specifying-File-Variables.html
Any time you think "I can't think of a case where...", check emacs.
You seem to be confused about levels.
> Even inside a shell, you can't just type something like
> #!/bin/ksh
> ls -la
> exit
> That first like is ignored.
Right, because it's a comment to the shell.
Okay, the basic questions:
1. How does the kernel identify executables? It identifies them by
looking at their first few bytes for a header to tell it what type they
are.
2. How can we make the first few bytes of a file look magical to the kernel,
without making them break the script for the scripting language? We can
make them a comment in the scripting language.
Solution:
If a file begins "#!" and is executable, it is a script file and the #!
is introducng the name of the interpreter.
The thing you're getting confused by, as shown by your other example, is
that you're thinking only about the shell processing the file. You're
forgetting that executables are launched by something OTHER than the shell.
In an interactive shell it can depend on the shell and its settings:
bash:
shopt -u interactive_comments
#!/bin/zsh
-bash: #!/bin/zsh: No such file or directory
this is interesting.
> Cydrome Leader <pres...@MUNGEpanix.com> writes:
>
> > Ben Finney <ben+...@benfinney.id.au> wrote:
> > > How so? It's a good way to have something the kernel can look for,
> > > without the shell getting confused by it. What is the intuition that
> > > you find countered by this?
> >
> > a # anywhere else is a comment and ignored.
>
> Yes, that's precisely the point. The shebang line is deliberately formed
> as a shell comment and hence is ignored by the shell.
>
> Have you read the references people have posted elsewhere in this
> thread? The shebang line is constructed to give the *kernel*
> information, that the *shell* will ignore when it reads the file.
Actually, when this was first created it was done by the shell. Only
later did the function move into the kernel.
So, you admit you "don't know what you don't know." <grin>
Have you ever looked at the PostScript DSC ??
Did you know that the 'vi' editor will pick up variable settings from
the first line of a text file -- even if they're inside a 'comment'
in whatever programming language the file content is written in.
The Unix "first-line-of-a-script-command-interpreter-specification' is
*intentionally* done as a special case of a standard 'comment'.
This way you can feed the file, as input, to a command interpretor that
does _not_ know anything about the convention.
You can use it 'as is' e.g. "interpreter_executable <scriptfile" *anywhere*
as long as *you* choose the appropriate interpreter (the one 'documented' on
the first-line 'comment', that is <grin>)
*OR* where the file-execution function _is_ aware of the protocol, you can
simply 'execute' the file, and the system execution function does the
appropriate magic.
Some history -- the functionality was _ORIGINALLY_ implemented as part of
the 'csh' command-line interpreter. 'csh' would interpret '#!' lines and
invoke the named command interpreter, passing the script as input, but the
Bourne shell did _not_ know about the convention. Thus, you could invoke
'sh' _or_ 'csh' scripts from the csh prompt, and the 'right thing' would
happen, but you could -not- invoke a csh script directly from the 'sh'
prompt -- you had to use something like 'csh <csh_scriptfile' every time.
For -that- to work, it =was= necessary that the command-interpreter
specification *be* a 'comment' in *that* context.
Eventually, the functionality was removed from csh, and moved into the
kernel 'exec' function -- thus making it available from *every* program
that executed arbitrary system commands.
I seem to remember reading that it started smaller: Scripts were normally
run as sh scripts, but those starting with '#' would run as csh scripts.
Then came the #! to run them as sh scripts again or something else.
--
Hallvard
> Some history -- the functionality was _ORIGINALLY_ implemented as part of
> the 'csh' command-line interpreter. 'csh' would interpret '#!' lines and
> invoke the named command interpreter, passing the script as input, but the
> Bourne shell did _not_ know about the convention. Thus, you could invoke
> 'sh' _or_ 'csh' scripts from the csh prompt, and the 'right thing' would
> happen, but you could -not- invoke a csh script directly from the 'sh'
> prompt -- you had to use something like 'csh <csh_scriptfile' every time.
> For -that- to work, it =was= necessary that the command-interpreter
> specification *be* a 'comment' in *that* context.
>
> Eventually, the functionality was removed from csh, and moved into the
> kernel 'exec' function -- thus making it available from *every* program
> that executed arbitrary system commands.
csh recognized if a script began with "#", that is, the signal,
that it should be run with csh. Otherwise it execed "sh" to run
the script. It didn't know about #! or calling other interpreters.
The Unix FAQ also tells that the Bourne shell did not know about
this convention. But that's incorrect (like the assumption that
Berkeley invented #!), the Bourne shell was modified likewise on
BSDs (which makes sort of a symmetry). See e.g. the sh code on 3BSD:
http://www.in-ulm.de/~mascheck/bourne/csh-hack.html
BTW,
the # csh-hack was invented before the Bourne shell knew # as comment
character at all. At this time (variants of the V7 shell), only the
null command ":" was available for this purpose.
When #! was implemented per default (System III for Bell Labs and
4.2BSD for Berkeley), sh certainly also recognized # as comment.
Perhaps "originally" or "moved" could be misleading, because
# (Berkeley) and #! (Bell Labs) might have been developed
independently.
Erm, no. You can execute
interpreter_executable <scriptfile
with any interpreter[*] independently from the #! line that is defined
in the script. Write a program that starts with, say
#!/bin/sh
and name it foobar and call that program with ksh, bash, zsh, whatever
ksh foobar
The #! declaration is only relevant if directly exec'ed as an executable.
Janis
[*] Any interpreter that knows the file syntax of course, otherwise you'd
get errors.
> When #! was implemented per default (System III for Bell Labs and
confusion, no: # as comment came, but #! not yet.