Hello, John.

thank you very much for the trouble you have taken with your answer.
I acknowlege that our script
is not the same as the example in "Programming Perl".  We really need
to have the leading bash code there to choose what directory to execute
Perl from.  My question is still, is there a way to have that leading
bash code and still have emacs see the file as a Perl script.

I agree the documentation you've quoted does not say that it's
possible.  I just thought that the example in "Programming Perl"
suggested there ought to be a way to do it.  I've been guessing
and trying different combinations, since there is no explicit
rule or example.    If I try
        #!/bin/bash -- # -*- perl -*- -x

Perl gives the error message
        Can't emulate -x on #! line.

The documentation you've quoted does not say explicitly that it's
possible to construct this sort of script and have emacs recognize it.
Perhaps it isn't.  Do you know whether it is possible, and if so,
how to do it?

Please note, I am not an emacs user.  The emacs user in question
doesn't know how to do this, either.

thanks again,
--Marilyn

PS You've made some useful suggestions in the code below and also
   asked why I've done things certain ways.  I've inserted answers.

On Oct 29, 2005, at 3:51 AM, John W. Krahn wrote:

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
Yes, I know that's available.  I didn't use it here.


$mydir=`dirname $0` ;      chomp $mydir;

perldoc FindBin
I'll look this one up.


$mydir=`(cd $mydir; pwd)`; chomp $mydir;

What????   Why????

perldoc -f chdir
perldoc Cwd

Thank you.  the $RealBin exported from FindBin looks like
it would do the trick in this case, since I am computing the
path where the script is located.  However, the $mydir
computation can be used to compute the absolute path to
any directory at run time.  We use it often to record absolute
paths in log files created during tests and builds, when we
suspect the user could have changed $PATH or inserted a symlink
to a control file or program.

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

Because I'm a beginner at the passing of arguments thru one program and
into another with exec, and this is debugging code. I wanted to make sure
I got each one as a separate item, and not all of them smooshed together
into a single argument. Actually, I should have ended each argument with
a distinguished separator.  The loop doesn't do what I intended.

thanks,
Marillyn

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

--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>




--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to