[Perl] Unixcommando wordt niet door perl script uitgevoerd

Pagina: 1
Acties:

  • Nitroglycerine
  • Registratie: Januari 2002
  • Laatst online: 23:05

Nitroglycerine

Autisme: belemmering en kracht

Topicstarter
Ik ben bezig om op een AIX machine een perl script werkend te krijgen. De bedoeling van het script is dat het het vrije virtuele geheugen opvraagd (met het commando vmstat), de laatste regel van de output neemt (middels tail -1) en daar de 3e en 4e waarde uit neemt (met awk '{print $3 $4}' ). So far so good zou je zeggen, maar ik krijg bij het uitvoeren van het commando de volgende foutmelding:
code:
1
2
3
4
# ./test.pl -f -w 50 -c 25
Use of uninitialized value in concatenation (.) or string at ./test.pl line 43.
Use of uninitialized value in concatenation (.) or string at ./test.pl line 43.
Can't use string (" 1  1 1439197  5470   0   4   4 ") as a symbol ref while "strict refs" in use at ./test.pl line 45.

Als ik op regel 43 kijk, dan staat daar juist de commandoregel (in het stuk code wat ik gegeven heb, is dat regel 24 - commentaar regels zijn weggehaald).

hier een gedeelte van de code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/perl -w 

# Tell Perl what we need to use 
use strict; 
use Getopt::Std; 

use vars qw($opt_c $opt_f $opt_u $opt_w 
$free_memory $used_memory $total_memory 
$crit_level $warn_level 
%exit_codes @memlist 
$percent $fmt_pct 
$verb_err $command_line); 

# Predefined exit codes for Nagios 
%exit_codes = ('UNKNOWN' ,-1, 
'OK' , 0, 
'WARNING' , 1, 
'CRITICAL', 2,); 

# Turn this to 1 to see reason for parameter errors (if any) 
$verb_err = 0; 

# This the unix command string that brings Perl the data 
$command_line = `vmstat | tail -1 | awk '{ print $3 $4}'`; 

print $command_line

chomp $command_line; 
@memlist = split(/ /, $command_line); 

# Define the calculating scalars 
$used_memory = $memlist[0]; 
$free_memory = $memlist[1]; 
$total_memory = $used_memory + $free_memory; 

# Get the options 
if ($#ARGV le 0) 
{ 
&usage; 
} 
else 
{ 
getopts('c:fuw:'); 
} 

# Shortcircuit the switches 
if (!$opt_w or $opt_w == 0 or !$opt_c or $opt_c == 0) 
{ 
print "*** You must define WARN and CRITICAL levels!" if ($verb_err); 
&usage; 
} 
elsif (!$opt_f and !$opt_u) 
{ 
print "*** You must select to monitor either USED or FREE memory!" if ($verb_err); 
&usage; 
} 

# Check if levels are sane 
if ($opt_w <= $opt_c and $opt_f) 
{ 
print "*** WARN level must not be less than CRITICAL when checking FREE memory!" if ($verb_err); 
&usage; 
} 
elsif ($opt_w >= $opt_c and $opt_u) 
{ 
print "*** WARN level must not be greater than CRITICAL when checking USED memory!" if ($verb_err); 
&usage; 
} 

$warn_level = $opt_w; 
$crit_level = $opt_c; 

if ($opt_f) 
{ 
$percent = $free_memory / $total_memory * 100; 
$fmt_pct = sprintf "%.1f", $percent; 
if ($percent <= $crit_level) 
{ 
print "Memory CRITICAL - $fmt_pct% ($free_memory kB) free | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'CRITICAL'}; 
} 
elsif ($percent <= $warn_level) 
{ 
print "Memory WARNING - $fmt_pct% ($free_memory kB) free | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'WARNING'}; 
} 
else 
{ 
print "Memory OK - $fmt_pct% ($free_memory kB) free | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'OK'}; 
} 
} 
elsif ($opt_u) 
{ 
$percent = $used_memory / $total_memory * 100; 
$fmt_pct = sprintf "%.1f", $percent; 
if ($percent >= $crit_level) 
{ 
print "Memory CRITICAL - $fmt_pct% ($used_memory kB) used | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'CRITICAL'}; 
} 
elsif ($percent >= $warn_level) 
{ 
print "Memory WARNING - $fmt_pct% ($used_memory kB) used | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'WARNING'}; 
} 
else 
{ 
print "Memory OK - $fmt_pct% ($used_memory kB) used | total=$total_memory, used=$used_memory, free=$free_memory"; 
exit $exit_codes{'OK'}; 
} 
}

Kan iemand me vertellen wat ik fout doe in dit script, en hoe ik dat op zou kunnen lossen?

[ Voor 8% gewijzigd door Nitroglycerine op 08-12-2004 11:50 ]

Hier kon uw advertentie staan


  • farlane
  • Registratie: Maart 2000
  • Laatst online: 17-05 17:19
Mijn gok is dattie $3 $4 ziet als variabelen die hij niet heeft. Misschien moet je die escapen?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


  • Nitroglycerine
  • Registratie: Januari 2002
  • Laatst online: 23:05

Nitroglycerine

Autisme: belemmering en kracht

Topicstarter
farlane schreef op woensdag 08 december 2004 @ 12:03:
Mijn gok is dattie $3 $4 ziet als variabelen die hij niet heeft. Misschien moet je die escapen?
Dat zijn toch commandovariabelen van awk? Ik heb trouwens begrepen dat perl binnen de enkel quotes niet aan substitutie doet, of heb ik het nu mis?
edit: You are a genious and I am incredible dumb (of gewoon geen ervaring met perl....... wat zal het zijn)

Het werkt! Bedankt!

[ Voor 18% gewijzigd door Nitroglycerine op 08-12-2004 12:12 ]

Hier kon uw advertentie staan


Verwijderd

Je hebt gelijk dat perl normaal gesproken tussen enkele quotes niet aan parameter substitutie doen, maar ik denk dat jou unix commando dit verandert.
Misschien een bug. :)

  • Onno
  • Registratie: Juni 1999
  • Niet online
