Frage zu eregi()

Pre7ender

Mitglied
Ich möchte gerne auf einer meiner Linux Rechner div. Statistiken erstellen.
Dazu verwende ich PHP4 Scripte, welche mir Werte in eine MySQL DB speichert, welche dann später vom Web Frontend wieder ausgelesen werden und evtl. ein paar hübsche Grafiken erstellt.

Eines dieser Scripte soll mir die Temperetaur meiner Festplatten in die DB speichern.
Code:
<?php

    mysql_connect('localhost','user','pw');
    mysql_select_db('server');

    $_hddtemp = "/usr/sbin/hddtemp";

    $sql = "SELECT id,disk FROM hddtemp;";
    $result = mysql_query($sql);
    if(mysql_num_rows($result)) {
        while ($row = mysql_fetch_array($result)) {
            //print_r($row);

            $output = shell_exec($_hddtemp." ".$row[disk]);
            if (!eregi ("No such device",$output)) {
                $out = explode(" ", $output);
                //print_r($out);
                $sql = "UPDATE hddtemp SET temp = ".$temp." WHERE id = ".$row[id].";";
                echo "yes\n";
            } else {
                echo "no\n";
            }
        }
    }
?>
Alle Festplatten sind in der DB erfasst und werden hier ausgelesen und dann für jede einzelne den Wert 'temp' geupdatet.
Jedoch funktioniert die if - Abfrage mit eregi() nicht:
Code:
root@ragnaros /testdata/stats/hddtemp
 > php4 update.db.php
yes
/dev/hdc: open: No such device or address

yes
yes
yes
yes
yes
yes
yes
/dev/sdg: open: No such device or address

yes
/dev/sdh: open: No such device or address

yes
In der DB vorhanden sind folgende Disks: hda, hdc, sda bis sdh
Im System eingebaut sind diese: hda, sda bis sdf (die restlichen kommen später noch)

Er gibt mir bei jeder Disk 'yes' aus, was nicht sein soll.
Wie ihr seht ist die Fehlermeldung von 'hddtemp' 'No such device or address' und genau darauf überprüfe ich auch den $output String. Geht aber nicht

Warum?
Müsste doch so funktionieren?

Zweite Frage
Kann ich der Funktion shell_exec() oder dem ganzen Script irgendwie beibringen, bei Fehlermeldungen kein Output zu liefern?
 
Hallo!

1. Die Funktion preg_match(), die eine zu Perl kompatible Syntax regulärer Ausdrücke verwendet, ist häufig die schnellere Alternative zu ereg().

2. Tipp: Verwenden Sie nicht preg_match(), wenn Sie nur überprüfen wollen, ob eine Zeichenkette in einer anderen Zeichenkette enthalten ist. Verwenden Sie dafür stattdessen die Funktionen strpos() oder strstr(), die das schneller erledigen.
(aus dem PHP Handbuch)

