Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]7938[/thread]

Assoziative Arrays...: Problem mit dem automatischen Erstellen



<< >> 9 Einträge, 1 Seite
nikster77
 2006-05-02 20:14
#65520 #65520
User since
2006-02-08
26 Artikel
BenutzerIn
[default_avatar]
Hallo zusammen.

Ich habe ein Problem mit assoziativen Arrays, denen wuerde ich naemlich gerne automatisch pro Schluessel zwei Werte zuweisen...

Also folgendes, ich versuche ein Skript zu schreiben, das meine Softraid1 Arrays monitored und zwar nach Moeglichkeit so, das ich nicht auf feste Werte beschraenkt bin sondern das Programm sich alles "von selbst" aus den Configs liest:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/perl

$raidtab = "/etc/raidtab";

## /etc/raidtab oeffnen und devices in temporaeres Array schreiben
open(RAIDTAB, $raidtab) || die "Unable to read from /etc/raidtab : $!";
while(<RAIDTAB>)
{
foreach $device (split(/ |raiddev|device/,$_)) {
#print $device;
if ($device =~ m/\/dev\//ig) {
push (@raid_tab, "$device");
}
}
}
close (RAIDTAB);

##raiddevices(md0, etc.) in eigenes Array schreiben (das koennte man wahrscheinlich im ersten Block bereits handlen...)
foreach $raiddev (@raid_tab) {
if ($raiddev =~ m/md/ig) {
push (@raids, "$raiddev");
}
}


Ich habe also bis hierhin ein eigenes Array mit den md's...
Diesen wuerde ich nun gerne jeweils die zwei folgenden (aus dem ersten Array) Devices zuordnen (damit ich spaeter bei z.B.: panic - md1 gleich automatisch die entsprechenden Platten checken lassen kann)

Bei einem Hash-Array mit nur "Schluessel/Wert" waere das auch nicht so schwer, ich koennte das erste Array einfach dafuer nehmen und als Hasharray "deklarieren" aber mit zwei Schluesseln bin ich irgendwie ueberfordert (wenn ich es automatisch machen will..)

Zur Info eine Beispiel-Raidtab:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
raiddev /dev/md0
raid-level 1
nr-raid-disks 2
nr-spare-disks 0
persistent-superblock 1
chunk-size 4
device /dev/hdc1
raid-disk 0
device /dev/hdd1
raid-disk 1

raiddev /dev/md1
raid-level 1
nr-raid-disks 2
nr-spare-disks 0
persistent-superblock 1
chunk-size 4
device /dev/hdc2
raid-disk 0
device /dev/hdd2
raid-disk 1


Es waere schoen wenn da jemand einen Rat fuer mich haette.

Gruesse

Niels
renee
 2006-05-02 22:57
#65521 #65521
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Wie gefällt Dir:
Code: (dl )
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
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;

my $raidtab = "./raidtab.txt";
my %info;

{
my $mnt;
local $/ = "\n\n";
open(my $fh,"<",$raidtab) or die $!;
while(my $entry = <$fh>){
my ($device,@infos) = split(/\r?\n/,$entry);
print $device;
($device) = $device =~ m~(/dev/.*?)$~;
chomp(@infos);
for my $detail(@infos){
my (undef,$key,$value) = split(/\s+/,$detail);
if($key eq 'device'){
$mnt = $value;
}
elsif($key eq 'raid-disk'){
$info{$device}->{devices}->{$mnt} = $value;
}
else{
$info{$device}->{$key} = $value;
}
}
}
close $fh;
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
nikster77
 2006-05-02 23:46
#65522 #65522
User since
2006-02-08
26 Artikel
BenutzerIn
[default_avatar]
Hmm... ja, das ist auch ganz gut, vor allem wie schnell das bei dir ging :>
(Ich bin schlecht..., Ich bin schlecht..., einfach schlecht in Perl.)

Aber leider gibt mir print @info; folgendes aus:
# autogenerated /etc/raidtab by YaST2raiddev /dev/md0raiddev /dev/md1raiddev /dev/md2raiddev /dev/md3raiddev /dev/md4

es sind zwar, wie es scheint, die schluessel richtig, nicht aber die werte dahinter, leider verstehe ich noch nicht ganz was das Programm tut, doch es ist (fuer den Wissenden) sicherlich leicht abzuaendern.
Danke auf jeden Fall schonmal fuer die Hilfe, das bringt mich bestimmt ein grosses Stueck weiter wenn ich etwas darueber "meditiert" habe :)

Waehrend ich auf deine (sehr schnelle) Antwort gewartet habe, habe ich einen neuen Ansatz versucht und es waere nett wenn du den vielleicht auch nocheinmal anschauen koenntest.

Code: (dl )
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
#!/usr/bin/perl

$raidtab = "/etc/raidtab";

## /etc/raidtab oeffnen und devices in temporaeres Array schreiben
open(RAIDTAB, $raidtab) || die "Unable to read from /etc/raidtab : $!";
while(<RAIDTAB>)
{
foreach $device (split(/ |raiddev|device/,$_)) {
#print $device;
if ($device =~ m/dev\/md/ig) {
push (@md_s, "$device");
}
elsif ($device =~ m/dev\/[a-z]d[a-z][0-9]/ig) {
push (@disks, "$device"); }
}
}
close (RAIDTAB);

#print @md_s; #Debug
#print @disks; #Debug

$how_many_disks_do_we_have_here = $#disks;
#print "\n$how_many_disks_do_we_have_here\n"; #Debug

