I am getting Bareword error in perl file - perl

I am executing my perl files in a batch. I am pasting all the name of the perl file in a batch file and executing it. I am giving a small demo of the file.
The batch file /10BT_run1.Amset contains:
Perl ../tools/test_driver_multi_aid_sequential.pl e2_h/l2_mode/set_bwprf #this is line 4 of the batch file
I am getting error like
Bareword found where operator expected at ./10BT_run1.Amset line 4, near "/tools /test_driver_multi_aid_sequential"
(Missing operator before test_driver_multi_aid_sequential?)
Bareword found where operator expected at ./10BT_run1.Amset line 4, near "/l2_mode/set_bwprf"
(Missing operator before et_bwprf?)

You are somehow executing the batch file (./10BT_run1.Amset) using perl instead of cmd.

you can run the perl files as argument to perl interpreter
perl "../tools/test_driver_multi_aid_sequential.pl e2_h/l2_mode/set_bwprf"
if you are going to use " in between the arguments separate those as escaping sequence like
\"
It will avoid the error that you have mentioned

Related

strange error message in a complex, but legal Perl one-liner

>perl -e '$_ = q(t b[\)sizeof];); s/(t?(\w)(?:\s(\w))?\s(\w)(\[([^\]]+)\]))/eval $1/e'
Bareword found where operator expected at (eval 1) line 1, near ")sizeof"
(Missing operator before sizeof?)
This is legal Perl, then why the error message? I have the latest Perl.
This is an SSCCE ; any one character less and the error message does not appear.
The Perl code is valid, but you are trying to eval a string which is not valid Perl code. When I run this code and swap eval for print, it prints the string:
t b[)sizeof]
Now if I try and run this as Perl code I get:
> perl -we't b[)sizeof]'
Bareword found where operator expected at -e line 1, near ")sizeof"
(Missing operator before sizeof?)
Unquoted string "sizeof" may clash with future reserved word at -e line 1.
syntax error at -e line 1, near "[)"
Execution of -e aborted due to compilation errors.
(You should always use warnings -w, even with one-liners)
This code does exactly what your evaluation is trying to do: It's trying to run that string as Perl code, and it fails because that string is not valid Perl code.
Also you should be careful when using eval, as it can do unexpected and catastrophical things to your computer. Usually, this kind of double evaluation is written using two of the /e modifiers, e.g.:
s/.../.../ee
Which is a bit more convenient than
s/.../eval .../e

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

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 u set the executable permissions to the file , then you can run the file by ./ or else run using perl filename.pl
perl test.pl
Specify to the shell that you want the current Perl executable (as is found in your $PATH) to execute the test.pl file that is located in your $PATH.
Run which perl to quickly see what version of perl is the default
Run echo $PATH to see where the '.' (current directory) is. ALL directories BEFORE the '.' will be checked FIRST for the test.pl file! Use ./test.pl instead so the shell looks in the current directory only...Unless you want it to hunt in the $PATH for the test.pl file.
./test.pl
Specify to the shell that you want the test.pl file, in the current directory, to be run by the executable as specified inside the test.pl file at the line with the she-bang (line that starts with #!).

Perl, Command not found after entering "perl -v"

I'm new to Perl.
Running Fedora 16
I have installed Perl recently, after the installation, I checked via "perl -v",
I got the following lines:
/usr/bin/perl: line 19: use: command not found
/usr/bin/perl: line 20: use: command not found
/usr/bin/perl: line 23: my: command not found
/usr/bin/perl: line 24: my: command not found
/usr/bin/perl: line 25: my: command not found
/usr/bin/perl: line 28: syntax error near unexpected token `('
/usr/bin/perl: line 28: `my %list=();'
Can I know why is it so?
Thank you.
That output is the output of a Perl script being executed by a bourne shell instead of perl.
perl is very funky on your setup. Maybe it has been accidentally replaced? Maybe you have an alias named perl? (What does type perl output?)
I had exactly the same problem.
Finally it was some so silly as that I had a blank space before the first line: #!/usr/bin/perl
Then, that line was ignored and the script was being interpreted by bash insted by perl.
I hope it helps to someone.
I'd be very surprised if there is a unix-like system which ships without perl. I'm not surprised that there are problems if more than one version are installed over each other.
If you have to use that system and can't start over, try installing it in some other location like /opt
Does #!/usr/bin/perl exists in your script at the begining?
I think its trying to run the script through the shell instead of perl, Check whether the script is using the encoding character UTF8 and finally try to invoke perl explicitly using the command perl filename.
Try to login with ROOT and try the same
Try the below command
which perl
You should get output as /usr/bin/perl

How to write perl one liner in Make?

I am writing the following command to extract the text in makefile:-
#awk '/Exported Layer/,/Total Polygons/' out_compare.err | perl -lane '$el=$F[3] if(/Exported Layer/); print "$el: $f[3]" if (/Total Polygons/);' | cat
But it is giving the following error:-
Can't modify constant item in scalar assignment at -e line 1, near "] if"
Execution of -e aborted due to compilation errors.
Would you guys like to suggest something? :-)
Make is oblivious to shell quoting in commands, so the $ characters in your Perl snippet are being interpreted as make variables $e and $F. These variables don't exist in your makefile and are being expanded as empty, leading to the Perl syntax errors you're seeing.
You need to escape the $ characters from make like this:
... perl -lane '$$el=$$F[3] if(/Exported Layer/); ...
See also the GNU Make manual.

What's the purpose of perl's #line directives?

Line directives (#line) are used to reconfigure perl's idea of the current filename and line number. When is this required to get right filename and line number (in an error message)?
Usually such markers are put into code that has been pre-processed or mechanically generated in order to refer back to the human-generated source.
For example, if there was a program that converted Python to Perl, it might insert a
# line 812 "foo.py"
so that error messages would refer to the original Python code which would make more sense to the programmer.
They're useful when wrapping a Perl script in another file, like pl2bat does. Perl doesn't see the batch commands at the beginning of the file which throws off its idea of line numbers. A #line directive at the beginning of the Perl source compensates for this.
I've seen several times that people incorrectly write the current line's number into the #line directive. It should contain the next line's number. Example code of linetest.pl (using a ksh wrapper to set an environment variable for the perl script):
1 #!/usr/bin/ksh
2 MY_ENV_VAR='something'
3 export MY_ENV_VAR
4 /usr/bin/perl -x $0 $# 2>&1
5 exit $?
6
7 #!/usr/bin/perl
8 #line 9
9 print "MY_ENV_VAR is $ENV{MY_ENV_VAR}\n";
10 die "This is line 10.";
Run the script and check the result:
$ ./linetest.pl
MY_ENV_VAR is something
This is line 10. at ./linetest.pl line 10.
You can see that line numbers are matching after writing #line 9 on line 8.
In addition to the already mentioned reasons perl has a (strongly discouraged) -P option that runs the Perl file through a C preprocessor before it is executed. Since most C preprocessor's will use line directives when they include or remove part of a file so any errors will be reported from where they were located in the original source instead of the processed source.
Line directives can also be very useful if you are generating code in strings that is then passed to eval. Normally if there is a warning or error in such code you get an error reported like "died at (eval 1) line 1." Using line directives you can supply a useful file name and line number.
The #line directive is also very helpful when doing perl -e in a shell script. I write
perl -e '#line X
more perl code here...
'
where X is the current shell script line +1 so that any Perl errors tell me the shell line where the failed Perl statement is.