Sziasztok!
Hirtelen nem jut eszembe egyszerű megoldás a következő problémára:
Adott egy könyvtár, amibe folyamatosan kerülnek be fájlok és ideális esetben pár mp múlva el is tűnnek, mert egy feldolgozó elkapja őket. De előfordulhat, hogy nem sikerül feldolgozni, ilyenkor ott marad. Na erre kellene nekem riasztót írnom.
Az egész egy HP-Unixon van, először bash irányba indultam, de a Unix-os find-ban nincs mmin. Ezért arra gondoltam, hogy a bash script csak egy könyvtár listát csinál és azt elküldi FTP-n egy Linuxra. Ott pedig egy percenként futó PHP-vel ellenőrizhetném, hogy van-e benne mai fájl. Ha van, berakom egy táblába, és a 'hanyszor' oszlopot 1-re állítom. Ha a következő futáskor is benne van, növelem a 'hanyszor' értékét, majd ha az eléri az ötöt, mehet a riasztás.
Eddig ez talán működne is, de mi van, ha a következő listában olyan fájl van, ami eddig nem volt a táblában? Teszem azt, első körben bekerült a táblába a,b és c fájl. A második körben jön egy b,e fájl lista. Ha a táblában lévő adatokat nézem végig egy ciklussal, abból ugyan ki fog derülni, hogy a b-t növelni kell, de nem derül ki, hogy az e új fájl.
Biztos pofon egyszerű a megoldás, csak késő van már nekem hozzá :)
Köszönöm!
- 1926 megtekintés
Hozzászólások
Azon a HP Unixon stat parancs sincs?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
De az van, csak még nem vagyunk ismerősök :)
Helyesbítek: nincs :(
- A hozzászóláshoz be kell jelentkezni
De mi a probléma? A számlálót minden filename esetében külön növeled és ami eltűnt, azt értelemszerűen dobod, nem?
- A hozzászóláshoz be kell jelentkezni
Igen, de honnan fogom tudni, hogy melyek az új fájlok?
- A hozzászóláshoz be kell jelentkezni
Úgy, hogy eddig nem volt, most meg van. Nyilván minden n-edik lépésben meg kell lennie az eggyel korábbi, n-1-edik file listád, s az aktuális filenevet keresned kell a régi nevek listájában. A művelet végén pedig az aktuális lista válik régivé.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Pont így gondoltam én is, csak kicsit elvesztem a lényegi megvalósításában.
Ha ciklussal olvasom a táblából a sorokat és hasonlítom össze az új könyvtár listával, abból az derül ki, hogy a 'b' már megvolt, de az 'e' nem kerül be újként. Esetleg berakhatnám mind a két listát tömbbe és azt hasonlítgatnám...
- A hozzászóláshoz be kell jelentkezni
Nem értem, miért. Az ugye megvan fejben, hogy ez két egymásba ágyazott ciklus? Veszed az új lista első elemét, keresed a régi listában. Ha megvan, a számlálóját növeled (mondjuk én csökkenteném, de ez lényegtelen). Ha nincs meg, akkor jé, ez egy új filename, inicializáljunk hozzá egy számlálót! Utána veszed az új lista második elemét, s ugyanígy keresed a régi listában...
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Igen, két egymásba ágyazott ciklus. Nézzük akkor sorban: veszem az új lista első elemét: 'b'. Megvan a listában, növelem a számlálót. Jön az új lista második eleme, az 'e'. Nincs meg, berakom a táblába. Eddig tényleg minden szép. De mi lesz szegény 'a'-val és 'c'-vel? Azoknak menni kell, mert már nincsenek benne az új listában.
Beismerem nem erősségem a logika :)
- A hozzászóláshoz be kell jelentkezni
Nem teszteltem, fejből írtam, de ez alapján azért már gondolom el tudsz indulni :)
#!/usr/bin/php
<?php
$tempFile = "/tmp/tempData.pser";
if (file_exists($tempFile)) $lastFiles = unserialize(file_get_contents($tempFile));
else $lastFiles = array();
$currFiles = array();
$d = dir("./");
while (false !== ($file = $d->read())) {
if ($file == "." || $file == "..") continue;
if (array_search($file, $lastFiles) === false) {
// A $file nem volt itt az előző körben
} else {
// A $file már itt volt az előző körben
}
$currFiles[] = $file;
}
$d->close();
foreach ($lastFiles as $file) {
if (array_search($file, $currFiles) === false) {
// A $file itt volt, de azóta eltűnt
}
}
file_put_contents($tempFile, serialize($currFiles));
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
"Ha a táblában lévő adatokat nézem végig egy ciklussal"
De miért nem a könyvtárlistában lévő fájlokon iterálsz?
(a,b,c bent vannak a táblában)
Következő alkalom pszeudo szkriptje (b,e):
select b (van)-> update számláló;
select e (nincs)-> insert;
végül minden törlése ami nem e v. b;
De lehet h csak nem értem a gondod..
- A hozzászóláshoz be kell jelentkezni
Na, azt hiszem ez nem fért a fejembe, hogy a végén delete minden, kivéve az új fájl lista szereplőit. Köszönöm!
- A hozzászóláshoz be kell jelentkezni
Nincs mit. Azt hiszem ez egy tipikus szituáció volt - ami velem is gyakran megesik- , amikor valaki rá van görcsölve valamire és nem tud egy lépést hátralépni önerőből, h áttekintsen egy egyszerű [v. épp komplkáltabb] dolgot. Ilyenkor jól jön a külső - akár laikus- vélemény, ami kimozdítja a holtpontról v. egy kis alvás :)
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
"a Unix-os find-ban nincs mmin. Ezért arra gondoltam, hogy a bash script csak egy könyvtár listát csinál és azt elküldi FTP-n egy Linuxra"
Unix at a glance? :)
- A hozzászóláshoz be kell jelentkezni
Ha ez: ls -lt --time-style +%s
megy, akkor bash-ben konnyen kiszamolhatodd a file eletkorat.
Ha van referencia file, akkor pedig bashben [ file1 -nt file2 ]
vagy [ file1 -ot file2 ]
feltetellel lehetne vizsgalni a fileokat...
- A hozzászóláshoz be kell jelentkezni
Ezt se eszi meg sajnos :(
- A hozzászóláshoz be kell jelentkezni
while true; do
find DIR -type f -exec md5 -r {} \; > FILELIST
rm `sort FILELIST FILELIST.old | uniq -d | awk '{print $2}'`
mv FILELIST FILELIST.old
sleep 30
done
Azaz:
- megkeressük a fájlokat, és mindegyikre egy
md5
-t eresztünk (a-r
a kimenet miatt kell) - kiíratom a
FILELIST
ésFILELIST.old
fájlok tartalmát, rendezem őket, csak a dupla sorokat íratom ki, és a második mezőt tartom meg (azmd5
-r
opciója) - kitörlöm a fájlokat
- átnevezem a fájllistát
- megvárjuk a megadott időt (30 másodperc, de nyilván lehet több vagy kevesebb is)
Ha minden igaz, akkor azokat a fájlokat töröljük, amelyek (legalább) 30 másodperce megvannak (és az md5 is megegyezik). Hibás működés akkor lehet, ha "gyakran" jelennek meg ugyanazon nevű fájlok ugyanazzal a tartalommal.
Esetleg az mv...
előtt újra lehetne generálni a FILELIST
-et, hiszen a kitörölt fájlok is benne vannak a listában. Vagy inkább: sort FILELIST FILELIST.old | uniq > FILELIST.old
az mv...
helyett :) Ha a sort
-nak van -u
opciója, akkor azzal ki lehet váltani a uniq
-ot.
Persze a fájlok törlése helyett nyugodtan lehet riasztást küldeni a fájllistával.
- A hozzászóláshoz be kell jelentkezni
Ez is nagyon tetszik, csak a fájlok, amik ott maradtak, mert nem kerültek feldolgozásra, azok végleg ott maradnak, nem nyúlhatok hozzájuk.
- A hozzászóláshoz be kell jelentkezni
Ahogy írtam:
Persze a fájlok törlése helyett nyugodtan lehet riasztást küldeni a fájllistával.
Azaz az rm
-es sor helyett nyugodtan lehet egy mail
parancsot hívni megfelelően paraméterezve.
Viszont ha nem nyúlhatsz hozzájuk, nem biztos, hogy ez a megoldás változtatás nélkül jó lesz, hiszen az ott maradó fájlok listája folyamatosan gyarapszik, és amikor már 30 fájl van, nem fogod megtalálni, melyik lesz az új. Erre szintén van egy egyszerű bővítés (meg szűkítés is lehet, hiszen ekkor az md5
felesleges):
touch FILELIST.old OLDFILES.old
while true; do
find DIR -type f -exec md5 -r {} \; > FILELIST
sort FILELIST FILELIST.old | uniq -d | awk '{print $2}' > OLDFILES
if ! diff -q OLDFILES OLDFILES.old > /dev/null; then
diff OLDFILES OLDFILES.old | mail ...
fi
mv OLDFILES OLDFILES.old
mv FILELIST FILELIST.old
sleep 30
done
- A hozzászóláshoz be kell jelentkezni
inotify?
Lehet figyeltetni vele könyvtárakat, és alert event-et írni hozzá.
- A hozzászóláshoz be kell jelentkezni
Ha van HP-UNIX-ra, akkor se biztos, hogy annyira egyszerű, hiszen nem az a lényeg, hogy megjelenik-e egy fájl, hanem az, hogy vannak-e olyan fájlok, amelyek "régóta" vannak (és melyek ezek).
- A hozzászóláshoz be kell jelentkezni
Akkor inotifywatch... és a kimenetet értelmezni. Amihez nem érkezik törlés, akkor azt pl. óránként törölni.
Bár a legegyszerűbb az eredeti szkriptet/programot javítani.
- A hozzászóláshoz be kell jelentkezni
Ezzel gyakorlatilag a viszonylag egyszerű szkriptemet bonyolítanád el :P
Hiszen nyilván kellene tartani a létrejött fájlokat, egy óra múlva megnézni, hogy megvan-e még, vagy berakod egy listába (környezeti változó, fájl, adatbázis, stb.) a létrejött fájlokat, és kiveszed, ha kitörölték, és a listában levő fájlokat mindig megnézed, hogy benn vannak-e már egy órája?
Ha van időd, kb. írd már meg, érdekel, hogy egyszerűbb lesz-e, mint a fentebbi szkriptem :)
- A hozzászóláshoz be kell jelentkezni
Tudtommal az inotify Linux-only.
- A hozzászóláshoz be kell jelentkezni
Elvileg FreeBSD-re is van: http://www.freshports.org/devel/libinotify
- A hozzászóláshoz be kell jelentkezni
Nem lenne egyszerűbb a feldolgozás státusza alapján rögtön alertet küldeni ha hibás?
---
Referrall https://goo.gl/7S2vlp (koding) | https://goo.gl/muWzKz (digitalocean)
- A hozzászóláshoz be kell jelentkezni
De igen, csak arra sajnos nincs ráhatásom.
- A hozzászóláshoz be kell jelentkezni
Mindenkinek köszönöm, végül is a jól bevált 'FTP-vel elhozom és helyben PHP-val feldolgozom' módszert választottam és úgy néz ki remekül működik :)
Még egyszer köszönöm!
- A hozzászóláshoz be kell jelentkezni
ha csak egy kicsit is ertelmesen kerulnek a file-ok abba a konyvtarba (pl. mint a Maildir formatumnal), azaz tmp/ ala mennek a file-ok, majd ha kesz, es volt close(), akkor move a new/ ala, es a 'feldolgozo' nevu cuccban is van annyi IQ, hogy loggoljon/szirenazzon/whatever, ha nem tud feldolgozni egy file-t, akkor kb. nincs is szukseg a riasztodra...
--
"nem tárgyszerűen nézem a dolgot, hanem a vádló szerepéből. Sok bosszúságot okoztak, örülnék ha megbüntetnék őket - tudom gyarló dolog, de hát nem vagyok tökéletes." (BehringerZoltan)
- A hozzászóláshoz be kell jelentkezni
De nem ez az eset áll fent :)
- A hozzászóláshoz be kell jelentkezni