LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   How to get the total arguments in perl?? (https://www.linuxquestions.org/questions/programming-9/how-to-get-the-total-arguments-in-perl-780446/)

ashok.g 01-06-2010 11:32 PM

How to get the total arguments in perl??
 
Hi,
How can I get the total arguments in perl.To be more specific if I try to execute the command
Code:

perl -w myperl.pl ash ok kumar
I should be able to get all the command line arguments.

I know that @ARGV will store only the arguments passed but not the entire arguments.

bartonski 01-07-2010 12:03 AM

Quote:

Originally Posted by ashok.g (Post 3817079)
Hi,
How can I get the total arguments in perl.To be more specific if I try to execute the command
Code:

perl -w myperl.pl ash ok kumar
I should be able to get all the command line arguments.

I know that @ARGV will store only the arguments passed but not the entire arguments.

I'm not quite sure what you mean by "entire arguments" as opposed to "arguments passed". Are you looking for the number of arguments passed?

Code:

$ cat /tmp/myperl.pl
#!/usr/bin/perl

use strict;
use warnings;

print join(" ", @ARGV) . "\n";
print scalar @ARGV . "\n";

$ perl /tmp/myperl.pl one two three four
one two three four
4

If you are trying to get environment variables exported by the shell, try this:
Code:

$ cat myperl2.pl
#!/usr/bin/perl

use strict;
use warnings;

print "the value of the environment variable \$USER is '$ENV{USER}'\n";
$ perl myperl2.pl
the value of the environment variable $USER is 'tiger'

Please explain what you mean by "entire arguments" as opposed to "arguments passed".

Thanks!

ashok.g 01-07-2010 12:23 AM

Quote:

Originally Posted by bartonski (Post 3817127)
I'm not quite sure what you mean by "entire arguments" as opposed to "arguments passed".

To be more clear....
Code:

#!usr/bin/perl -w
#Program to display the total arguments
use warnings;
use strict;
foreach (@ARGV)
{
print $_," ";
}
print "\n";

Now I run the command as:
Code:

[Ashok@station130 Assignment_1]$ perl -w package.pl ash ok kumar
ash ok kumar
[Ashok@station130 Assignment_1]$

What my requirement is I want to the output as:
Code:

[Ashok@station130 Assignment_1]$ perl -w package.pl ash ok kumar
perl -w package.pl ash ok kumar
[Ashok@station130 Assignment_1]$

I think it's very clear now....

ashok.g 01-07-2010 04:05 AM

Also, there is a special variable $0 which can be used to get our program name. But what about rest of the arguments(perl -w)?

bartonski 01-07-2010 05:18 PM

Ahh. I see. The problem is that your perl script doesn't actually see the entire command line.

The shell sees

Code:

perl -w package.pl ash ok kumar
perl sees

Code:

-w package.pl ash ok kumar
[and knows that it is being called as 'perl'].

Package.pl sees

Code:

ash ok kumar
[and knows that it is being called as 'Package.pl']

For Package.pl to be able to see the entire command line, it's going to have to make a call back to the shell. The shell has a variable '$COMP_LINE' contains the entire command line, but it's not populated by default... I didn't have time to read the entire section in the Bash man pages about this, but I know that it's there.

Alternatively, /proc/$$/cmdline is a virtual file which contains the command line.

smeezekitty 01-07-2010 07:36 PM

Code:

use warnings;
open f, '/proc/$$/cmdline';
print <f>;
close(f);

Try that!

ashok.g 01-07-2010 11:43 PM

Quote:

Originally Posted by bartonski (Post 3818141)
For Package.pl to be able to see the entire command line, it's going to have to make a call back to the shell. The shell has a variable '$COMP_LINE' contains the entire command line, but it's not populated by default... I didn't have time to read the entire section in the Bash man pages about this, but I know that it's there.

How can I invoke $COMP_LINE correctly in perl?

Hi bartonski and smeezekitty
By using the virtual file /proc/$$/cmdline, I am not able to get the specific command line arguments like "perl","-w", etc..,. Rather I am getting the total command line arguments as entire string. I tried as below:
Code:

#!usr/bin/perl
use strict;
use warnings;
open F, "/proc/$$/cmdline";
my @a=split "", <F>;
print @a,"\n";
close F;

How can I get the specific command for example "-w".



Thanks for your replies.

bartonski 01-08-2010 11:39 AM

Quote:

Originally Posted by ashok.g (Post 3818416)
How can I invoke $COMP_LINE correctly in perl?

Hi bartonski and smeezekitty
By using the virtual file /proc/$$/cmdline, I am not able to get the specific command line arguments like "perl","-w", etc..,. Rather I am getting the total command line arguments as entire string. I tried as below:
Code:

#!usr/bin/perl
use strict;
use warnings;
open F, "/proc/$$/cmdline";
my @a=split "", <F>;
print @a,"\n";
close F;

How can I get the specific command for example "-w".



Thanks for your replies.

I ran smeezekitty's code, and /proc/$$/cmdline does in fact contain the '-w'. Smeezekitty's code splits the file into individual characters. If you want to see it by words, you have to use ascii 0 as the delimiter.

Code:

> cat /tmp/asdf.pl
#!usr/bin/perl
use strict;
use warnings;
open F, "/proc/$$/cmdline";
my @a=split "\000", <F>;
print "@a\n";
close F;

> perl -w /tmp/asdf.pl asdf asdf sadf sadf
perl -w /tmp/asdf.pl asdf asdf sadf sadf


GooseYArd 01-08-2010 11:59 AM

Quote:

Originally Posted by ashok.g (Post 3818416)
How can I get the specific command for example "-w".

Why would you want to? If you're trying to detect whether perl is running -w so you can modify your own warnings behavior, you should just have your perl script accept -w as well.

bartonski 01-08-2010 12:30 PM

Quote:

Originally Posted by GooseYArd (Post 3819090)
Why would you want to? If you're trying to detect whether perl is running -w so you can modify your own warnings behavior, you should just have your perl script accept -w as well.

In general, I have to agree. If your perl script needs to resort to tricks like this, you probably need to revisit the design of your program. If you can't see a way around this on your own, you might also want to talk to someone about the design its self.

Telemachos 01-08-2010 02:25 PM

The -w is a flag not an argument. The Perl interpreter takes that and modifies execution accordingly (it turns on warnings), but the -w is not supposed to end up in @ARGV.

To jump ahead a little bit, can you tell us more about what you are really trying to do? If your goal is to be able to write command-line scripts with flags, Perl has lots of good modules to help you do that. Take a look at GetOpt::Std or Getopt::Long.

MBybee 01-08-2010 02:58 PM

Quote:

Originally Posted by Telemachos (Post 3819282)
The -w is a flag not an argument. The Perl interpreter takes that and modifies execution accordingly (it turns on warnings), but the -w is not supposed to end up in @ARGV.

To jump ahead a little bit, can you tell us more about what you are really trying to do? If your goal is to be able to write command-line scripts with flags, Perl has lots of good modules to help you do that. Take a look at GetOpt::Std or Getopt::Long.

Seconded - GetOpt is the right way to handle complex args.
To get the number of args just run $#ARGV, btw.

GooseYArd 01-08-2010 04:25 PM

Quote:

Originally Posted by MBybee (Post 3819330)
Seconded - GetOpt is the right way to handle complex args.
To get the number of args just run $#ARGV, btw.

not quite- that'll be the number of args - 1, since ARGV[0] is the first argument (unlike C) You want scalar(@ARGV)

rweaver 01-08-2010 04:52 PM

Another thing I'd point out is... you should really be specifying the commandline uses in the script itself--

Code:

use strict;
use warnings;

There is really no time you don't want those on. $0 will return perl and it's full path and as someone said earlier $#ARGV+1 will return the number of *arguments*, but *perl* flags aren't arguements. I don't recall a way to grab what perl flags are in use however.

You can see an example of this like such:

Code:

perl -e 'print $0 . " has " . (($#ARGV)+1) . " args.\n"'
test.pl:
Code:

#!/usr/bin/perl
print $0 . " has " . (($#ARGV)+1) . " args.\n"

Code:

core:~/test/test22$ perl -e 'print $0 . " has " . (($#ARGV)+1) . " args.\n"' 1 2 3
-e has 3 args.
core:~/test/test22$ ./test.pl asd as a
./test.pl has 3 args.
core:~/test/test22$ perl -w test.pl asd as a
test.pl has 3 args.


MBybee 01-08-2010 04:53 PM

Quote:

Originally Posted by GooseYArd (Post 3819467)
not quite- that'll be the number of args - 1, since ARGV[0] is the first argument (unlike C) You want scalar(@ARGV)

Sure - that's true that it gives you the size of an array counting from 0. Both give you the size, though they give you a different value :) Best part of perl is that there are many ways to shoot off your foot. I happen to prefer arrays 0 based, so that I can walk through it like this:

for( $val= 0; $val <= $#ARRAY; $val++ ){
}
Which is just a C habit.

However, it's all about preference, and both will work. Yay Perl :)


All times are GMT -5. The time now is 09:22 AM.