Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

passing value to a perl program 1

Status
Not open for further replies.

warmongr

MIS
Joined
Mar 17, 1999
Messages
214
Location
US
This may seem silly however I would like to run a perl program from the command line such as

./name_o_program 999

How do I pass the 999 to the script.

Thanks,
War
 
Nevermind. Duh!

my $run = $ARGV[0];

later just access the variable $run.

I was using an @ for ARGV, like @ARGV[0];

 
@ARGV[0] should have worked too, although it is messy syntax. That's an array slice, and would have simply returned the first element of the @ARGV array in a list context. The only reason that might have not worked is if you maybe misspelled ARGV as well.

Code:
my $run = $ARGV[0];
my $run = @ARGV[0];
my ($run) = @ARGV;

All of those should end with the same assignment to $run. Personally I prefer the last method since you can quickly and easily add more parameters to your script.
 
FYI. Outside of a subroutine, the "shift" function works on @ARGV by default, so the following would work too:
Code:
my $run = shift;
 
ishnid, so that I understand your last

my $run = shift;

without specifying ARGV it would look for it?

N

One additional question:

I am looking at /proc/stat and gathering cpu information. If I have 4 cpu's what is the best way to parse the list and store the various data? An array? A list?

Thanks,
 
Regarding ishnid's use of shift, just read the documentation:


Concerning the list of cpus, either a hash or array would work. The names are generally of the form: 'cpu0', 'cpu1', 'cpu2', 'cpu3'. These could easily be treated as array indexes

Code:
my ($index) = $cpuname =~ /cpu(\d+)/;
my $cpus[$index] = foobar;

But they could just as easily be used as hash keys

Code:
my $cpus{$cpuname} = foobar;

Whatever floats your boat.
 
Thanks MillerH:

I'm not great with perl so be patient but here is what I have.

open ( STAT,"</proc/stat" ) or die;
@raw_stat=<STAT>;
close(STAT);
$iteration = 0;
foreach $line (@raw_stat) {
if ($line =~/cpu/) {
$iteration = $iteration + 1;
print $line;
}
}

I'd like to take the data as follows:

1st row in file is the aggregate data; break it up in fields so I can capture useragg jiffies, systemagg jiffies etc.

and then do the same for each subsequent cpu(n).

How can I do this better/more efficiently.
War
 
if all you want is the cpu data, and if I understand how the stat file is formatted, this might work. A hash of arrays:

Code:
use Data::Dumper;
my %CPU = ();
open ( STAT, "</proc/stat" ) or die;
while (<STAT>) {
   chomp;
   if (/^(cpu\d?)/) {
      $CPU{$1} = [(split(/\s+/))[1..7]];        
   }
   else {last;}
}
close(STAT);
print Dumper %CPU;



- Kevin, perl coder unexceptional! [wiggle]
 
KevinADC:

Thanks, I've just gotten back to this. While this does break out the /proc/stat file I guess I should have mentioned that I am running this in 3 second intervals and then calculating the difference between intervals.

This tells me how much work is being done by USER processes vs SYSTEM processes. I assumed (incorrectly) that since the application we are testing is single threaded that individual CPU data wasn't necessary and the aggregated data would do. Once I was asked to break it out by CPU I thought "hmmm!". Not being too good with hashes and array's just yet I looked at this as a learning project but then got stuck.

How can I access the individual elements of this output from your code.

$VAR1 = 'cpu';
$VAR2 = [
'30177',
'1140',
'21767',
'17514397',
'17930',
'90467',
'0'
];
$VAR3 = 'cpu0';
$VAR4 = [
'30177',
'1140',
'21767',
'17514397',
'17930',
'90467',
'0'
];
 
$CPU{cpu}->[0]
$CPU{cpu0}->[2]

etc
etc

where '$CPU' is the hash name, 'cpu' and 'cpu0' are the hash keys, and [0],[2] are the index number of one of the array elements. The arrays you posted have 7 elements so the index numbers are 0 thru 6.

- Kevin, perl coder unexceptional! [wiggle]
 
So would for instance $VAR4[0] equal element one? of the array VAR4?
 
essentially, yes. Really it's $CPU{cu}->[0] but you could dereference the array

Code:
my @array = @{$CPU{cpu}};
print $array[0];

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
KevinADC,

I need to beg for your help one more time.

I've been working on a way to parse /proc/stat to get the raw CPU jiffies and then calculate the difference between reads in a predefined interval. I have the following so far and was hoping I could get some help on debugging. The problem that I get is that every interval the aggregate data is correct but all other cpu's are zero. I'm sure it is becuase of my flawed logic as I am not real good with hashes or arrays just yet but you were a big help with that. Here is what I have so far. My desire is to have a delta calculation for each cpu.

#!/usr/bin/perl


