1

I came across the following example. I tried to google but could not find much so I'm posting this question here.

  1. What is the benefit of executing the perl script like this?
  2. How can we make the shell script work like a "normal" shell script once we are through executing the perl code?

Here's the code:

#!/bin/ksh
#! -*- perl -*-
eval 'exec $PERLLOCATION/bin/perl -x $0 ${1+"$@"} ;'
if 0;

print "hello world\n";
# how can I make it behave like a "normal" shell script from this point onwards? What needs to be done?
# echo "hello world" ### this results in error
1

3 Answers 3

7

This idiom is described in the perlrun documentation. The -x switch scans the whole file and ignores anything that appears before the first line that begins with #! and also contains the word perl. It means that your system will run the script with the Perl interpreter whether you invoke the script with perl or with a shell command (sh/bash/ksh/etc.) That is,

$ perl this_script

and

$ sh this_script

will both run the script with perl.

To address your second question, this idiom has just about nothing to do with combining shell script and Perl script in the same file. There are a few different ways to approach that problem, but maybe the most readable way is to write in shell script, but use the shell's heredoc notation to invoke perl code.

#!/bin/bash
# this is a bash script, but there is some Perl in here too

echo this line is printed from the shell
echo now let\'s run some Perl

perl <<EOF
# this is now perl script until we get to the EOF
print "This line is printed from Perl\n";
EOF

echo now this is from the shell script again
Sign up to request clarification or add additional context in comments.

2 Comments

It bears pointing out that this "idiom" is hardly necessary on a modern system; it was implemented as a workaround for systems where the shebang line doesn't work like you want it to.
@tripleee, It bears pointing out that the OP is not actually using the idiom, and that having a modern system woulnd't help here.
2

1. If you start a Perl script in the usual way:

#!/usr/bin/perl
print "hello world\n";

the #! line will only work if the Perl interpreter is actually installed under /usr/bin. The perl/ksh bilingual script you show is a tricky kluge to make the script work even if perl is installed somewhere else. For more information, see e.g. this.

2. You can't. When the shell process encounters the exec command, it terminates and hands control over to perl. (Technically, it executes perl in place of the shell, without creating a new process.) The only way to run more shell commands after that would be to launch a new shell.

Comments

2

It's way simpler than what's already been posted.

#!$PERLLOCATION/bin/perl

doesn't work because the shebang (#!) line is interpreted by the kernel (not the shell), and the kernel doesn't do variable interpolation.

The code invokes ksh to expand the environment variable and to launch the specified installation of Perl.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.