kein DBM close nach untie ?
Alain
- perl
Hallo,
ich habe eine frage bezüglich close (DBM);
ist es neigentlich nicht mehr notwendig eine DB datei zu schliessen nachdem untie?
Mein unix server meldet einen close fehler.
der anfang sieht so aus
use DB_File;
my %logins;
my $db = tie %logins , "DB_File", "$loginlog", O_RDWR|O_CREAT, 0644;
my $fd = $db->fd;
open (DBM, "+<&=$fd");
flock (DBM, LOCK_EX);
es passiert was...
der schluss sieht so aus
undef $db;
untie %logins;
close (DBM) or die "cant close $!";
der server meint
cant close Bad file descriptor at test.cgi line...
Grüsse vom
Alain
Hallo,
untie %logins;
fertisch;
close (DBM) or die "cant close $!";
brauchschd net ;-)
der server meint
cant close Bad file descriptor at test.cgi line...
ähh...
Viele Grüße, Rolf
Hallo Alain
Hallo,
ich habe eine frage bezüglich close (DBM);
ist es neigentlich nicht mehr notwendig eine DB datei zu schliessen nachdem untie?
Mein unix server meldet einen close fehler.
der anfang sieht so aus
use DB_File;
my %logins;
my $db = tie %logins , "DB_File", "$loginlog", O_RDWR|O_CREAT, 0644;
my $fd = $db->fd;
open (DBM, "+<&=$fd");
flock (DBM, LOCK_EX);es passiert was...
der schluss sieht so aus
undef $db;
untie %logins;
close (DBM) or die "cant close $!";
Du solltest die Reihenfolge beachten.
Mit untie löst du auch die Verbindung zu $db->fd.
also erst close und dann untie.
Struppi.
Hallo Struppi,
untie %logins;
close (DBM) or die "cant close $!";Du solltest die Reihenfolge beachten.
Mit untie löst du auch die Verbindung zu $db->fd.also erst close und dann untie.
ok danke,
aber auch wenn ich close vor untie nehme kommt ein error wie vorhin beschrieben.
ich hab mir schon paar beispiele angeguckt über die such maschiene und habe mit ausnahmen keine
close funktionen nach oder vor untie gesehen wie hier http://www.hk8.org/old_web/linux/cgi/ch10_02.htm zum Beispiel.
Grüsse vom
Alain
ok danke,
aber auch wenn ich close vor untie nehme kommt ein error wie vorhin beschrieben.
ich hab mir schon paar beispiele angeguckt über die such maschiene und habe mit ausnahmen keine
close funktionen nach oder vor untie gesehen wie hier http://www.hk8.org/old_web/linux/cgi/ch10_02.htm zum Beispiel.
Ich benutze schon länger kein DB_File mehr. Aber in meinem altem code ist zuerst das close und dann das untie. Das close ist aber nicht notwendig und wenn du wie in dem Beispiel den Handle $db löscht, geht es nicht mehr.
Struppi.
hi ihr beiden,
aber auch wenn ich close vor untie nehme kommt ein error wie vorhin beschrieben.
ich hab mir schon paar beispiele angeguckt über die such maschiene und habe mit ausnahmen keine
close funktionen nach oder vor untie gesehen wie hier http://www.hk8.org/old_web/linux/cgi/ch10_02.htm zum Beispiel.
wenn ich close vor untie und vor undef setze dann sagt der server
undef problem (Inappropriate ioctl for device)
undef und untie muss man doch nach bzw. an den schluss hängen oder?
Ich benutze schon länger kein DB_File mehr. Aber in meinem altem code ist zuerst das close und dann das untie. Das close ist aber nicht notwendig und wenn du wie in dem Beispiel den Handle $db löscht, geht es nicht mehr.
was benutzt Du denn?Was ist den modern?
Gibts wo ein Beispiel?
Jetzt gehts bei mir aber ich benutze kein close mehr aber dazu noch use strict;
Grüsse vom Alain
wenn ich close vor untie und vor undef setze dann sagt der server
undef problem (Inappropriate ioctl for device)undef und untie muss man doch nach bzw. an den schluss hängen oder?
Das undef bezog sich auf den Handle von tie nicht auf das Hash.
Ich benutze schon länger kein DB_File mehr. Aber in meinem altem code ist zuerst das close und dann das untie. Das close ist aber nicht notwendig und wenn du wie in dem Beispiel den Handle $db löscht, geht es nicht mehr.
was benutzt Du denn?Was ist den modern?
Ob's modern ist, weiß ich nicht, aber kostenlos und weit verbreitet: mySql
Struppi.
hi Struppi,
noch so spät auf ? ;-)
wenn ich close vor untie und vor undef setze dann sagt der server
undef problem (Inappropriate ioctl for device)Das undef bezog sich auf den Handle von tie nicht auf das Hash.
sollte es denn auf das handle Hash beziehen?
Sorry,wenn ich so bl...frage aber das mit undef
ist mir etwas zu hoch.Tie und untie hab ich etwas kapiert,was so gut heisst wie öffnen und schliessen,
aber wofür undef gut sein soll check ich nicht.
was benutzt Du denn?Was ist den modern?
Ob's modern ist, weiß ich nicht, aber kostenlos und weit verbreitet: mySql
Das kann ich nicht in diesem fall muss ich das perl script nehmen.
Gruss
Alain
noch so spät auf ? ;-)
War noch 'ne Runde am zocken und da vergeht die zeit.
wenn ich close vor untie und vor undef setze dann sagt der server
undef problem (Inappropriate ioctl for device)Das undef bezog sich auf den Handle von tie nicht auf das Hash.
sollte es denn auf das handle Hash beziehen?
Sorry,wenn ich so bl...frage aber das mit undef
ist mir etwas zu hoch.Tie und untie hab ich etwas kapiert,was so gut heisst wie öffnen und schliessen,
aber wofür undef gut sein soll check ich nicht.
Naja, du hast mir doch den Link gezeigt. http://www.hk8.org/old_web/linux/cgi/ch10_02.htm und da steht im absatz 10.2.1:
my $db = tie %hash, "DB_File", $dbm_file, O_CREAT | O_RDWR, 0644 or
die "Could not tie to $dbm_file: $!";
my $fd = $db->fd; # Get file descriptor
open DBM, "+<&=$fd" or die "Could not dup DBM for lock: $!"; # Get dup filehandle
flock DBM, LOCK_EX; # Lock exclusively
undef $db; # Avoid untie probs
..# All your code goes here; treat %hash like a normal, basic hash..untie %hash
Ein Trick scheint zu sein die Zeile mit dem undef $db;
Das ganze ist ja nur notwendig weil DB_File angeblich die Daten nicht locked. Ich meine mich aber zu erinnern das es neuere Versionen tun (such mal), damit wäre das ganze (mit ->fd und open DBM) überflüssig.
Struppi.
hi struppi,
Das ganze ist ja nur notwendig weil DB_File angeblich die Daten nicht locked. Ich meine mich aber zu erinnern das es neuere Versionen tun (such mal), damit wäre das ganze (mit ->fd und open DBM) überflüssig.
na gut,
aber ich hab den fehler nun gefunden,wesshalb das script nur halbhalb lief.
Und zwar wars ander der falschen anweisung am anfang des scripts:
fehler war folgend:
while (<DBM>){
if (!/$username/){
$dbfile{$username} = "20*0*$date_today";#wenn der username nicht drinn steht,schreibe folgende zeile.
}
}
anstatt
until (<DBM>){
if (!/$username/){
$dbfile{$username} = "20*0*$date_today";
}
}
ich habe durch suchen von DBM etc. zufällig bei http://www.rrz.uni-hamburg.de/wwwtrost/KURS/perlbase.html
den hinweis von while und until gelesen.
Mit while ging plötzlich gar nix mehr,am anfang schon.
Gruss
Alain
aber ich hab den fehler nun gefunden,wesshalb das script nur halbhalb lief.
Und zwar wars ander der falschen anweisung am anfang des scripts:
fehler war folgend:
while (<DBM>){
Wieso das denn?
Du brauchst und hast, wenn du mit DB_File arbeitest keinen Filehandle.
Wenn du alle Einträge durchlaufen möchtest musst du die keys abfragen.
foreach(keys %hash)
{
.....
}
Das ist ja gerade das nette an dieser Datenbank, du brauchst keinerlei Fileoperationen mehr sondern du kannst einfach auf den HASH zugreifen und es wird automatisch geändeert, gespeichert oder gelöscht.
Das wird auch auf dieser Seite so gezeigt, dieses while (<>) bezieht sich auf STDIN d.h. du kannst in den Beispiel mit der tastatur Daten eingeben.
Struppi.
hi Struppi,
while (<DBM>){
Wieso das denn?
Du brauchst und hast, wenn du mit DB_File arbeitest keinen Filehandle.
Wenn du alle Einträge durchlaufen möchtest musst du die keys abfragen.foreach(keys %hash)
{
.....}
ich will nicht in jedem key was ändern.Er soll sämtliche user loggen und wenn ein neuer kommt dann soll er das auch eintragen,wenn er nicht exitstiert in der DBM datei.
Nur im Moment kann ich die logdatei nicht ansehen da ich mit einer schleife ein dauer lauf bewirkt habe,welche meine error log auf über 700MB anstiegen liess ;-)
Musste den apache neu starten.
Das ist ja gerade das nette an dieser Datenbank, du brauchst keinerlei Fileoperationen mehr sondern du kannst einfach auf den HASH zugreifen und es wird automatisch geändeert, gespeichert oder gelöscht.
wenn ich es so brauchen würde?
Das wird auch auf dieser Seite so gezeigt, dieses while (<>) bezieht sich auf STDIN d.h. du kannst in den Beispiel mit der tastatur Daten eingeben.
Nun jetzt hab ich es doch wieder rückgängig gemacht etwas anders
while (<DBM>){
$dbfile{$username} = "20*0*$date_today" unless (/$username/);
}
Gruss
Alain
Du brauchst und hast, wenn du mit DB_File arbeitest keinen Filehandle.
Wenn du alle Einträge durchlaufen möchtest musst du die keys abfragen.foreach(keys %hash)
{
.....}
ich will nicht in jedem key was ändern.Er soll sämtliche user loggen und wenn ein neuer kommt dann soll er das auch eintragen,wenn er nicht exitstiert in der DBM datei.
Du gibst mir Rätsel auf. Du benutzt doch DB_File, oder?
Da passiert das was du willst von ganz alleine.
use DB_File;
my $name = 'irgendwas'; # Der username
my %logins;
tie %logins , "DB_File", "$loginlog", O_RDWR|O_CREAT, 0644;
if(exist $logins{$name} )
{
print "User: $name existiert";
}
else
{
$logins{$name} = <- deine daten
}
und nach einem untie sind diese Daten gespeichert, fertig.
Nur im Moment kann ich die logdatei nicht ansehen da ich mit einer schleife ein dauer lauf bewirkt habe,welche meine error log auf über 700MB anstiegen liess ;-)
Falls dies wirklich der Fall ist, vergiß es!
Bei so einer Größenordnung ist DB_File hoffnungslos überfordert. Mach dir über richtig Datenbanken Gedanken. selbst mySQL hat Grenzen.
Nun jetzt hab ich es doch wieder rückgängig gemacht etwas anders
while (<DBM>){
Was ist denn dieses DBM? Das kam bisher nirgendwo vor und das brauchst du auch nicht.
Struppi.
hi,
ich will nicht in jedem key was ändern.Er soll sämtliche user loggen und wenn ein neuer kommt dann soll er das auch eintragen,wenn er nicht exitstiert in der DBM datei.
Du gibst mir Rätsel auf. Du benutzt doch DB_File, oder?
;-) ja doch
Da passiert das was du willst von ganz alleine.
so selbstverständlich logisch ist das (DB...) für mich nicht
use DB_File;
my $name = 'irgendwas'; # Der username
my %logins;
tie %logins , "DB_File", "$loginlog", O_RDWR|O_CREAT, 0644;if(exist $logins{$name} )
{
print "User: $name existiert";
}
else
{
$logins{$name} = <- deine daten}
und nach einem untie sind diese Daten gespeichert, fertig.
»»
Danke so gehts perfekt ;-)
Nur im Moment kann ich die logdatei nicht ansehen da ich mit einer schleife ein dauer lauf bewirkt habe,welche meine error log auf über 700MB anstiegen liess ;-)
Falls dies wirklich der Fall ist, vergiß es!
Nö nicht die datenbank sondern die errorlog datei,weil ich den schalter -w aktiviert hatte und der server nur noch warnungen ausspuckte.
while (<DBM>){
Was ist denn dieses DBM? Das kam bisher nirgendwo vor und das brauchst du auch nicht.
hab ich irgendwo wie z.B. http://iis1.cps.unizar.es/Oreilly/perl/learn/ch17_02.htm aufgefangen und übernommen.
Hab mich halt etwas festgefressen,eine datei öffnen zu müssen explizit zu flocken und wieder mit close zu schliessen.
Anyway thx
Gruss
Alain
Nur im Moment kann ich die logdatei nicht ansehen da ich mit einer schleife ein dauer lauf bewirkt habe,welche meine error log auf über 700MB anstiegen liess ;-)
Falls dies wirklich der Fall ist, vergiß es!
Nö nicht die datenbank sondern die errorlog datei,weil ich den schalter -w aktiviert hatte und der server nur noch warnungen ausspuckte.
Jo, hatte ich beim 2. lesen auch gemerkt.
while (<DBM>){
Was ist denn dieses DBM? Das kam bisher nirgendwo vor und das brauchst du auch nicht.
hab ich irgendwo wie z.B. http://iis1.cps.unizar.es/Oreilly/perl/learn/ch17_02.htm aufgefangen und übernommen.
Hab mich halt etwas festgefressen,eine datei öffnen zu müssen explizit zu flocken und wieder mit close zu schliessen.
Der flock bei DB_File ist keine Datei, d.h. du öffnest keine Datei, sondern erzeugst einen Handle um die Datei locken zu können.
wie du schon hier gelesen hast http://www.hk8.org/old_web/linux/cgi/ch10_02.htm
my $db = tie %hash, "MLDBM", $dbm_file, O_CREAT | O_RDWR, 0644;
Hier wird der HASH "getied"
my $fd = $db->fd; # Get file descriptor
Das ist (wenn ich dsas richtig verstehe) der Dateihnadle aus DB_File
open DBM, "+<&=$fd" ; # Get dup filehandle
mit Hilfe dieses Handles und der seltsamen Zeichen davor, bekommt man einen normalen Dateihandle.
flock DBM, LOCK_EX; # Lock exclusively
Den man dan locken kann.
Aber ansonsten wird mit DBM nichts mehr gemacht, es ist überflüssig.
und durch:
undef $db;
hast du auch keine Zugriff mehr darauf. weshalb close fehl schlägt.
Das close ist aber überflüssig, da untie die Datei ja schon schliesst.
Struppi.
hi Struppi,
Das close ist aber überflüssig, da untie die Datei ja schon schliesst.
ok,
ich habe jetzt auch den ganzen kram von »» open DBM, "+<&=$fd" ;
weg und es geht so auch wie Du sagtest also ohne open und close sowie ohne
dieses $fd = $db->fd;...
ich benötige auch nicht das if(exist $logins{$username... mehr,da der eintrag automatisch erfolgt am schluss.
Ist halt nur so dass der server mekert mit dem schalter -w ,aber nur beim erstenmal danach nicht mehr.
Dennoch es läuft so,auch mit use strict; den -w schalter hab ich nun auch draussen.
Gruss
Alain
ich habe jetzt auch den ganzen kram von »» open DBM, "+<&=$fd" ;
weg und es geht so auch wie Du sagtest also ohne open und close sowie ohne
dieses $fd = $db->fd;...
Das war das File locking, d.h. wenn du das als CGI skript laufen läßt kann es u.U. sein das mehere Prozesse gleichzeitig auf ein und dieselber Datei zugreifen und dann droht Daten verlust.
Aber!
Ich bin mir nicht sicher, aber ich glaube neuere Versionen von der Datenbank locken von alleine, wie schon erwähnt such mal danach.
ich benötige auch nicht das if(exist $logins{$username... mehr,da der eintrag automatisch erfolgt am schluss.
Das war als Beispiel gedacht, wenn du Wissen willst ob der User existiert. Du musst nämlich aufpassen, wenn du Wissen willst ob ein Eintrag existiert und du es so abfragst:
if( $hash{'name'} ) {.....}
Dann wird automatisch ein (undefinierten) Eintrag mit dem schlüssel 'name' gemacht, was nicht immer gewünscht ist.
D.h. nach der obigen abfrage ist
if(exists $hash{'name'}) => wahr
aber
if(defined $hash{'name'}) => unwahr
Ist halt nur so dass der server mekert mit dem schalter -w ,aber nur beim erstenmal danach nicht mehr.
Der Server meckert nicht, Perl meckert.
Dennoch es läuft so,auch mit use strict; den -w schalter hab ich nun auch draussen.
Die Hinweise vo -w solltest du beseitigen, da sie u.U. zu Effekten führen die nicht von dir gewünscht sind.
wenn du auf eine variabel zugreifen möchtest, soltest du diese vorbelegen oder mit if(defined $var) überprüfen ob sie definiert wurde und schon meckert Perl nicht mehr.
Struppi.
hi,
dieses $fd = $db->fd;...
Das war das File locking, d.h. wenn du das als CGI skript laufen läßt kann es u.U. sein das mehere Prozesse gleichzeitig auf ein und dieselber Datei zugreifen und dann droht Daten verlust.
Ich bin mir nicht sicher, aber ich glaube neuere Versionen von der Datenbank locken von alleine, wie schon erwähnt such mal danach.
naja dann muss ich eben doch flocken das ganze,obwohl hier http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?display=16&id=15
zwar gesagt wird zitat "Berkeley - DB's sind unempfindlich gegenüber gleichzeitigen Schreibzugriffen mehrerer Prozesse. Trotzdem sollte die Datei
gelockt werden: "
was also heisst dass ich doch locken muss.
ich benötige auch nicht das if(exist $logins{$username... mehr,da der eintrag automatisch erfolgt am schluss.
Das war als Beispiel gedacht, wenn du Wissen willst ob der User existiert. Du musst nämlich aufpassen, wenn du Wissen willst ob ein Eintrag existiert und du es so abfragst:
if( $hash{'name'} ) {.....}
das war ja auch ein problem,das perl den usernamen in der DB datei nie gefunden hat und desshalb das weitere vorgehen blockiert wurde(nur beim ersten mal gings und zwar der neue eintrag,wenn nicht gefunden),somit
der eintrag wegblieb.Ich weiss ehrlich gesagt nicht mit welcher methode genau ich die DB datenbank absuchen soll damit was wahr ist.
Desshalb nehm ich das raus,weil am schluss der eintrag
$dbfile{$username} = ("$agent_now*$count_last*$date_today");
undef $db;
untie (%dbfile);
automatisch erfolgt.
Dann wird automatisch ein (undefinierten) Eintrag mit dem schlüssel 'name' gemacht, was nicht immer gewünscht ist.
D.h. nach der obigen abfrage ist
if(exists $hash{'name'}) => wahr
aber
if(defined $hash{'name'}) => unwahr
Ist halt nur so dass der server mekert mit dem schalter -w ,aber nur beim erstenmal danach nicht mehr.
Die Hinweise vo -w solltest du beseitigen, da sie u.U. zu Effekten führen die nicht von dir gewünscht sind.
ja das mach ich in der regel auch,aber bei diesem fall ist es nicht mehr so wichtig.
wenn du auf eine variabel zugreifen möchtest, soltest du diese vorbelegen oder mit if(defined $var) überprüfen ob sie definiert wurde und schon meckert Perl nicht mehr.
das wollte ich ja mit if (!-e $username ... oder if (!/$username/) aber es geht so nicht weil sich etwas widerspricht.
Gruss
Alain
naja dann muss ich eben doch flocken das ganze,obwohl hier http://perlbase.xwolf.de/cgi-bin/perlbase.cgi?display=16&id=15
zwar gesagt wird zitat "Berkeley - DB's sind unempfindlich gegenüber gleichzeitigen Schreibzugriffen mehrerer Prozesse. Trotzdem sollte die Datei
gelockt werden: "
Das ist nicht DIE Quelle. Nihcts gegen Rolf's Seiten, aber es gibt seit einiger Zeit eine neue Version der Berkley DB, aber wie gesagt ich hab keine Anhnung da ich sie nicht mehr nutze.
»
if( $hash{'name'} ) {.....}
das war ja auch ein problem,das perl den usernamen in der DB datei nie gefunden hat und desshalb das weitere vorgehen blockiert wurde(nur beim ersten mal gings und zwar der neue eintrag,wenn nicht gefunden),somit
Nein, du hast immer noch nicht verstanden.
Angenommen der Eintrag $hash{'name'} existiert nicht.
Dann ruft
if( $hash{'name'} eq 'test')
eine warnung hervor, weil du versuchst auf einen undefinierten wert zu zugreifen,
der eintrag wegblieb.Ich weiss ehrlich gesagt nicht mit welcher methode genau ich die DB datenbank absuchen soll damit was wahr ist.
Wie ich dir schon schribe if( exists $hash{'name'}) prüft ob der schlüssel (also der eintrag) existiert.
Desshalb nehm ich das raus,weil am schluss der eintrag
$dbfile{$username} = ("$agent_now*$count_last*$date_today");
FALSCH!!!!!
%dbfile existiert nicht. In deinem Beipsiel heißt es %hash
Außerdem hast du geprüft ob:
$username
$agent_now
$count_last
$date_today
existieren?
Du kannst die Warnungen auch vermeiden, wenn du bei der Deklaration einen Defaultwert (z.b. einen Leerstring) zuweist.
z.b.
$username = $ENV{HTTP_USER} || '';
jezt kannst du ohne Problem mit $username vergleiche oder verkettungen durchführen und erhälst keine Warnung.
wenn du auf eine variabel zugreifen möchtest, soltest du diese vorbelegen oder mit if(defined $var) überprüfen ob sie definiert wurde und schon meckert Perl nicht mehr.
das wollte ich ja mit if (!-e $username ... oder if (!/$username/) aber es geht so nicht weil sich etwas widerspricht.
Das eine hat mit dem anderen nichts zu tun und schon gar nicht mit dem was ich dir versuche zu erklären.
-e $var heißt 'existiert die Datei $var ' und das andere: kommt $username nicht in der Spezialvariabel $_ vor.
Ich glaub das ist nicht was du willst.
Wenn du Wissen willst ob eine Varibel einen definierten Wert hat:
if(defined $var) { print "definiert";}
Wen du Wissen willst ob eine Variabel einen definierten Wert der nicht 0 (null) und kein Leerstring ist:
if($var) { print "keine null, kein Leerstring";}
Wenn du Wissen willst ob ein Schlüssel eines Hashes existiert:
if(exists $hash{'key'} { print "Der Schlüssel 'key' existiert";}
Struppi.
hi,
Nein, du hast immer noch nicht verstanden.
Angenommen der Eintrag $hash{'name'} existiert nicht.
»»
ja diese abfrage sollte am anfang sein aber nicht mit if (exists
sondern ich will wissen ob der eintrag nicht existiert.Wär dann if (!exists $hash{$name}) korrekt?
Dann ruft
if( $hash{'name'} eq 'test')
eine warnung hervor, weil du versuchst auf einen undefinierten wert zu zugreifen,
das ist mir klar.
Wie ich dir schon schribe if( exists $hash{'name'}) prüft ob der schlüssel (also der eintrag) existiert.
Desshalb nehm ich das raus,weil am schluss der eintrag
$dbfile{$username} = ("$agent_now*$count_last*$date_today");FALSCH!!!!!
%dbfile existiert nicht. In deinem Beipsiel heißt es %hash
doch neuerdings nehm ich das "my %dbfile;" als hash - sorry.
Außerdem hast du geprüft ob:
$username
$agent_now
$count_last
$date_today
ja diese variablen sind gesetzt.
Du kannst die Warnungen auch vermeiden, wenn du bei der Deklaration einen Defaultwert (z.b. einen Leerstring) zuweist.
z.b.
$username = $ENV{HTTP_USER} || '';
hab ich auch so und am anfang wird es auch geprüft so
if($username eq ''||!$username)
{
exit;
}
jezt kannst du ohne Problem mit $username vergleiche oder verkettungen durchführen und erhälst keine Warnung.
wenn du auf eine variabel zugreifen möchtest, soltest du diese vorbelegen oder mit if(defined $var) überprüfen ob sie definiert wurde und schon meckert Perl nicht mehr.
das wollte ich ja mit if (!-e $username ... oder if (!/$username/) aber es geht so nicht weil sich etwas widerspricht.
Das eine hat mit dem anderen nichts zu tun und schon gar nicht mit dem was ich dir versuche zu erklären.
-e $var heißt 'existiert die Datei $var ' und das andere: kommt $username nicht in der Spezialvariabel $_ vor.
aha die datei also und nicht den wert bzw. hash in einer datei?!
Ich glaub das ist nicht was du willst.
nö
Wenn du Wissen willst ob eine Varibel einen definierten Wert hat:
if(defined $var) { print "definiert";}
das ist nicht nötig.Ich möchte eigentlich nur wissen ob der eintrag
$dbfile{$username} = ("$agent_now*$count_last*$date_today");
in der dbfile NICHT existiert ohne else zweig oder so.
Wenn du Wissen willst ob ein Schlüssel eines Hashes existiert:
if(exists $hash{'key'} { print "Der Schlüssel 'key' existiert";}
also in meinem fall etwa so?
if(!exists $dbfile{$username})
{
$dbfile{$username} = ("$agent_now*$count_last*$date_today");
}
also wie gehabt beim ersten aufruf des scriptes bzw. einem neuen user,wird der eintrag erst am schluss gemacht in die dbfile,
was aber dann zur warnung führt weil der hash ja nicht in der dbfile ist.
ja diese abfrage sollte am anfang sein aber nicht mit if (exists
sondern ich will wissen ob der eintrag nicht existiert.Wär dann if (!exists $hash{$name}) korrekt?
bingo!
Bzw. unless(exists $hash{$name}) (Perl macht Spaß ;-) )
hab ich auch so und am anfang wird es auch geprüft so
if($username eq ''||!$username)
{
exit;
}
Dadurch, dass du erst mit einem String vergleichst erhälst du die Warnung.
In deinem Falle reicht es einfach aus:
if(!$username)
{
exit;
}
und etwas perliger:
exit unless $username;
Das eine hat mit dem anderen nichts zu tun und schon gar nicht mit dem was ich dir versuche zu erklären.
-e $var heißt 'existiert die Datei $var ' und das andere: kommt $username nicht in der Spezialvariabel $_ vor.aha die datei also und nicht den wert bzw. hash in einer datei?!
-e String prüft ob die Datei String existiert.
Du musst nicht prüfen ob der HASH existiert durch tie ist diese quasi in der datei vorhanden und wenn du in ihn vorher deklariert hast ist alles im Lot.
also in meinem fall etwa so?
if(!exists $dbfile{$username})
{
$dbfile{$username} = ("$agent_now*$count_last*$date_today");
}
Fast. Die Klammern erzeugen eine Liste, du wilst aber einen String.
also wie gehabt beim ersten aufruf des scriptes bzw. einem neuen user,wird der eintrag erst am schluss gemacht in die dbfile,
Nein, er wird in dem Augenblick gemacht, wo du auf das Hash zugreifst (das ist die Magie von tie)
was aber dann zur warnung führt weil der hash ja nicht in der dbfile ist.
Doch ist er in dem Momnent wo du ihn tie'st. D.h. wenn du immer noch eine Warnung erhälst muss der Fehler bzw. undefinierte Wert woanders sein.
Struppi.
hi struppi,
Dadurch, dass du erst mit einem String vergleichst erhälst du die Warnung.
ok dann lass ich den vergleich wech.
In deinem Falle reicht es einfach aus:
if(!$username)
{
exit;
}und etwas perliger:
exit unless $username;
mal was gelernt ;-)
hab vorher immer mit ! gearbeitet
Nein, er wird in dem Augenblick gemacht, wo du auf das Hash zugreifst (das ist die Magie von tie)
was aber dann zur warnung führt weil der hash ja nicht in der dbfile ist.
Doch ist er in dem Momnent wo du ihn tie'st. D.h. wenn du immer noch eine Warnung erhälst muss der Fehler bzw. undefinierte Wert woanders sein.
ich habs glaub ich beim erstenmal mit dem falsch geschriebenen "exist" anstatt mit exists versucht,was ja nicht ganz korrekt war.
nun diesesmal hab ich mir mit if(exists ... {print "blabla .... am bildschirm anzeigen lassen und es geht alles nach plan.
cool,alles in butter nun...perl macht wircklich spass ;-)
Grüsse vom
Alain
Dadurch, dass du erst mit einem String vergleichst erhälst du die Warnung.
ok dann lass ich den vergleich wech.
nur um zukünftige Problem zu vermeiden, du kannst durchaus vergleichen, nur solltest du dies in deiner oder Verknüpfung als zweites machen:
if(!$username || $username ne 'bla')
Dann wird erst geprüft ob $username einen Inhalt hat, wenn ja ist der Vergleich Problemlos möglich.
Aber wie gesagt in deinem Falle ist dies nicht nötig.
cool,alles in butter nun...perl macht wircklich spass ;-)
Da bin ich aber froh, dass wir diesen Thread damit endlich zu Abschluss brinegn konnten ;-)
Struppi.
jetzt komm eyh
Alain, du zitierst
http://www.hk8.org/old_web/linux/cgi/ch10_02.htm zum Beispiel.
steht
untie %hash; # Clears buffers, then saves, closes, and unlocks file
untie %hash; # Clears buffers then saves, closes, and unlocks file
...Then untie will act like close and always be the command that frees your DBM file.
Gehts noch?
;-) Rolf
Hallo Alain
Hier zwei Artikel zum Thema DB_File und File lock
http://www.radwin.org/michael/blog/2003/05/adventures_with_db_fileloc.html
http://search.cpan.org/~dharris/DB_File-Lock-0.05/Lock.pm
Struppi.