Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between "perl test.pl" and "./test.pl"?

Tags:

perl

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?

like image 911
Rahul Desai Avatar asked Aug 15 '12 13:08

Rahul Desai


4 Answers

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:

    1. 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.

    2. 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"

    3. 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

like image 142
DVK Avatar answered Nov 14 '22 14:11

DVK


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.

like image 41
HonkyTonk Avatar answered Nov 14 '22 14:11

HonkyTonk


  • 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.

like image 4
rush Avatar answered Nov 14 '22 15:11

rush


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.

like image 3
Quentin Avatar answered Nov 14 '22 15:11

Quentin