Pfad aus Datei auslesen und verarbeiten

Status
Für weitere Antworten geschlossen.
janis

janis

BOFH
Hallo Leute,

ich will eine Datei auf Viren prüfen, und wenn keine Viren gefunden wurden, sie in einer MySQL Datenbank als "sauber" registrieren.

Funktioniert dieser Shell-Script so? (Ich denke eig nicht)
Code:
cat /var/www/setup/upload/file.dat
  read line

  if  [ $line -e 0]
  then
  echo "Nothing to do" >/var/log/php_antivirus.log
  else
  clamscan "/var/www/setup/tmpfiles/$line > /var/log/php_antivirus.log
  fi


lynx --dump http://localhost/setup/upload/scan.php

und hier noch die PHP Datei die das weiterverarbeitet:
PHP:
<?php
  $db   = mysql_connect('localhost','user','pw');
  mysql_select_db('setup');
  
  $ret  = file_get_contents("php_antivirus.log");
  $file = file_get_contents("file.dat");
  $file = explode("/",$file);
  echo $ret;
  
  $exp  = nl2br($ret);
  $exp  = explode('<br />',$exp);
  array_walk($exp,'arr_walk','Infected files:');
  $a    = $id;
  $err  = eregi_replace("([^\\[]*)Infected files: ([^\\[]*)","\\2",$exp[$a]);
  if($err==0)
  {
    $anfrage="UPDATE `tempfiles` SET `checked` = 'Y' WHERE `id` LIKE '".$file[0]."'";
    mysql_query($anfrage);
  }  
  else
  {
    $anfrage="UPDATE `tempfiles` SET `checked` = 'V' WHERE `id` LIKE '".$file[0]."'";
    mysql_query($anfrage);
  }


  $anfrage="SELECT * FROM `tempfiles` WHERE `checked` = 'N'";
  $ergebnis = mysql_query($anfrage);
  $anz=mysql_num_rows($ergebnis);
  if ($anz > 0)
  {
    $zeile  = mysql_fetch_row($ergebnis);
    $datei  = fopen("file.dat","w");
    fwrite($datei,$zeile[0]."/".$zeile[1]);
    fclose($datei);
  }
  mysql_close($db);
  
  echo "\n";
  echo "\";
  echo date("r");
  
  function arr_walk(&$item, $key, $string)
  {
    global $id;
    if (strpos($item,$string) !== false)
    {
      $id = $key;
    }
  }
?>

Script und Datei sind in einem Ordner!

Schon mal danke
Jan
 
Zuletzt bearbeitet:
Auch hier:
Von welcher Shell reden wir?
Welches OS?

Hallo Leute,

ich will eine Datei auf Viren prüfen, und wenn keine Viren gefunden wurden, sie in einer MySQL Datenbank als "sauber" registrieren.

Funktioniert dieser Shell-Script so? (Ich denke eig nicht)
Hast du es probiert?
Wenn nein, warum nicht?

Allgemein zur Syntax:
Datei Line für Line lesen mit while read
Code:
while read line

done </var/www/setup/upload/file.dat

Das hier
Code:
 if  [ $line -e 0 ]
Ist sowohl syntaktisch falsch, als auch sinnlos.
Du prüfst hier nicht etwa ob Datei file.dat existiert, sondern die einzelnen Zeilen aus dem Inhalt der Datei.
Sicher nicht das was du willst.
Es sei denn, in deiner file.dat stehen Dateinamen mit gültigem Pfad drin.
Dann müsstest du aber so testen.
Code:
if [ -f "$line" ];
then
...
fi
Wenn du nur testen willst, ob /var/www/setup/upload/file.dat existiert und eine gültige Datei ist:
Code:
DAT="/var/www/setup/upload/file.dat";
    if [ -f "$DAT" ];
    then
    echo "Datei $DAT existiert"
    fi
Deinen PHP -Code habe ich mir nicht angesehen, da das nix mit Shell zu tun hat.