# This is the format of the data I want
# CPU User nice sys idle iowait irq softirq
# cpu 3530 111 1837 289668 3771 715 0
# cpu0 3530 111 1837 289668 3771 715 0




sub getcpu
# Routine to capture /proc/stat and store in a hash table or hash tables
{

my ($cpu,$user,$nice,$system,$idle,$iowait,$irq,$softirq);
my %HoH = ();
my $file = '/proc/stat';
open ( CPUSTAT, "<$file" ) or die "Cannot open file";
while ( <CPUSTAT> ) {
# Look for lines with the cpu information
if ( $_ =~ /^(cpu\d?)/ ) {
# Read in data and split into fields
($cpu,$user,$nice,$system,$idle,$iowait,$irq,
$softirq) = split(' ');
# Declare the hash table; $cpu will be key and the rest are elements of hash
# store in variables

$HoH{ $cpu }{ 'user' } = $user;
$HoH{ $cpu }{ 'nice' } = $nice;
$HoH{ $cpu }{ 'system' } = $system;
$HoH{ $cpu }{ 'idle' } = $idle;
$HoH{ $cpu }{ 'iowait' } = $iowait;
$HoH{ $cpu }{ 'irq' } = $irq;
$HoH{ $cpu }{ 'softirq' } = $softirq;

}
}

close CPUSTAT;
# Provide hash to calls to this function
return \%HoH;
}

# This is where the rubber meets the road

$iteration = 0;
while ( $iteration >= 0 ) {
# Declare a variable to store return value from getcpu function call
my $rHoH = getcpu();
my ( $user,$nice,$system,$idle,$iowait,$irq,$softirq );

foreach $cpu ( sort(keys %$rHoH) ) {
# Declare variables to store hash elements

$user = $rHoH->{ $cpu }{ 'user' };
$nice = $rHoH->{ $cpu }{ 'nice' };
$system = $rHoH->{ $cpu }{ 'system' };
$idle = $rHoH->{ $cpu }{ 'idle' };
$iowait = $rHoH->{ $cpu }{ 'iowait' };
$irq = $rHoH->{ $cpu }{ 'irq' };
$softirq= $rHoH->{ $cpu }{ 'softirq' };

#print "$cpu,$user,$system,$nice,$idle,$iowait,$irq,$softirq";
if ( $iteration > 0 ) {
$deltauser = $user - $olduser;
$deltasystem = $system - $oldsystem;
$deltanice = $nice - $oldnice;
$deltaidle = $idle - $oldidle;
$deltaiowait = $iowait - $oldiowait;
$deltairq = $irq - $oldirq;
$deltasoftirq = $softirq - $oldsoftirq;

print "$iteration,$cpu,$deltauser,$deltasystem,$deltanice,$deltaidle,$deltaiowait,$deltairq,$deltasoftirq,$olduser,$oldsystem,$iteration\n";

}

$olduser = $user;
$oldsystem = $system;
$oldnice = $nice;
$oldidle = $idle;
$oldiowait = $iowait;
$oldoldirq = $irq;
$oldsoftirq = $softirq;


}
$iteration++;
sleep 1;

}

 
post some sample data and I'll give it a shot sometime today.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks for your help. Below is a little data to play with. If you have a linux box you can look at /proc/stat and the values change regularly.

1. The idea is to read the file
2. Look for anything with 'cpu' in it
3. Grab the fields and store in variable
4. Store each iteration and subtract it from the
next iteration to find out how many jiffies were used
in at least fields 1 and 3 (user and system jiffies)
5. I really don't expect you to write it but if you could tell me what's wrong it would be valuable to me as a learning tool.

cpu 7080 251 7767 8623782 4405 35440 0
cpu0 7080 251 7767 8623782 4405 35440 0
cpu1 7083 251 7769 8623782 4405 35440 0
cpu2 7085 251 7772 8623782 4405 35440 0
cpu3 7095 251 7774 8623782 4405 35440 0

intr 96910182 86800485 3607 0 1 8 1 1 848632 1 6 1 8441480 17910 0 17563 780486
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
ctxt 13093329
btime 1171462776
processes 11701
procs_running 2
procs_blocked 0
 
is ths a typo?

$oldoldirq = $irq;


the variable $oldoldirq is only used once. Maybe that is supposed to be $oldirq

note: use strict [wink]

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
OK, I had a chance to test your code and see what was going on. The proc/stat function I was testing with returned less data than yours, maybe because I was testing it on a hosted site as I do not have a local linux setup to test with. But all you have to do is add the other data fields missing in my code.

Your code wasn't too bad but the logic you were using to calculate the old data with the new and get the differences was wrong. As I was unable to work it out using your strategy, I used the Storable module to freeze and thaw the old data as needed to compare to the new data.

