i am very new to perl just began to learn when i try to assign a scalar a value and the print it i am facing problem. I am doing
perl -e "$number=30;"
perl -e "print $number;"
the output doesnt show anything but when i do
perl -e "$number=30; print $number;"
the output shows 30 why?
This:
perl -e "$number=30;"
runs the Perl program $number=30;, which sets the variable $number to 30 and then does nothing with it.
This:
perl -e "print $number;"
runs the Perl program print $number;, which prints the value of the uninitialized variable $number.
The key point is that, since these are two completely separate Perl programs, there's no connection between the variable $number in the first program and the variable $number in the second program. There is no relationship between the two programs, and no communication between them, so they do not and cannot share any variables.
when you execute:
perl -e "$number=30;"
perl -e "print $number;"
these are two independent processes, so they don't share information. Variable $number won't be available to the second command.
The other one:
perl -e "$number=30; print $number;"
Works because it runs in the same execution, and $number is visible to the next print sentence
Related
I have a perl module with data definitions (hashes, arrays, etc.), is there any way I can access that data from inside a bash script? This isn't working for me...
#!/bin/bash
perl -e 'use Data'
tests=`perl -e "#tests"; `
echo "Perl tests = ${tests}" # prints "Perl tests = "
The module looks something like this:
our #EXPORT_OK = qw( #tests );
our #tests = qw( 1 2 3 4 5 );
If you have package variable #tests inside Data module,
perl -MData -e 'print "$_\n" for #Data::tests'
For perl 5.10 and above,
perl -MData -E 'say for #Data::tests'
You can use a module from the command line with -M
perl -MData -e'print map {"$_\n"} #tests;'
In the code you give, you run one interpreter that loads Data. It exits. You then run a second interpreter, which prints #tests. As that's the only action the second interpreter has performed, it's uninitialized, and prints nothing.
This question already has answers here:
How can I process options using Perl in -n or -p mode?
(2 answers)
Closed last year.
I often need to run some Perl one-liners for fast data manipulations, like
some_command | perl -lne 'print if /abc/'
Reading from a pipe, I don't need a loop around the command arg filenames. How can I achieve the next?
some_command | perl -lne 'print if /$ARGV[0]/' abc
This gives the error:
Can't open abc: No such file or directory.
I understand that the '-n' does the
while(<>) {.... }
around my program, and the <> takes args as filenames, but doing the next every time is a bit impractical
#/bin/sh
while read line
do
some_command | perl -lne 'BEGIN{$val=shift #ARGV} print if /$val/' "$line"
done
Is there some better way to get "inside" the Perl ONE-LINER command line arguments without getting them interpreted as filenames?
Some solutions:
perl -e'while (<STDIN>) { print if /$ARGV[0]/ }' pat
perl -e'$p = shift; while (<>) { print if /$p/ }' pat
perl -e'$p = shift; print grep /$p/, <>' pat
perl -ne'BEGIN { $p = shift } print if /$p/' pat
perl -sne'print if /$p/' -- -p=pat
PAT=pat perl -ne'print if /$ENV{PAT}/'
Of course, it might make more sense to create a pattern that's an ORing or all patterns rather than executing the same command for each pattern.
Also reasonably short:
... | expr=abc perl -lne 'print if /$ENV{expr}/'
Works in bash shell but maybe not other shells.
It depends on what you think will be in the lines you read, but you could play with:
#/bin/sh
while read line
do
some_command | perl -lne "print if /$line/"
done
Clearly, if $line might contain slashes, this is not going to fly. Then, AFAIK, you're stuck with the BEGIN block formulation.
[root# ~]$ perl -e "print 1 if blessed $a;"
1
[root# ~]$ perl -e "print 1 if blessed $c;"
1
[root# ~]$ perl -e "print 1 if blessed $cee;"
1
It seems always true,the version is 5.8.8.
UPDATE
I'm not running as root, it's CHANGED by me for the sake of privacy:)
blessed is not a keyword in Perl. You are using double quotes in your shell command, so the variables ($a, $c, etc.) are from your shell's environment, they are not Perl variables.
Since these environment variables are probably empty, you are essentially executing the script
print 1 if blessed ;
When used like this, blessed is just a bareword string and always evaluates to true. What you have done is not much difference from running
$ perl -e 'print 1 if foo'
Do you mean blessed from Scalar::Util? You probably want to load the function first:
perl -MScalar::Util=blessed -e "print 1 if blessed $a;"
otherwise your blessed is just bareword (string), which is obviously true.
As has been pointed out, you need to load the module before using the method. Also, if you had used perl -we instead of perl -e, you would probably not have asked this question.
For me, with perl -we, I get this warning:
Can't call method "blessed" without a package or object reference at -e line 1.
On Mac OSX, this works fine with perl
perl -v
This is perl, v5.8.9 built for darwin-2level
perl -e 'sub test {}'
But on Solaris
perl -v
This is perl, v5.8.8 built for i86pc-solaris-thread-multi
perl -e 'sub test {}'
Illegal declaration of anonymous subroutine at -e line 1.
Any ideas?
Thanks,
Kelly
It's most likely a behavior difference between the two versions of Perl. It's also probably just a bug in the CLI evaluation mode in 5.8.8
Try this test to see if it's just the CLI evaluation or Perl itself:
use strict;
sub test {}
If it passes strict mode in a file, it's probably as good as it's gonna get.
perldoc perldiag says:
Illegal declaration of anonymous subroutine
(F) When using the sub keyword to construct an anonymous subroutine,
you must always specify a block of code. See perlsub
It's could possibly be in a sitecustomize.pl file. It's not seeing the "test". It's reading it as 'sub'. Try typing perl -e 'test {}' on the command line.
Also to take out the customization file, you could add the -f switch to the command line. `perl -fe 'sub test {}'
perldoc perlrun for more information.
I want to wrap a Perl one-liner in a batch file. For a (trivial) example, in a Unix shell, I could quote up a command like this:
perl -e 'print localtime() . "\n"'
But DOS chokes on that with this helpful error message:
Can't find string terminator "'" anywhere before EOF at -e line 1.
What's the best way to do this within a .bat file?
For Perl stuff on Windows, I try to use the generalized quoting as much as possible so I don't get leaning toothpick syndrome. I save the quotes for the stuff that DOS needs:
perl -e "print scalar localtime() . qq(\n)"
If you just need a newline at the end of the print, you can let the -l switch do that for you:
perl -le "print scalar localtime()"
For other cool things you can do with switches, see the perlrun documentation.
In Windows' "DOS prompt" (cmd.exe) you need to use double quotes not single quotes. For inside the quoted Perl code, Perl gives you a lot of options. Three are:
perl -e "print localtime() . qq(\n)"
perl -e "print localtime() . $/"
perl -le "print ''.localtime()"
If you have Perl 5.10 or newer:
perl -E "say scalar localtime()"
Thanks to J.F. Sebastian's comment.
For general batch files under Windows NT+, the ^ character escapes lots of things (<>|&), but for quotes, doubling them works wonders:
C:\>perl -e "print localtime() . ""\n"""
Thu Oct 2 09:17:32 2008
First, any answer you get to this is command-specific, because the DOS shell doesn't parse the command-line like a uniq one does; it passes the entire unparsed string to the command, which does any splitting. That said, if using /subsystem:console the C runtime provides splitting before calling main(), and most commands use this.
If an application is using this splitting, the way you type a literal double-quote is by doubling it. So you'd do
perl -e "print localtime() . ""\n"""
In DOS, you use the "" around your Perl command. The DOS shell doesn't do single quotes like the normal Unix shell:
perl -e "print localtime();"