user2131116 user2131116 - 3 months ago 7
Perl Question

Change the position of program lead to syntax error

I have a program called

shuffle.pl
. When I use
perl shuffle.pl Input Shuffled
to execute , it success work and show no error .

I create a directory called
./tools
under my home directory , and I set this path to
.cshrc
. So I can execute the program without typing
perl
to execute . ( This is my first time to do this , maybe some wrong in here)

But when I move the shuffle.pl to ~/.tools and execute . it show I have error in line 5 . But if I use
perl ~/.tools/shuffle.pl
it can work . So it means it should have no syntax error in my program ,But why it can't work after I put my program to ~/.tools

error message

.tools/shuffle.pl: 5: Syntax error: "(" unexpected


.cshrc

set path = (. ~ ~/.tools /sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin )


enter image description here

thanks

here is my program

#!/usr/bin/perl
use strict;
use warnings;

use List::Util qw(first max maxstr min minstr reduce shuffle sum);

open(my $fh,"<","$ARGV[0]");
my @Lines = readline($fh);
my @Shuffled = shuffle(@Lines);
close $fh;

open(my $shuf,">","$ARGV[1]");
print $shuf @Shuffled;
close $shuf;


enter image description here

Answer

The shebang is used to tell which interpreter should be used for this script. For this to work, the magic number #! has to appear at the immediate beginning of the file. Otherwise, the default interpreter is used.

In this case, the shebang was preceded by a few empty lines. They have to be removed.

The shebang is not parsed when an explicit interpreter is used to execute the file, E.g. in $ perl script.pl.
It is only important when launched as executable: ./script.pl. In that case, the kernel is left to figure out what to do with it: Load into memory as compiled program? Launch an interpreter? Which one? Magic numbers like #! resolve this.

In general, if the shebang doesn't work, the following possible errors can be checked:

  • An UTF byte order mark precedes the #!.
    Diagnosis: A hexdump shows FE FF at the beginning.
    Solution: configure your editor to store files without a BOM
  • The script is encoded in such a way that the beginning does not decode to #! as ASCII.
    Diagnosis: The file does not begin with #! when opened as ASCII or does not begin with 23 21 in a hexdump. Or your editor shows UTF-16 or UTF-32 as the encoding.
    Solution: Store the script in ASCII-compatible encoding. UTF-8 is an especially good choice.
  • Non-native line endings can be confused to be part of the executable name. E.g. with windows line endings, the shebang in

    #!/usr/bin/perl
    print 1;
    

    could be taken as the interpreter name "/usr/bin/perl\r". Many filesystems allow line endings inside filenames.
    Diagnosis: A hexdump shows something other than a space (20) or newline (0A) after the executable name.
    Solution: Convert line endings to Unix.