for ($i=0; $i <= $how_many_disks_do_we_have_here; $i++) {
$o = $i + 2;
$temp = $disks[$i];
if ($o/2==true) {
push (@related_disks[$o], $temp, $disks[$o]);
}
}


Wie du siehst, habe ich hier das File bereits am Anfang in zwei Arrays gesplittet die auch beide genau das liefern was ich brauche:
@md_s liefert die /dev/md's
@disks liefert die platten /dev/(h|s)d[a-z]

Mein Gedanke war es jetzt beide Arrays mittels einer Schleife zu Verknuepfen und erstmal jeweils zwei Elemente aus @disks in ein eigenes Array zu kopieren.
Diese Arrays haette ich dann in @md_s referenziert.
Ungefaehr so:
@xy=($md_s[0], \@related_disks[1], usw.)

So haette ich in /proc/mdstat immer nach mdX greppen koennen und wenn etwas nicht gestimmt haette sagen koennen:

if $md_s[0] nicht OK
foreach $xy (@related_disks[1])
rebuild array (Z.B)
done;

Leider kommt perl anscheinend mit dem true nicht zurecht, ich habe auch noch kein Beispiel mit "true" gesehen...
Ausserdem passt es ihm nicht, das ich das Array in der Schleife "referenziere" (@related_disks[$o],...).
Weisst du vielleicht warum das so ist? Oder ob es bei Perl tatsaechlich kein true gibt?

Aber bis dahin habe ich die Funktionsweise deines Programms bestimmt auch schon besser verstanden.

Vielen Dank

Niels
Dubu
 2006-05-03 00:35
#65523 #65523
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Ein "print @info" bringt dich nicht weiter, da es kein Array @info in renees Code gibt. Die Ausgabe, die du gesehen hast, ist die Debugausgabe ("print $device").

Setze die folgenden Zeilen hinter renees Code, dann kannst du sehen, wie die Informationen abgelegt werden:
Code: (dl )
1
2
3
# ...
use Data::Dumper;
print Dumper \%info;
Dubu
 2006-05-03 00:42
#65524 #65524
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Und nein, Perl kennt kein "true".

Aus perlsyn:
Quote
      Truth and Falsehood

      The number 0, the strings '0' and '', the empty list "()", and "undef" are all false in a boolean context. All other values are true.  Negation of a true
      value by "!" or "not" returns a special false value.  When evaluated as a string it is treated as '', but as a number, it is treated as 0.


Und ein "$o/2" ist für alle $o außer Null wahr. Vielleicht meintest du "$o % 2"? Aber der Code ist mir ohnehin nicht so ganz klar.

So oder so fände ich es (auch in C/C++/Java/...) sinnvoller, das Ergebnis einer (integer)arithmetischen Operation mit 0 oder 1 zu vergleichen, als mit einem Wahrheitswert.
nikster77
 2006-05-03 00:46
#65525 #65525
User since
2006-02-08
26 Artikel
BenutzerIn
[default_avatar]
Ah... OK!
Das gibt soetwas:

'/dev/md0' => {
'chunk-size' => '4',
'persistent-superblock' => '1',
'raid-level' => '1',
'nr-spare-disks' => '0',
'nr-raid-disks' => '2',
'devices' => {
'/dev/hdc1' => '0',
'/dev/hdd1' => '1'
}
}
Nur um zu sehen ob ich das richtig verstanden habe:
/dev/md0 ist jetzt der Schluessel fuer:
'chunk-size' => '4',
'persistent-superblock' => '1',
'raid-level' => '1',
'nr-spare-disks' => '0',
'nr-raid-disks' => '2',
'devices' => {
'/dev/hdc1' => '0',
'/dev/hdd1' => '1'

und devices der Schluessel fuer:
'/dev/hdc1' => '0',
'/dev/hdd1' => '1'

Waehrend /dev/hdc1 wiederum der Schluessel fuer '0' ist?

Das ist noch komplizierter als ich angenommen hatte... ;)

Danke euch beiden!

Niels
Dubu
 2006-05-03 01:17
#65526 #65526
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
Correctamente. 8)
nikster77
 2006-05-03 01:20
#65527 #65527
User since
2006-02-08
26 Artikel
BenutzerIn
[default_avatar]
Hallo.

Quote
Und nein, Perl kennt kein "true".


Ja. Hab's jetzt auch rausgefunden...

Und, ja... der Code ist verwirrend aber ich wusste nicht wie ich perl sagen sollte:
kopiere jeweils zwei Werte von arrayX hinter den ersten Wert von ArrayY.
Aber ich denke jetzt wo ich Renes Code besser verstehe muss das auch nicht mehr unbedingt sein... bzw. das Herausfinden kann auf spaeter verschoben werden.
(Wie leider fast alles was ich ueber perl lernen will...)

Danke, Ihr habt mir sehr geholfen.

Niels
Strat
 2006-05-03 21:02
#65528 #65528
User since
2003-08-04
5246 Artikel
ModeratorIn
[Homepage] [default_avatar]
doch, kennt perl schon, z.B.
Code: (dl )
1
2
use constant TRUE => 1;
use constant FALSE => 0;

oder besser mit CPAN:Readonly
Code: (dl )
1
2
use Readonly our $True => 1;
use Readonly our $False => 0;
\n\n

<!--EDIT|Strat|1146675767-->
perl -le "s::*erlco'unaty.'.dk':e,y;*kn:ai;penmic;;print"
http://www.fabiani.net/
<< >> 9 Einträge, 1 Seite



View all threads created 2006-05-02 20:14.