Wolfgang
 
Also ich nehme mal an, dass dieses "clamscan" eine Datei als Argument annimmt. Abgesehen davon, dass die Syntax völlig falsch ist, könnte das sowieso nicht funktionieren... (Also die Datei zeilenweise einlesen und dann jede Zeile auf Viren prüfen...)
Btw, wenn du testen willst, ob eine Datei größer 0 byte groß ist, kann man das mit der "-s" Option von test machen:
Code:
if [ -s ~/somefile ]; then echo '~/somefile has size greater than 0!'; fi
Siehe auch:
Code:
man test
Wenn du eine while-Schleife zeilenweise über eine Datei iterieren lassen willst, würde man das so machen:
Code:
while read line; do
   # Hier der code
done < infile
Naja, die Sache ist auch, dass du nicht wirklich sagst, was du eigentlich willst..
Willst du den Dateinamen per Usereingabe holen? Dann wäre das mit dem "read" sinnvoll, wenn du aber die Datei "/var/www/setup/upload/file.dat" auf Viren prüfen willst, so ist dein Code Schwachfug...

Und obwohl das hier eigentlich gar nichts zu suchen hat, diese Zeile hier:
Code:
  $db   = mysql_connect('localhost','user,'pw');
Da fehlt ein single-quote...

[Edit]:
Oha, wenn in der file.dat Dateinamen ohne absolutes Verzeichnis stehen, die Dateien aber alle aus einem Verzeichnis kommen, macht diese Zeile fast schon wieder Sinn:
Code:
clamscan "/var/www/setup/tmpfiles/$line"
Dann müsste man die while-Schleife ungefähr so machen:
Code:
while read filename; do
   if [ -f "/var/www/setup/tmpfiles/$filename" ]; then
      clamscan "/var/www/setup/tmpfiles/$filename" > logfile
   fi
done < /var/www/setup/upload/file.dat
Du siehst wieviel Klarheit man in so ein Skript bringen kann, wenn man einfach mal informative Variablennamen verwendet?
Also da habe ich jetzt mal einfach den "-f" Switch von test genommen. Wobei, können Dateien mit Größe 0 Viren "enthalten"? kA, ansonsten könntest du auch immer den "-s" Switch nehmen..
 
Zuletzt bearbeitet:
In der file.dat steht eine! Relative Pfadangabe zu der zu überprüfenden Datei.
Diese Datei soll mit Clamscan überprüft werden.
Das Ergebnis soll mit dem PHP-Script ausgewertet werden.
Dann soll das PHP-Script eine neue Datei aus der Datenbank suchen und die relative Angabe in die file.dat schreiben. Wenn keine Datei mehr in der Datenbank ist, soll eine "0" in file.dat geschrieben werden.
Das Script soll die "0" erkennen und dann eine halbe Stunde warten, bevor die Schleife erneut ausgeführt wird.

Das fehlende single-quote ist durch das unkenntlichmachen des Passworts geschehen!

Edit://
es ist noch nicht alles so umgesetzt, wie es sein soll

Noch mal Edit://
Sorry, dass ich mich vorher nicht so genau ausgedrückt habe, aber mit der Shell Programmierung hab ich mich bisher noch nicht beschäftigt!

Und Betriebssystem: Debian Etch
Und was meinst du Wolfgang: welche Shell? -> Die die unter Debian Standard ist
 
Zuletzt bearbeitet:
Hllo
Zu meiner Standardfrage gehört leider die Frage nach Shell und OS.
Das darfst du ruhig mal anklicken ;) .
Da ich per default Debian stable nutze, weiß ich, dass dort bash 3.xx standard ist. ;)
Aber woher sollen das z.B. Gentoo oder SuSe-user wissen?

