[MEGOLDVA] könyvtár törlése nagyon sok fileval

Fórumok

Helló

Olyan problémába futottam bele, hogy van egy könytár nagyon sok fileval. Nem tudom mennyi, mert akármilyen parancsot is adok ki mindegyik előbb be akarja parse-lni és előbb utóbb elfogy a memória (16G). Mv, rm, find semmi se segít. Milyen módszerrel lehetne törölni ezt a könyvtárat. Csak filek vannak benne alkönyvtárak nincsenek.

Hozzászólások

Hülye ötlet, de nem lenne jobb "részekre bontani" a törlést?
for i in {a..z}; do for j in {a..z}; do rm -f $i$j*; done; done;
for i in {A..Z}; do for j in {a..z}; do rm -f $i$j*; done; done;
for i in {a..z}; do for j in {A..Z}; do rm -f $i$j*; done; done;
for i in {A..Z}; do for j in {A..Z}; do rm -f $i$j*; done; done;

Plusz ezek számos variációi. Egyébként nem tudok elképzelni annyi állományt hogy azoktól a rendszer megegyen 16 Gb RAM-ot. Meg tudod mondani, melyik processz eszi meg a memóriát? Lehet állományrendszer hiba és/vagy kernel bug? Milyen fs?

Ha ez nem segít, akkor semmi se.
Oda kell menni az nfs szerverhez, és azon kiadni a parancsot.

Ja, és az nem baj, ha elkezd nőni a memóriafogyasztás, és előbb-utóbb elhal a kliens - ha mire idáig eljut, egy csomó fájlt le tudott törölni, márpedig ennek így kéne lennie. Mert így a reboot után lehet folytatni tovább.
Amúgy én is arra tippelek, hogy a swap hiánya és/vagy egyéb vfs/inode cache paraméterek okozzák, hogy a memóriafogyasztás végén meghal a gép.

Ja. Az nem esett le elsőre, hogy az rm csak olyat tud törölni, amin a find már átment. X bejegyzés törlése pedig nem lehet hatással az Y bejegyzés láthatóságára (vagyis nem tudja átverni a find-ot, hogy az Y-t ne vegye észre). Legalábbis a readdir() speckó nem tűnik ezt megengedni.

Ha ki tudod számolni, hány fájlnál telik meg a ram, akkor alkothatsz regexpet, ami legfeljebb annyit töröl egyszerre. Vagy a regexp alapján történő parse-olás is az összes fájlra vonatkozik?

Eszembe jutott egy valószínűleg működő, de nagyon ronda megoldás. Adj neki sok-sok-sok giga swapet!

Én meg nem értem, hogy miről beszélsz.
A fs úgy működik, hogy bizonyos műveleteket lehet rajta végrehajtani (mkdir, rmdir, create, ln, mv, rm meg haverjaik). Azt gondoljuk elvárásnak a fs felé, hogy minden művelet akkor "kész", amikor a feladatát elvégezte, módosította a fs-t úgy, hogy az a változtatás után ismét konzisztens állapotban van. Az általad említett művelethez a konzisztencia jegyében hozzátartozik, hogy a directory-ban levő neveket el kell előbb távolítani, az azok által hivatkozott inode-ok usecount-ját eggyel csökkenteni, ha így valamelyik 0 lett, akkor a hozzátartozó diszkterületet felszabadítani (ha nem fogja még futó processz).
El lehet hagyni ezeket, de akkor a művelet végrehajtása után reboot és fsck fog kelleni...

find /bla/* | xargs rm
----------------------
while (!sleep) sheep++;

Ez duplán nem jó. A find /bla/* kapásból végig akarja olvasni a könyvtárat, plusz a fájlnevek listáját abc-rendbe rakni, majd command line paraméterként a find-nak átadni (ez mire jó?), majd utána ugyanezt a find mégegyszer eljátssza, amikor az xargsnak próbálja átadni a paraméterlistát...

Igen, ez csak egyszer követi el az említett hibát ;-)
Szóval az rm egy fájlt sem töröl addig, amíg a teljes listát meg nem kapja a find-tól (mert be sem indul addig), ahhoz pedig végig kell olvasni a könyvtárat, plusz a teljes listát át kell tudni adni command line paraméterként.

...

Lehet annyi fájlt egy könyvtárba berakni, hogy őket ne tudjad felsorolni egy command line listába (mondjuk ha a teljes RAM + swap terület byte-ban kevesebb, mint ahány karakter kell a neveiket leírni, az triviális megoldása ennek). Akkor az lokális fs-en sem fog menni...

Olvasva a hozzászólásokat, felmerült bennem a kérdés, hogy miből látszik, hogy elfogy a memória? A free/top szerint, vagy elkezd dögleni a gép és az oom killer elkezd lövöldözni a processekre?

Nem csak arról van szó, hogy elhasználja cache-nek a memóriát, ami teljesen normális, jó, stb. stb.?

Illetve ha nagyon sok fálj van, akkor az rm * a paranccsor hosszába fog belefutni, szóval én szeretnék egy pontos hibaüzenetet, mert lehet hogy tévúton járunk.

rendes rendszerekben az ls -nek van (asszem) -f opciója, aminek lényege, hogy nem rendezi a listát, hanem a könyvtárbeli sorrendnek megfelelően listáz. Ebben az esetben nem kell neki semmit kesselni, lévén a kapott neveketz simán lehet kiírni. Így kb:


while true: ; do
rm `ls -1f | head -50`
done

De ha nem megy, akkor lehet perl szkriptet írni, amely az opendir/readdir/closedir használatát megfűszerezi egynéhány (szintén értelemszerűen 50-100) nevenként meghívott unlink-kel. (Ha rosszul emlékszem, és a perl-féle unlink csak egy nevet fogad el, akkor egyesével.) Speciel a *dir C-library rutinok nem rendeznek, tehát nem szabad memóriát zabálniuk.

ls | xargs rm

vagy

ls | head -n 1024 | xargs rm

nem segít?

Mintha explicit leírta volna, hogy - mivel az ls ABC-rendbe akarja rendezni a fájlneveket, ehhez össze kell gyűjteni az összeset - szépen elfogy a memória. Ezen nem változtat az a tény, hogy kierőszakolod tőle, hogy soronként csak 1 db nevet írjon, hiszen attól még rendezni akarja. De föntebb akad már két működő megoldás is :-)

Jólvanna.. :) kissé fáradt/figyelmetlen voltam amikor írtam. Viszont én is futottam már ilyenbe és nekem ez segített. Igaz nem milliós nagyságrendben, de volt vagy 100K+ file. Egy kb. 512M/1G memóriás gépnél. És nem vettem észre, h felemésztette volna a memóriát (igaz nem is figyeltem, mert láttam, h lassan de biztosan törli).