[oak perl] Re: shell script or perl? (Belden Lyman)
Joshua Wait
joshnjillwait at yahoo.com
Sat Jun 26 11:57:35 CDT 2004
That's very clever. Thanks for the clear and practical
presentation of the solution.
--JOSHUA
--- oakland-request at mail.pm.org wrote:
> Send Oakland mailing list submissions to
> oakland at mail.pm.org
>
> To subscribe or unsubscribe via the World Wide Web,
> visit
> http://mail.pm.org/mailman/listinfo/oakland
> or, via email, send a message with subject or body
> 'help' to
> oakland-request at mail.pm.org
>
> You can reach the person managing the list at
> oakland-owner at mail.pm.org
>
> When replying, please edit your Subject line so it
> is more specific
> than "Re: Contents of Oakland digest..."
>
>
> Today's Topics:
>
> 1. shell script or perl? (Belden Lyman)
>
>
>
----------------------------------------------------------------------
>
> Message: 1
> Date: 24 Jun 2004 15:21:29 -0700
> From: Belden Lyman <blyman at iii.com>
> Subject: [oak perl] shell script or perl?
> To: Oakland Perl Mongers <oakland at mail.pm.org>
> Message-ID: <1088115688.31959.10.camel at ls104>
> Content-Type: text/plain
>
>
> This may be interesting to someone else.
>
> Today at work I developed a perl script that
> manipulates a text file in
> some useful way. Then I realized that not all of our
> servers have perl
> installed on them, so I re-developed the data
> manipulation in sed.
>
> But this was a loss, because in perl the program did
> some extra
> reporting which I couldn't make sed do- a verbose
> mode and the like. I
> know extra reporting will be useful, so decided to
> compromise: combine
> the two programs together into a single executable
> script.
>
> If perl is found, then the perl portion of the
> script gets run. If
> not, then the shell script portion picks out what
> arguments it knows
> about, warns that it is ignoring other arguments,
> and runs the sed
> command that does the data transformation.
>
> I've hoisted out the guts of the script because the
> text manipulation
> isn't all that interesting. However, the bit that
> selects between using
> shell or perl is kind of neat:
>
> 1 #!/bin/ksh
> 2 `perl -e 1 > /dev/null 2>&1` && eval 'exec
> perl -x $0 $*'
> 3
> 4 echo "hello shell script"
> 5 for opt in $*
> 6 do
> 7 echo "shell: $opt"
> 8 done
> 9 exit 0
> 10
> 11 #!perl -l
> 12 print "hello perl script";
> 13 print "perl: $_" for @ARGV;
> 14 exit 1;
> 15 __END__
>
> All the shell scripting falls between lines 3 and
> 10. The perl
> code takes up lines 11-15.
>
> These are the important lines in the script:
>
> 2 `perl -e 1 > /dev/null 2>&1` && eval 'exec
> perl -x $0 $*'
>
> 11 #!perl -l
>
> 15 __END__
>
> Line 2 is executed by the shell, /bin/ksh. It starts
> with
>
> `perl -e 1 > /dev/null 2>&1`
>
> which tries to invoke the perl interpreter to
> execute the command
> statement '1;'. If perl can be found on the system,
> then the
> interpreter starts up, does nothing, and exits with
> a true value.
>
> If perl cannot be found, then the shell started by
> my `backticks` spits
> out an error message, which gets redirected to
> /dev/null. The `backtick`
> shell exits with a false value.
>
> The '&&' on line 2 causes the right side, "eval
> 'exec perl -x $0 $*'",
> to be executed only if the left side returns a true
> value. So, where
> a perl interpreter is available, the kernel replaces
> the running shell
> script with the following process:
>
> perl -x script_name_here script_args_here
>
> The -x switch to perl is pretty neat: 'perldoc
> perlrun' says that it
>
> tells Perl that the program is embedded in a
> larger chunk of
> unrelated ASCII text, such as in a mail
> message.
>
> (Well, I'm embedding it in a shell script, but same
> difference.)
>
> Leading garbage will be discarded until the
> first line that
> starts with #! and contains the string "perl".
>
> (Hence line 11 being a very important line!)
>
> Any meaningful switches on that line will be
> applied.
>
> (I tossed on a -l switch so the prints have a
> newline automatically
> appended.)
>
> If a directory name is specified, Perl will
> switch to that
> directory before running the program.
>
> (I didn't bother with this, though I suppose
> changing to /tmp might
> not be a bad idea: both the shell script and the
> perl script read
> input from a pipe, so a chdir wouldn't hurt
> anything.)
>
> The -x switch controls only the disposal of
> leading garbage.
> The program must be terminated with "__END__"
>
> (And that's why line 15 is another important line.)
>
> Tada, a script written in shell and perl!
>
> Belden
>
> ps-
>
> You can simulate running the script on a server
> where perl isn't found
> by changing line 2 from this:
>
> 2 `perl -e 1 > /dev/null 2>&1` && eval 'exec
> perl -x $0 $*'
>
> to this:
>
> 2 `$1 -e 1 > /dev/null 2>&1` && eval 'exec
> perl -x $0 $*'
>
> and then you can run:
>
> $ ksh-or-perl fnurffanurf hello world
> hello shell script
> shell: fnurffanurf
> shell: hello
> shell: world
>
> and on a server where perl is found:
>
> $ ksh-or-perl perl hello world
> perl: perl
> perl: hello
> perl: world
>
> pps- if I needed to put any shell script after the
> perl code, I'd
> change
>
=== message truncated ===
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - Send 10MB messages!
http://promotions.yahoo.com/new_mail
More information about the Oakland
mailing list