Verwijderd schreef op woensdag 08 december 2004 @ 12:14:
Je hebt gelijk dat perl normaal gesproken tussen enkele quotes niet aan parameter substitutie doen, maar ik denk dat jou unix commando dit verandert.
Misschien een bug. :)
Dit zijn geen enkele quotes maar backticks, en daar gebeurt het wel. En niet alleen in perl trouwens. :)

Verwijderd

Onno schreef op woensdag 08 december 2004 @ 12:17:
[...]

Dit zijn geen enkele quotes maar backticks, en daar gebeurt het wel. En niet alleen in perl trouwens. :)
Ik bedoel wel de "quotes" in het awk commando niet daarom omheen.
Ik begrijp hieruit dat ` = backtick en ' = enkele quote !!!

  • Onno
  • Registratie: Juni 1999
  • Niet online
Quotes binnen quotes zijn niet relevant, dat is gewoon tekst. Anders zou $a = "bla ' bla $variabele '" ook niet meer werken. En wat te denken van $a = "bla ' bla", zou ie dan een fout moeten geven over niet juist geneste quotes? :Y)

Verwijderd

nog een mooie truuk om output te lezen van een commando:
Perl:
1
2
3
4
5
6
7
8
$cmd = "uw command hier";
open(CMD, "$cmd |") or die "Kan pipe van $cmd niet openen: $!\n";
while (<CMD>) {
 # de gelezen line komt in $_
 # de loop stopt als $cmd stopt
 print $_;
} 
close(CMD); 

deze heb ik heel vaak gebruikt in mijn vorig leven als AIX sys-admin
voordeel van deze manier is dat je de regels 1 voor 1 leest
ipv alles in 1 keer in een var te slurpen.
kan erg fijn zijn als je logfiles van 100-erden MBs moet doorvlooien

en voor de volledigheid ff ook de andere kant op
Perl:
1
2
3
4
$cmd = "uw commando hier";
open (CMD, "| $cmd") or die "Kan pipe naar $cmd niet openen: $!\n";
print CMD "uw uitvoer naar $cmd hier";
close(CMD); 


@TS
als je snel perl onder de knie wilt krijgen (schrijven bedoel ik, niet lezen) in dit boek zijn enorm veel oplossingen te vinden die mij erg veel geholpen hebben.

[ Voor 29% gewijzigd door Verwijderd op 08-12-2004 19:01 ]


  • windancer
  • Registratie: Maart 2000
  • Laatst online: 15:12
Als je toch in perl bezig bent zou ik persoonlijk het gebruik van tail en awk er ook progarmmeren, dan ben je ook niet meer afhankelijk van deze commandos.
Nitroglycerine schreef op woensdag 08 december 2004 @ 11:49:
Ik ben bezig om op een AIX machine een perl script werkend te krijgen. De bedoeling van het script is dat het het vrije virtuele geheugen opvraagd (met het commando vmstat), de laatste regel van de output neemt (middels tail -1) en daar de 3e en 4e waarde uit neemt (met awk '{print $3 $4}' ).
Pagina: 1