Zum Inhalt springen

PERL: Variable in Array-Name


Empfohlene Beiträge

Hallo Com.

Ich hab mal wieder ein kleines Problem, das ich mit diverser Fachliteratur ohne Anhaltspunkt nicht loesen kann.

Vielleicht koennt ihr mir helfen?!

Eine Subroutine in meinem Script sieht wie folgt aus:


    79  sub se_output {

    80

    81     #AUsgabe aller PODs einer SE

    82

    83     my $msc="$_[0]";

    84     open(PODTREE, "/XXX/report/seclist_podtree")

    85        or die "ERROR: seclist_podtree nicht gefunden. DO: seclist -update";

    86     my @podtree=<PODTREE>;

    87     close(PODTREE);

    88     my @setree=grep /$msc/,@podtree;

    89     my $zaehler=1;

    90     foreach my $i (@setree) {

    91        my @{"splitted$zaehler"} = split(/:/,$i);

    92        $zaehler++;

    93     }

    94     for (my $s=1;$s <= $zaehler;$s++)

    95     {

    96        print "\n   Datenfiles ($msc): /YYY/${"splitted$s\[2\]"}\n";

    97        for (my $zz=1;$zz<=$termsz;$zz++) {

    98           print "*";

    99        }

   100        qx(rsh priv$msc -l f223 "/XXX/scripts/seclist_ext ${"splitted$s\[2\]"} $msc");

   101        open(DPOUT,"/XXXreport/seclist_$msc\_${"splitted$s\[2\]"}\_tmp");

   102        while(defined(my $i = <DPOUT>)) {

   103           print $i;

   104        }

   105        close(DPOUT);

   106        unlink("/XXX/report/seclist_$msc\_${"splitted$s\[2\]"}\_tmp");

   107        for (my $zz=1;$zz<=$termsz;$zz++) {

   108           print "*";

   109        }

   110     }

   111  }

   112

   113

   114

   115  sub create_sfrtree {

   116

   117     #Quelltext zur Erstellung eines

Fuer die Routine ist noch kein Aufrufszenario im Hauptteil des Skripts programmiert. Es existiert bisther nur die Methodendefinition. Wenn ich das Skript jetzt aufrufe schaut sich ja der Compiler den ganzen Quelltext an und findet in dieser Routine diverse Fehler:

<HOSTNAME>:-::/XXX/scripts > seclist

Bareword found where operator expected at seclist line 114, near ""/XXX/report/seclist_$msc\_${"splitted"

        (Missing operator before splitted?)

Backslash found where operator expected at seclist line 114, near "$s\"

        (Missing operator before \?)

Backslash found where operator expected at seclist line 114, near "2\"

        (Missing operator before \?)

String found where operator expected at seclist line 114, near "]"}\_tmp""

        (Missing operator before "}\_tmp"?)

Bareword found where operator expected at seclist line 105, near ""/XXX/report/seclist_$msc\_${"splitted"

        (Missing operator before splitted?)

Backslash found where operator expected at seclist line 105, near "$s\"

        (Missing operator before \?)

Backslash found where operator expected at seclist line 105, near "2\"

        (Missing operator before \?)

String found where operator expected at seclist line 105, near "]"}\_tmp""

        (Missing operator before "}\_tmp"?)

Global symbol "$termsz" requires explicit package name at seclist line 97.

Global symbol "$termsz" requires explicit package name at seclist line 115.

syntax error at seclist line 114, near ""/XXX/report/seclist_$msc\_${"splitted"

syntax error at seclist line 105, near ""/XXX/report/seclist_$msc\_${"splitted"

Execution of seclist aborted due to compilation errors.

Der Fehler mit $termsz ist mir klar, da fehlt die Variablendefinition. Also:

my $termsz=qx(/usr/bin/tput cols);

Aber was mache ich bei Definition/Aufruf der Arrays mit einer fortlaufenden Variable im Namen falsch?

Und: Fehler in Zeile 114. Die Zeile ist leer?!?!

Danke im Vorraus && Gruss

starbuck

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

grenze doch mal den Fehler ein. Wie debuggst du normalerweise? Schreibst du 500 Zeilen und überprüfst dann ob es geht oder nicht? Ich glaub nicht, dass dir hier jemand den ganzen Wust debuggt.

Ausserdem ist die Linien-Angabe nur ein Anhaltspunkt. Wenn du irgendwo ne Klammer vergessen hast zu öffnen, dann kann das auch irgendwo in einer anderen Zeile sein.

ciao,

vic

Link zu diesem Kommentar
Auf anderen Seiten teilen

Steht doch alles dort? Der Fehler ist in dieser Zeile:

unlink("/XXX/report/seclist_$msc\_${"splitted$s\[2\]"}\_tmp");

Du kannst "${"..."}" nicht interpolieren lassen. Mal abgesehen davon, dass du vielleicht im ganzen Quellcode deine Anfuehrungszeichen solltest, um das ganze halbwegs lesbar zu machen, vermute ich, dass sich das Problem loesen laesst, wenn du im Dateinamen nur dort Anfuehrungszeichen verwendest wo sie gebraucht werden. Die einzelnen Teile des Strings kannst du per . zusammenfuegen.

mfg

Unix

Link zu diesem Kommentar
Auf anderen Seiten teilen

Hi,

grenze doch mal den Fehler ein. Wie debuggst du normalerweise? Schreibst du 500 Zeilen und überprüfst dann ob es geht oder nicht? Ich glaub nicht, dass dir hier jemand den ganzen Wust debuggt.

Ausserdem ist die Linien-Angabe nur ein Anhaltspunkt. Wenn du irgendwo ne Klammer vergessen hast zu öffnen, dann kann das auch irgendwo in einer anderen Zeile sein.

ciao,

vic

Vic Deine Antwort war jetzt echt fürn A****, hat mich ehrlich gesagt 0 weitergebracht.

Natürlich soll mir das hier keiner debuggen, ich will ja selbst wissen was ich falsch gemacht habe. Das steht da nur alles um den Context zu haben.

Zum Thema Fehler eingrenzen.

Der Fehler liegt in dieser Routine. Wenn ich se_output auskommentiere läuft das Skript einwandfrei. Also ist es wohl dieser Bereich, der nicht so ganz will.

Hauptsächlich ging es mir um diese Fragestellung:

Aber was mache ich bei Definition/Aufruf der Arrays mit einer fortlaufenden Variable im Namen falsch?

Ich werds jetzt mal über die String-Verbindung mit dem . probieren. Allerdings ist mir die GENAUE Syntax nicht so klar, deswegen frage ich ja hier nach. sh. Zitat.

Ich meine klar:

$a="Hal";

$b="lo";

$hallo=$a.$b;

Aber es handelt sich hier ja um den Spezialfall, dass das $hallo, dann kein String ist, den ich einfach nur ausgeben will, sondern der Name eines Arrays.

Bearbeitet von starbuck86
Link zu diesem Kommentar
Auf anderen Seiten teilen

Vic Deine Antwort war jetzt echt fürn A****, hat mich ehrlich gesagt 0 weitergebracht.

Ruhig Blut. Hilfe ist ein Privileg, kein Recht. Ich bin mir sicher, dass die Anmerkung von victorinox wahr und konstruktiv ist.

Aber es handelt sich hier ja um den Spezialfall, dass das $hallo, dann kein String ist, den ich einfach nur ausgeben will, sondern der Name eines Arrays.

Ehrlich gesagt kann (oder will) ich deinen Code nicht nachvollziehen. Du versuchst auf sehr kryptische Weise irgendwie die Datei "/XXX/report/seclist_irgendwas_irgendwas_tmp" zu loeschen oder? Wo ist denn da der Name eines Arrays? Willst du etwa mehrere Dateien auf einmal loeschen? Dann mach das lieber per map { "/XXX/undsoweiter" . $_ } @deinarray; Falls nicht, dann noch folgender Gedanke:

"/XXX/report/seclist_$msc\_${"splitted$s\[2\]"}\_tmp" - Ist so unleserlich, dass weder du noch ich es wieder hinkriegen. Mir fallen da sofort einige sachen ins Auge:

"/XXX/report/seclist_$msc\_${"splitted$s\[2\]"}\_tmp"

Sicher dass der Backslash an der richtigen Stelle ist?

Spaetestens an dieser Stellte braeuchtest du einen . um die Strings miteinander zu verbinden, wenn ich mir auch nicht sicher bin was du hier vorhast.

Hoffe, dass ich weiterhelfen konnte.

Unix

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ruhig Blut. Hilfe ist ein Privileg, kein Recht. Ich bin mir sicher, dass die Anmerkung von victorinox wahr und konstruktiv ist.

Sorry, die Sache mit dem Skript bringt mich etwas aus der Fassung, weil ichs nicht hinbekomme..

Das ganze ist so unübersichtlich, da es mein 1. Perl-Skript ist und ungeplante Dimensionen angenommen hat. Ich habe noch nicht die Erfahrung um Übersicht reinzubringen, weil für mich alles Neuland ist.

Backslash ist an der richtigen Stelle. Der Name des Files lautet zB:

seclist_se617_sfr2P01_tmp

seclist_$msc_$pod_tmp

"/XXX/report/seclist_" . $msc . "_" . ${"splitted" . $s . "[2]"} . "_tmp"

Ich habe da so ein Gefühl, dass der Fehler in der Definition des Arraynamen liegt.

Also sagen wirs mal so: Ich hab unbestimmt viele 2D-Arrays und will über eine Schleife immer das 2. Element jedes Arrays abfragen. Das wäre von der Logik was hinter diesem "Wust" stecken soll.

Nehmen wir an die laufende Variable ist $i. $i ist 1..3.

Jetzt hab ich die Arrays:

@array$i

@array1

@array2

@array3

und will davon immer das zweite Element und die Arrays heissen bei mir "splitted"

$splitted$i[2]

Aber so geht das ja nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

"/XXX/report/seclist_" . $msc . "_" . ${"splitted" . $s . "[2]"} . "_tmp"

Ich denke, ich verstehe was du vorhast und das wird so nicht funktionieren. Bereits in der Zeile 91 muesstest du einen Fehler bekommen. Ruf doch mal bitte perl -d deinscript.pl auf. Mit n oder s kannst du das ganze Schrittweise aufrufen. Wenn das Script an einem Fehler vorbeikommt, wird es dir Bescheid sagen.

Also sagen wirs mal so: Ich hab unbestimmt viele 2D-Arrays und will über eine Schleife immer das 2. Element jedes Arrays abfragen. Das wäre von der Logik was hinter diesem "Wust" stecken soll.

Also beim besten Willen... Sowas macht man nicht. Dadurch entstehen naemlich genau solche Probleme. Bau dir lieber ein Array auf und fuelle es mit Arrayreferenzen. Das ganze funktioniert etwa so:

my @array;

for (1..10) {

  push @array, [ "erster wert", "zweiter wert" ];

}


foreach my $ref (@array) {

  print $ref->[1] # oder $ref->[2]

}

Eine Einfuehrung in Referenzen findest du unter perlreftut und perlref. Noch sieht dein Programm recht klein aus. Wenn du es jetzt aenderst, ersparst du dir viel Sorgen in der Zukunft.

mfg

Unix

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ok. Hat geholfen. Danke!

Jetzt noch eine letzte Frage:

Wenn ich den Perl Debugger laufen lasse mit "perl -d seclist se617" bringt er mir ne Meldung gleich für die erste Zeile in meinem Skript nach "use strict;".

Da habe ich geschrieben:

my $argvlaenge = @ARGV;
Ich will die Anzahl der Argumente einem skalaren Kontext übergeben. Geht das nicht so einfach? Danach kommt eine Folgemeldung, wo ich in einer if-Schleife die Anzahl abfrage mit:
if($argvlaenge == 1)

Wie geht dieser Debugger vor, oder was will er mir damit sagen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was sagt er dir denn? ;)

Er sagt eigentlich gar nix. Er gibt mir nur diese erste Zeile aus:


perl -d seclist se617

Default die handler restored.


Loading DB routines from perl... 1.07

Editor support available.


Enter h for help..


main::(seclist:9):   my $argvlaenge = @ARGV;

Aber er schreibt keine Fehlermeldung dazu. Es kommt einfach nur diese Meldung. Was will er mir damit sagen?

Ist da ein Fehler in der Zeile?

Link zu diesem Kommentar
Auf anderen Seiten teilen


perl -d seclist se617

Default die handler restored.


Loading DB routines from perl... 1.07

Editor support available.


Enter h for help..


main::(seclist:9):   my $argvlaenge = @ARGV;

Nein, du solltest mal h druecken. Dann siehst du die Hilfe - oder man perldebug lesen. Mit den Tasten n oder s laesst du den Code ausfuehren und springst eine Zeile weiter.

perl -d schaut nicht nach Fehlern, sondern geht den Quellcode Stueck fuer Stueck durch. Trifft es dann auf einen Laufzeitfehler, dann weisst du genau in welchen Zeilen er sich befindet.

Um die letzte Zeile etwas zu erlaeutern:

Du befindest dich im Defaultpackage 'main' der Datei 'seclist', Zeile 9. Der Code, der als naechstes Ausgefuehrt wird ist my $argvlaenge = @ARGV;

Drueckst du nun 'n', wird dieser Code ausgefuehrt. Drueckst du 's', dann geschieht das gleiche. Wuerde dort aber eine Subroutine stehen, dann wuerdest du mit 's' in die Subroutine springen. Der Perl Debugger ist ein maechtiges Werkzeug. Du solltest nicht erwarten, dass er sich von alleine erklaert.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...