Deine PHP Geschichte klärst du besser im entsprechenden Forum, weil das nichts mit diesem zu tun hat.
Wenn in der eingelesenen file.dat wirklich Dateinamen stehen, dann hast du meinen Lösungsansatz ja schon.
Allerdings rate ich dir mit absoluten Pfaden zu arbeiten.
Oder du stellst sicher, dass $PWD im richtigen Pfad steht.
Bei einer non-interactively Shell (wie z.B. als cronjob) ist das $HOME.
Welche Argumente und Optionen dein clamscan braucht, liest du bitte aus der Manpage dazu.

Gruß Wolfgang
 
Deine PHP Geschichte klärst du besser im entsprechenden Forum, weil das nichts mit diesem zu tun hat.
Dieser Teil sollte auch schon gelöst sein, was mir jetzt fehlt ist halt das Shell Script.

Wenn in der eingelesenen file.dat wirklich Dateinamen stehen, dann hast du meinen Lösungsansatz ja schon.
da steht z.B. "1/datei_zum_ueberpruefen.exe" drin.
oder halt "0"

Allerdings rate ich dir mit absoluten Pfaden zu arbeiten.
Wo habe ich bis jetzt einen Relativen Pfad angegeben (außer in der file.dat)?
->Oder sollte ich den auch absolut machen?

Welche Argumente und Optionen dein clamscan braucht, liest du bitte aus der Manpage dazu.
Hab ich auch schon getan und die stehen so auch schon im Script

Was mir jetzt noch fehlt:
->Wie kann ich überprüfen, ob in der file.dat eine "0" steht?
->Wie kann ich das Script "schlafen" lassen?
->Wie kann ich die erste Zeile auslesen, und dann deren Text weiterverwenden?
reicht da einfach ein read *variable*?
->Wie kann ich das Script sich ständig wiederholen lassen?
und gibt es dann irgendeine Lösung es von außen wieder zu beenden?
also als init.d script?
 
->Wie kann ich überprüfen, ob in der file.dat eine "0" steht?
Code:
foo="blub"
if [ x"$foo" = x"blub" ]; then echo "$foo ist gleich blub."; fi
Wie du das mit der Variable "$line" hinkriegst, muss ich wohl (hoffentlich) nicht mehr erläutern..

->Wie kann ich das Script "schlafen" lassen?
Code:
man sleep
Code:
sleep 10 # "Schläft" 10 Sekunden
sleep 10s # Auch 10 Sekunden
sleep 5m # "Schläft" 5 Minuten
sleep 1h # "Schläft" eine Stunde
sleep 7d # "Schläft" ne Woche..
sleep 10s 5m # "Schläft" 10 Sekunden und 5 Minuten

->Wie kann ich die erste Zeile auslesen, und dann deren Text weiterverwenden?
Code:
head -n1 file
reicht da einfach ein read *variable*?
read liest eine Zeile von stdin, wobei wir in der while-Schleife das stdin von einer Datei beziehen, und speichert das "gelesene" in einer Variable. Also nein, das geht so nicht...

->Wie kann ich das Script sich ständig wiederholen lassen?
Code:
while [ 1 ]; do ./script.sh; done
:d

[Edit]:
->Wie kann ich die erste Zeile auslesen, und dann deren Text weiterverwenden?
Ganz vergessen zu sagen, man kann den output von Variablen direkt auf der command-line verwenden via command-substitution:
Code:
echo "$(head -n1 file)"
Macht dasselbe wie "head -n1 file", allerdings mit einem echo drumrumgebaut. (Das kann man übrigens bis ins Unendliche weiterführen, infiniter regress..)
So kann man die erste Zeile dann zum Beispiel in eine Variable packen:
Code:
Ich_bin_die_erste_Zeile_von_file="$(head -n1 file)"
Beachte die double-quotes, die in 99% Prozent der Fälle (Ausnahme: Die erste Zeile besteht aus einem zusammenhängenden Wort (manche shebangs zb...)) absolut notwendig sind..
 