PHP:
if (!eregi ("No such device",$output)) {
Wie ihr seht ist die Fehlermeldung von 'hddtemp' 'No such device or address'
Du prüfst aber "or adress" nicht.

Grüße

Martin
 
Danke für deine Antwort!
PHP:
if (!eregi ("No such device",$output)) {
Du prüfst aber "or adress" nicht.

Grüße

Martin
Müsste doch aber gehen, eregi() überprüft ja ob der Suchstring enthalten ist, nicht ob die genau gleich sind?

Naja egal, ich probier mal die anderen Funktionen aus, die erwähnt worden sind.

Danke, meld mich dann wieder
 
Hallo!

Müsste doch aber gehen, eregi() überprüft ja ob der Suchstring enthalten ist, nicht ob die genau gleich sind

Nein, eben nicht.

1. Argument ist genaugenommen kein "Suchstring", sondern ein regulärer Ausdruck ("Die Nadel").
2. Argument Ist Dein "Heuhaufen" der durchsucht werden soll
3. Argument ist optional und gibt eventuell gefundene Teilstrings zurück, die mit einem geklammerten Ausdruck in 1. übereinstimmen.

Würdest Du bei Dir oben das 3. Argument auswerten, müsste unter $reg[0] ein Treffer gelistet werden, wenn Du No such device in Klammern packst.

Die Reguläre Ausdrücke in 1. lassen viel mehr Möglichkeiten zu, als einen String in einem anderen zu suchen.

Grüße

Martin
 
Hier funktioniert das aber...
PHP:
function ping_host($ip)
{
  $options = "ping -c 1 -t 2";
  $command = $options." ".$ip;

  $cmd=shell_exec($command); // Ping mit counter=1 und timeout=2 (wartet zwei millisek. auf Antwort)
  $checker=explode(",",$cmd);

  if (eregi ("0", $checker[1])) {
      $status = false;
  }
  if (eregi ("1", $checker[1])) {
      $status = true;
  }
  return $status;
}
Naja egal, ich habs jetzt so gelöst
PHP:
<?php

    mysql_connect('localhost','user','pw');
    mysql_select_db('server');

    $_hddtemp = "/usr/sbin/hddtemp -n";

    $sql = "SELECT id,disk FROM hddtemp;";
    $result = mysql_query($sql);
    if(mysql_num_rows($result)) {
        while ($row = mysql_fetch_array($result)) {
            $temp = shell_exec($_hddtemp." ".$row[disk]);
            if (preg_match("/[0-9]{2}/", $temp)) {
                $sql = "UPDATE hddtemp SET temp = ".$temp." WHERE id = ".$row[id].";";
                mysql_query($sql);
                echo "Database successfully updated\n";
            } else {
                echo "Couldn't get information for ".$row[disk]."\n";
            }
        }
    }
?>
Mit der Option -n von hddtemp liefert er nur den Wert der Temperatur zurück.
 
Zuletzt bearbeitet:
Hallo!

PHP:
function ping_host($ip)
{
  $options = "ping -c 1 -t 2";
  $command = $options." ".$ip;

  $cmd=shell_exec($command); // Ping mit counter=1 und timeout=2 (wartet zwei millisek. auf Antwort)
  $checker=explode(",",$cmd);

  if (eregi ("0", $checker[1])) {
      $status = false;
  }
  if (eregi ("1", $checker[1])) {
      $status = true;
  }
  return $status;
}
Naja egal, ich habs jetzt so gelöst

Ja, da funktioniert das wirklich, aber in checker[1] steht auch nichts anderes drin als 1 oder 0. Je nachdem, was shell_exec zurückgibt. Da ist aber ereg() etwas überdimensioniert ...

PHP:
if ($checker[1] == 1) {
      $status = true;
  } else {
      $status = false;
  }

... wäre ausreichend.

PS: Ich habe gerade im Manual nachgelesen, das der ping Befehl 3 Exit Codes hat, 0,1 und 2. Bin mir aber nicht darüber im klaren, was shell_exec zurückgibt. Den Exit Code von ping? Solltest Du Dir also vielleicht nochmal ansehen, wenn die ping-Funktion richtig werkeln soll :-)

0 = OK
1 = No reply oder deadline
2 = Other errors

Wenn es den der ping exit code ist, müßte das bei Dir so aussehen:


PHP:
if ($checker[1] == 0) {
      $status = true; // Ping OK
  } else {
      $status = false; // Ping mit exit Code 1 oder 2
  }

Grüße

Martin
 
Die Ping Funktion läuft tadellos.
Entweder ist der Host pingbar oder nicht, das setzt der auch richtig um.

In der Funktion wird ein String, der Ping zurück geliefert mit explode() in ein Array aufgeteilt. Der Wert mit dem Key 1 ist ein String, somit sollte 'if($checker[1] == 1)' auch nicht gehen, wenn dann == "1".

Aber egal, beides funktioniert jetzt wies muss =)

Danke trotzdem der Hilfe!
 
Hallo!

Die Ping Funktion läuft tadellos.
Entweder ist der Host pingbar oder nicht, das setzt der auch richtig um.

Na dann passt ja alles. Deine Lösung mit == "1" ist natürlich die korrektere, aber == nimmt was ich weiß keine Typenprüfung vor, so dass == 1 auch gehen muss.

Aber wenn alles läuft gibts ja kein Grund sich weiter darüber zu unterhalten :-)

Grüße

Martin
 
Zurück