Code:
[gray]#!/usr/bin/perl[/gray]
[url=http://perldoc.perl.org/functions/use.html][black][b]use[/b][/black][/url] [green]strict[/green][red];[/red]
[black][b]use[/b][/black] [green]warnings[/green][red];[/red]
[black][b]use[/b][/black] [green]diagnostics[/green][red];[/red]
[black][b]use[/b][/black] [green]Storable[/green] [red]qw/[/red][purple]freeze thaw[/purple][red]/[/red][red];[/red]

[gray][i]# I was testing in a browser, just remove this stuff[/i][/gray]
[gray][i]# if running in console[/i][/gray]
[url=http://perldoc.perl.org/functions/print.html][black][b]print[/b][/black][/url] [red]"[/red][purple]Content-type: text/html[purple][b]\n[/b][/purple][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
[black][b]print[/b][/black] [red]'[/red][purple]<plaintext>[/purple][red]'[/red][red];[/red]

[url=http://perldoc.perl.org/functions/sub.html][black][b]sub[/b][/black][/url] [maroon]getcpu[/maroon] [red]{[/red]

  [url=http://perldoc.perl.org/functions/my.html][black][b]my[/b][/black][/url] [blue]%HoH[/blue] = [red]([/red][red])[/red][red];[/red]
  [url=http://perldoc.perl.org/functions/open.html][black][b]open[/b][/black][/url] [red]([/red] CPUSTAT, [red]'[/red][purple]cat /proc/stat |[/purple][red]'[/red] [red])[/red] or [url=http://perldoc.perl.org/functions/die.html][black][b]die[/b][/black][/url] [red]"[/red][purple]Cannot open pipe to stat: [blue]$![/blue][/purple][red]"[/red][red];[/red]
  [black][b]my[/b][/black] [blue]@lines[/blue] = <CPUSTAT>[red];[/red]
  [olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$lines[/blue] [red]([/red][blue]@lines[/blue][red])[/red] [red]{[/red]
     [url=http://perldoc.perl.org/functions/chomp.html][black][b]chomp[/b][/black][/url] [blue]$lines[/blue][red];[/red]
     [olive][b]if[/b][/olive] [red]([/red]  [blue]$lines[/blue] =~ [red]/[/red][purple]^(cpu[purple][b]\d[/b][/purple]?)[/purple][red]/[/red] [red])[/red] [red]{[/red]
     [black][b]my[/b][/black] [red]([/red][blue]$cpu[/blue],[blue]$user[/blue],[blue]$nice[/blue],[blue]$system[/blue],[blue]$idle[/blue][red])[/red] = [url=http://perldoc.perl.org/functions/split.html][black][b]split[/b][/black][/url][red]([/red][red]/[/red][purple][purple][b]\s[/b][/purple]+[/purple][red]/[/red],[blue]$lines[/blue][red])[/red][red];[/red]
        [blue]$HoH[/blue][red]{[/red] [blue]$cpu[/blue] [red]}[/red][red]{[/red]    [red]'[/red][purple]user[/purple][red]'[/red] [red]}[/red]    = [blue]$user[/blue][red];[/red]
        [blue]$HoH[/blue][red]{[/red] [blue]$cpu[/blue] [red]}[/red][red]{[/red]    [red]'[/red][purple]nice[/purple][red]'[/red] [red]}[/red]    = [blue]$nice[/blue][red];[/red]
        [blue]$HoH[/blue][red]{[/red] [blue]$cpu[/blue] [red]}[/red][red]{[/red]  [red]'[/red][purple]system[/purple][red]'[/red] [red]}[/red]    = [blue]$system[/blue][red];[/red]
        [blue]$HoH[/blue][red]{[/red] [blue]$cpu[/blue] [red]}[/red][red]{[/red]   [red]'[/red][purple]idle[/purple][red]'[/red]  [red]}[/red]    = [blue]$idle[/blue][red];[/red]
     [red]}[/red]
  [red]}[/red]
  [url=http://perldoc.perl.org/functions/close.html][black][b]close[/b][/black][/url] CPUSTAT[red];[/red]
  [url=http://perldoc.perl.org/functions/return.html][black][b]return[/b][/black][/url] \[blue]%HoH[/blue][red];[/red]
[red]}[/red]

[black][b]my[/b][/black] [blue]$rHoH[/blue][red];[/red]
[black][b]my[/b][/black] [blue]$store[/blue][red];[/red]
[black][b]my[/b][/black] [blue]$iteration[/blue] = [fuchsia]0[/fuchsia][red];[/red]

[maroon]LOOP[/maroon][maroon]:[/maroon] [olive][b]until[/b][/olive] [red]([/red] [blue]$iteration[/blue] == [fuchsia]10[/fuchsia] [red])[/red] [red]{[/red]
   [olive][b]if[/b][/olive] [red]([/red][blue]$iteration[/blue] == [fuchsia]0[/fuchsia][red])[/red] [red]{[/red] [gray][i]#<-- for initializing first set of data from stat[/i][/gray]
      [blue]$rHoH[/blue] = [maroon]getcpu[/maroon][red]([/red][red])[/red][red];[/red]
      [blue]$store[/blue]  = freeze [blue]$rHoH[/blue][red];[/red] [gray][i]#<-- first set of records "frozen"[/i][/gray]
      [blue]$iteration[/blue]++[red];[/red]
      [olive][b]next[/b][/olive] LOOP[red];[/red] [gray][i]#<-- go to next iteration of loop[/i][/gray]
   [red]}[/red]
   [olive][b]else[/b][/olive] [red]{[/red] [gray][i]#<-- we have the first set compare with the next set [/i][/gray]
      [black][b]my[/b][/black] [blue]$rOld[/blue] = [maroon]thaw[/maroon][red]([/red][blue]$store[/blue][red])[/red][red];[/red] [gray][i]#<-- "thaw" old set      [/i][/gray]
      [blue]$rHoH[/blue] = [maroon]getcpu[/maroon][red]([/red][red])[/red][red];[/red] [gray][i]#<-- get the next set [/i][/gray]
      [blue]$store[/blue]  = freeze [blue]$rHoH[/blue][red];[/red] [gray][i]#<-- "freeze" new set from stat for next iteration[/i][/gray]
      [olive][b]foreach[/b][/olive] [black][b]my[/b][/black] [blue]$cpu[/blue] [red]([/red] [url=http://perldoc.perl.org/functions/sort.html][black][b]sort[/b][/black][/url] [url=http://perldoc.perl.org/functions/keys.html][black][b]keys[/b][/black][/url] [blue]%$rHoH[/blue] [red])[/red] [red]{[/red]
         [black][b]print[/b][/black] [red]"[/red][purple][blue]$cpu[/blue] [/purple][red]"[/red], [url=http://perldoc.perl.org/functions/join.html][black][b]join[/b][/black][/url][red]([/red][red]'[/red][purple],[/purple][red]'[/red],
                              [blue]$rHoH[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]user[red]}[/red]   - [blue]$rOld[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]user[red]}[/red],
                              [blue]$rHoH[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]nice[red]}[/red]   - [blue]$rOld[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]nice[red]}[/red],
                              [blue]$rHoH[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red][url=http://perldoc.perl.org/functions/system.html][black][b]system[/b][/black][/url][red]}[/red] - [blue]$rOld[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red][black][b]system[/b][/black][red]}[/red],
                              [blue]$rHoH[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]idle[red]}[/red]   - [blue]$rOld[/blue]->[red]{[/red][blue]$cpu[/blue][red]}[/red][red]{[/red]idle[red]}[/red],
                             [red])[/red][red];[/red]
         [black][b]print[/b][/black] [red]"[/red][purple][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red]
      [red]}[/red]
      [black][b]print[/b][/black] [red]"[/red][purple][purple][b]\n[/b][/purple][/purple][red]"[/red],[red]'[/red][purple]-[/purple][red]'[/red] x [fuchsia]30[/fuchsia],[red]"[/red][purple][purple][b]\n[/b][/purple][/purple][red]"[/red][red];[/red] 
      [blue]$iteration[/blue]++[red];[/red]
      [url=http://perldoc.perl.org/functions/sleep.html][black][b]sleep[/b][/black][/url] [fuchsia]2[/fuchsia][red];[/red]
   [red]}[/red]
[red]}[/red]
[tt]------------------------------------------------------------
Pragmas (perl 5.8.8) used :
[ul]
[li]diagnostics - Produce verbose warning diagnostics[/li]
[li]strict - Perl pragma to restrict unsafe constructs[/li]
[li]warnings - Perl pragma to control optional warnings[/li]
[/ul]
Core (perl 5.8.8) Modules used :
[ul]
[li]Storable - persistence for Perl data structures[/li]
[/ul]
[/tt]

You can se I coded it just to make a few loops:

Code:
LOOP: until ( $iteration == 10 ) {

but you can just change that to suit your needs.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Thanks,

that is much cleaner. I will test out this morning on a 2 way and a 4 way dual core and let you know.

I think the thing I was missing was:
$rHoH->{$cpu}{user} - $rOld->{$cpu}{user},
. I assume this creates a hash per cpu of the values retrieved. I knew the other iterations were 0 becuase they were storing the initial value to oldvalue then immediately subtracting those values on iterations > than 0 but I could not figure out how to do what you've done here.

War.
 
this is just subtraction:

$rHoH->{$cpu}{user} - $rOld->{$cpu}{user},

the two hashes are created before that part of the script.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top