Zuletzt bearbeitet:
Code:
while [ 1 ];
do 
  path="$(head -n1 file)"
  if [ x"$path" = x"0" ];
  then
  echo "Nothing to do" >/var/log/php_antivirus.log
  sleep 30m
  else
  clamscan "/var/www/setup/tmpfiles/$path" > /var/log/php_antivirus.log
  fi

  lynx --dump http://localhost/setup/upload/scan.php
done
Sieht jetzt so aus!

Wie kann ich das Script jetzt beenden? Wenn ich es im rc2.d verknüpfe?

Noch mal Edit:
./av.php.sh: line 13: syntax error near unexpected token `done'
./av.php.sh: line 13: `done'
 
Zuletzt bearbeitet:
Indem du kill benutzt.
Die PID findest du mit diversen Werkzeugen wie ps oder pgrep.

Wolfgang
oder pidof ist auch gut dafür

Code:
~> pidof kopete
10472

also im Init-Script einfach:
Code:
kill -9 `pidof scriptname`
Oder, wenn der Name schön eindeutig ist, evtl killall? Das braucht ja gar keine PID...

Und woran liegt jetzt der Fehler?
Welcher?

Wie kann ich das Script jetzt beenden? Wenn ich es im rc2.d verknüpfe?
Wie meinst du das, wie machst du das? Schau mal die dortigen Init-Scripte an, die haben eine Syntax extra für die Verwendung als Init-Script. So ein Script solltest du erstellen und daraus dein Script starten. Das Init-Script hat dann die Option, das laufende Script zu killen.
 
Ergänze das mal mit einer shebang und setze Semikolon nach jedem Befehl.
Lass es mit set -x laufen.
Eventuell wird es dann etwas klarer.

Wolfgang
PS Du hast die Datei nicht zufälling unter MS Win.. erstellt?
 
Semiko(h)len sind halbe Briketts.
Du meinst Semicola. (Was nach der Logik eigentlich pepsi sein sollte, aber egal..)
Und Betriebssystem: Debian Etch
Und das war dann ja auch nicht 100%-tig korrekt... (beziehungsweise vollständig..)

[Edit]:
Btw: Die while-Schleife hatte ich eigentlich nicht so wirklich ernst gemeint...
Und zumindest meine bash (3.2.25(1)) kennt auch "true", deswegen prozesssparender/schneller:
Code:
while true; do
   # something
done
Code:
help true
true: true
    Return a successful result.
Es gibt natürlich auch false. Die Dinger setzen einfach die spezielle Variable $?.
 
Zuletzt bearbeitet:
noch eine Frage:

ich habe das Script mit screen ./script
und danach habe ich den Screen detached!
dann habe ich ps ausgeführt:
PID TTY TIME CMD
2970 pts/0 00:00:00 bash
2985 pts/0 00:00:00 ps
und wie beende ich jetzt das Script?
 
und wie beende ich jetzt das Script?
Du wolltest es doch als Init-Script starten. Wie hast du das gemacht?

In den Beispielen für Init-Scripte siehst du ja, wie mit "case" meistens auf den Parameter "stop" reagiert wird. Wenn du ein Init-Script gebaut hast und nicht einfach das Script selber da rein kopiert hast, dann könntest du in den Bereich eine kill-Anweisung schreiben (siehe vorige Posts) und es dann mit /etc/init.d/scriptname stop anhalten.
 
So, nun mal Klartext:

Du gibst nach Nachfrage ein Debian etch an, erstellst das aber in einem hier OT OS (Windows),
erwartest dann Hilfe zu Debuginfos, liest nichtmal die Hinweise zur Selbsthilfe.
Was erwartest du noch?

Kennst du die Manpage von kill?

closed

Wolfgang
 
Status
Für weitere Antworten geschlossen.

Ähnliche Themen

NagiosGrapher 1.7.1 funktioniert nicht

dovecot und postfix Konfiguration Problem

Windows clients können nicht mehr auf lange laufendes System zugreifen

Falsche Rechte gesetzt beim Anlegen von Ordnern via Samba-Client

Neue Zeilen in der Datei

Zurück
Oben