Re: Perl/sh/bash scripts and emacs
- From: krahnj@xxxxxxxxx (John W. Krahn)
- Date: Sat, 29 Oct 2005 03:51:20 -0700
Marilyn Sander wrote:
> Not sure how much of a beginner question this is. I've been searching
> mail archives and can't find anything about it. I've embarrassed myself
> by giving advice based on my reading of the Camel book, but the advice
> doesn't work.
>
> In the "Camel" book "Programming Perl", Chapter 19 is a chapter on using
> the Perl command line. One example there is to use
>
> #!/bin/sh -- # -*- perl -*-
> eval 'exec perl -S $0 ${1+"$@"}'
> if 0;
>
> The explanation says that the presence of -*- perl -*- on the
> shebang line causes perl not to pay attention to that line,
> but does cause emacs to treat the script as a perl file.
That is not exactly what the book says.
<QUOTE>
Parsing of #! switches starts from where "perl" is first mentioned in the
line. The sequences "-*" and "- " are specifically ignored for the benefit of
emacs users, so that, if you're so inclined, you can say:
#!/bin/sh -- # -*- perl -*- -p
eval 'exec perl -S $0 ${1+"$@"}'
if 0;
and Perl will see only the -p switch. The fancy "-*- perl -*-" gizmo tells
emacs to start up in Perl mode; you don't need it you don't use emacs. The -S
mess is explained later under the description of that switch.
</QUOTE>
What that means is that the system sees that the first two characters are '#!'
and feeds the script to the program following those two characters, in this
case the Bourne shell. The shell reads the first line and deals with any
switches following the program name (the first switch "--" means turn off
further switch processing) then runs the code on the second and subsequent
lines. The second line runs perl with the name of the current script ($0) as
the perl program and the rest of the command line (${1+"$@"}) as arguments to
that program. When perl reads the script it sees 'perl' on the first line and
processes every thing after that (-*- -p) as switches for perl.
> But we'd like to be able to use sh or bash to locate one of
> several okay versions of Perl. The path to Perl differs depending
> on what installation it is run in. We cannot just use the user's path
> or environment, because these scripts are used in strictly-managed
> configuration management/QA/build/release processes. Each one has
> to use a particular version and installation of Perl and no other.
>
> We have got something that works quite well, except that an emacs
> user complains that emac doesn't recognize the script header as Perl,
> and instead provides shell highlighting instead of Perl highlighting.
> Hence my question is, how do we accommodate the emacs user?
>
> The following code works well (pathname specifics changed for
> confidentiality):
>
> #!/bin/bash -- #
>
> perl1="/path1/perl"
> perl2="/path2/perl"
>
> if [ -x $perl1 ]
> then
> perl=$perl1
> elif [ -x $perl2 ]
> then
> perl=$perl2
> else
> echo Unable to find perl, contact local suport person
> exit 2
> fi
>
> exec $perl -x $0 "$@"
>
> #!/dummydir/perl -w
>
> $myname=`basename $0` ; chomp $myname;
perldoc File::Basename
> $mydir=`dirname $0` ; chomp $mydir;
perldoc FindBin
> $mydir=`(cd $mydir; pwd)`; chomp $mydir;
What???? Why????
perldoc -f chdir
perldoc Cwd
> print "I am $myname in directory $mydir\n";
> print "My options are:\n";
> for $a ( @ARGV ) {
> print "$a ";
> }
> $onlyonce=1;
> print "\n";
Why not just use a here doc and one print:
print <<"TEXT";
I am $myname in directory $mydir
My options are:
@ARGV
TEXT
> exit 0;
>
> ---------------------------------------
> Perl gets control, skips the bash code, finds the second shebang line,
> honors the -w flag, and runs the script.
> But if we change the initial shebang line to
>
> #!/bin/bash -- # -*- perl -*-
>
> then Perl does not skip the bash code, and gives lots of error messages.
>
> So it looks like the advice in the Camel book is no good. Either that
> or I've forgotten how to read a technical manual. Can someone help?
perldoc perlrun
[snip]
-x
-x directory
tells Perl that the program is embedded in a larger chunk of
unrelated ASCII text, such as in a mail message. Leading garbage
^^^^^^^^^^^^^^^
will be discarded until the first line that starts with #! and
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
contains the string "perl". Any meaningful switches on that line
^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^
will be applied. If a directory name is specified, Perl will switch
to that directory before running the program. The -x switch controls
only the disposal of leading garbage. The program must be terminated
with "__END__" if there is trailing garbage to be ignored (the
program can process any or all of the trailing garbage via the DATA
filehandle if desired).
The best documentation for Perl is the documentation that is provided with Perl.
perldoc perl
John
--
use Perl;
program
fulfillment
.
- Follow-Ups:
- Re: Perl/sh/bash scripts and emacs
- From: Marilyn Sander
- Re: Perl/sh/bash scripts and emacs
- Prev by Date: Re: <> tag in perl
- Next by Date: Re: input validation and persistency module for (mod_perl) web apps?
- Previous by thread: Re: grep help request -- data fields max size
- Next by thread: Re: Perl/sh/bash scripts and emacs
- Index(es):
Relevant Pages
|