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 :)

bartonski 01-08-2010 05:08 PM

Quote:

Originally Posted by rweaver (Post 3819507)
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.

Hallelujah, Brother.

I didn't really learn that this was the right way to do things until I started working in a mixed Unix/Windows environment:

I used to run perl scripts using this shebang line.

Code:

#! /usr/bin/perl -w
That won't work under Windows.

(What's worse is when someone opens one of your perl files in a windows text editor... then saves it without makeing any changes... except for the nice little ^M characters littered throughout the code. This will mess up the shebang line because /usr/bin/perl is not the same as /usr/bin/perl^M... meaning that the shebang line won't work under Unix, either).

ashok.g 01-11-2010 02:53 AM

Quote:

Originally Posted by bartonski (Post 3819059)
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.plasdfasdfsadfsadf


Please observe that I used print @a,"\n"; instead of print @a,"\n";.
Why this is happening?

Sergei Steshenko 01-11-2010 04:51 AM

Quote:

Originally Posted by ashok.g (Post 3822141)
Please observe that I used print @a,"\n"; instead of print @a,"\n";.
Why this is happening?

What "this" ?

Telemachos 01-11-2010 06:51 AM

Quote:

Originally Posted by ashok.g (Post 3822141)
Please observe that I used print @a,"\n"; instead of print @a,"\n";.
Why this is happening?

I believe you mean print @a, "\n"; instead of print "@a\n";.

If you interpolate an array in double quotes and print it, you get each item separated by a space. If, however, you print the array unquoted, you get all the items concatenated together without any separation of any kind.

Code:

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

my @stuff = qw/foo bar bizz buzz fizzbuzz/;

print "With quotes:\n";
print "\t@stuff\n";

print "Without quotes:\n";
print "\t", @stuff, "\n";

Output:
Code:

telemachus ~ $ perl array_print
With quotes:
        foo bar bizz buzz fizzbuzz
Without quotes:
        foobarbizzbuzzfizzbuzz

Note that the behavior of interpolated arrays (space separated) can be adjusted by tinkering with the $" built-in variable.

Sergei Steshenko 01-11-2010 07:01 AM

Quote:

Originally Posted by Telemachos (Post 3822310)
I believe you mean print @a, "\n"; instead of print "@a\n";.

If you interpolate an array in double quotes and print it, you get each item separated by a space. If, however, you print the array unquoted, you get all the items concatenated together without any separation of any kind.

Code:

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

my @stuff = qw/foo bar bizz buzz fizzbuzz/;

print "With quotes:\n";
print "\t@stuff\n";

print "Without quotes:\n";
print "\t", @stuff, "\n";

Output:
Code:

telemachus ~ $ perl array_print
With quotes:
        foo bar bizz buzz fizzbuzz
Without quotes:
        foobarbizzbuzzfizzbuzz

Note that the behavior of interpolated arrays (space separated) can be adjusted by tinkering with the $" built-in variable.

Such answers leave the OP no chance to learn to ask questions correctly in the first place.

Telemachos 01-11-2010 04:11 PM

Quote:

Originally Posted by Sergei Steshenko (Post 3822325)
Such answers leave the OP no chance to learn to ask questions correctly in the first place.

That is your opinion, and you have every right to it. In my opinion, your style of answer ("Here are the docs. Read them. If you don't understand something, write here, explaining the first word you don't understand and why...") makes people ask elsewhere (or give up).

I will continue to answer in my style. You can continue to disagree with my choices. Such is life.

Sergei Steshenko 01-12-2010 01:00 AM

Quote:

Originally Posted by Telemachos (Post 3822964)
That is your opinion, and you have every right to it. In my opinion, your style of answer ("Here are the docs. Read them. If you don't understand something, write here, explaining the first word you don't understand and why...") makes people ask elsewhere (or give up).

I will continue to answer in my style. You can continue to disagree with my choices. Such is life.

They'd better give up - otherwise their job has to be done by others.

As someone else wrote in this forum - instead of learning nowadays "Internet forum learning" or something like this has become immensely popular. I.e. instead of making an effort to read and understand people just ask questions in forums without making an effort first.

Unfortunately, I too often had to work with people who never bothered to read the documentation on tools they were systematically/repeatedly using.

It was a disaster, i.e. they didn't understand how the tools were working/what they were doing, they just new command line format for certain tasks they were routinely performing. They couldn't make even a minimal modification of the command lines when needed (i.e. all they could was, say, replacing file names on command lines), they couldn't analyze and correct mistakes they made (and we all make mistakes) - exactly because they didn't understand what they and the tools were doing.

Kind of "command line monkeys" if you wish - similar to "coding monkeys".

As you said, such is life. I.e. the more you do the job of others, the more the others take it for granted.

Telemachos 01-12-2010 08:33 AM

Quote:

Originally Posted by Sergei Steshenko (Post 3823349)
They'd better give up - otherwise their job has to be done by others.

<snip>

As you said, such is life. I.e. the more you do the job of others, the more the others take it for granted.

This is a reasonable response, so I will try to explain why I disagree. I agree that if people use forums only to get the answer, they won't ever learn.

However, my hope is that if I give more explanation and people read what I write and think about it, they will learn. I also generally post links to fuller documentation or articles or mention books. If someone posts question after question about very basic things and doesn't show any increase in knowledge, I stop posting answers. But I don't mind writing fuller answers at first.

Perl's documentation is excellent, but it can be overwhelming for someone new to the language or new to programming. I remember how it felt for me at first. Everything was in there, but (1) I couldn't always find things and (2) sometimes the explanations went way over my head.

Anyhow, that's why I often write fuller answers.


All times are GMT -5. The time now is 12:16 AM.