I have observed that there are two ways of executing a perl program:
perl test.pl
and
./test.pl
What is the exact difference between these two and which one is recommendable?
I will rephrase slightly what other answers stated.
The first case will run the program called "perl" - presumably, a Perl language interpreter, and pass the value "test.pl" to it as the first parameter. Please note that this will do one of 3 things, depending on what "perl" is and what "test.pl" is:
If "perl" does not exist as an executable in your $PATH
or a shell alias (check by running which perl
), your shell will try to find a non-existing executable, and fail with perl: Command not found
error.
If "perl" is an executable in your path (or a shell alias) that is NOT actually a Perl interpreter program, that will get executed instead. As example, try this in csh:
alias perl echo
which perl # Will print "perl: aliased to echo"
perl test.pl # Will print "test.pl". NOT what you intended!
unalias perl
This will execute your "perl" alias and simply echo the word "test.pl"
If "perl" is an executable in your path that IS a real perl interpreter, it will pass "test.pl" to it as a first parameter. In that case, Perl interpreter will treat this parameter (as it doesn't start with a "-") as the name of a file containing Perl code to execute and try to read the file in, compile it as Perl code and execute it.
Note that, since the program being run is actually "perl" and "test.pl" is just a text file being read in, "test.pl" does NOT need to have the "execute" Unix file permission.
The second case, shell will try to find a file called "test.pl" in your current directory, and - if it exists AND is executable - try to execute it as a program.
If the file does not exist OR if the execute bit on it is not set, the shell will fail with "command not found" error.
If the file has the execute bit set, shell (or actually process loader in Unix kernel) will try to execute it. The rules by which Unix executes a given executable file is governed by the first 2 bytes of the file, aka "magic number".
For a VERY good in-depth coverage of how magic numbers work, see "How does the #! work?
" question on SO.
In a special case where the "magic number" is "#!" (aka "shebang"), the loader will read the first line of the file, and treat the contents of that line (sans the first 2 bytes) as a command to run instead of the given executable file; and append the path to the executable file as one more parameter to the command it read from shebang line. As examples:
if "test.pl" is a text file with a first line of #!/bin/sh -x
, the kernel will execute /bin/sh -x ./test.pl
.
if "test.pl" is a text file with a first line of #!/usr/bin/perl
, the kernel will execute /usr/bin/perl ./test.pl
.
if "test.pl" is a text file with a first line of #!perl
, the kernel will execute perl ./test.pl
.
if "test.pl" is a text file with a first line of my $var = 1;
(or any other first 2 bytes it doesn't know what to do with), it will either error out or (at least on RedHat Linux) will pretend that there was an implied #!/bin/sh
shebang and try to execute the file as Bourne Shell script. Which will of course fail since it was Perl code, not shell script
In the first case you are starting the perl
interpreter and asking it to use your file and run it.
In the second case you are asking your shell to execute your file. This requires that the file starts with
#!/<path to perl>/perl
and that the file has the execute bit set.
The best method to use is the one that fits your usecase the best.
The first one will always run the script as the perl
code.
The second one will do it only in case the perl is specified in she-bang. Otherwise it will run it as shell code or whatever is specified in she-bang (if there is no she-bang at all it will run as current shell code).
The first one will be executed even noexec
mount option is enabled.
The second one will fail in that case.
The same stuff with execute bit. The first one will work if +x
isn't setted, the second will fail.
The first executes the program using the perl
that is found first in your $PATH
. The second uses whatever shebang line in the program says.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With