Egyszerűnek tűnő kérdés, de milyen parancssori program tudja összesíteni Linux-on egy adott könyvtár alatti fájlok és csak a fájlok összesített méretét?
A `du` nem jó, mert az disk blokkméretben számol, a -b vagy a --apparent-size se teljesen a fájlok méretével számol, mert rekurzív esetben látszólag hozzászámolja a könyvtárak méretét is (fájlok neve, metaadatok, egyebek):
$ ls -lR | awk {'a=a+$5; print $5" "a'}
0
0
106 106
3581 3687
4371 8058
2155 10213
2018 12231
106 12337
$ du
20 .
$ du -b
16433 .
$ du --apparent-size
17 .
- 892 megtekintés
Hozzászólások
$ du -b
16433 .
Vonj le belőle 4096-ot és az eredmény pontos.
- A hozzászóláshoz be kell jelentkezni
És hányszor 4096-ot vonjak le, ha mennyi alkönyvtár van? :D
Például:
$ find . -type f | xargs -d '\n' ls -l | awk '{sum=sum+$5;} END{print sum}'
1881035633
vs
$ du -b -s
1898558321 .
- A hozzászóláshoz be kell jelentkezni
Kell neked annyit mászkálni! :) Én egy könyvtárat néztem csak.
- A hozzászóláshoz be kell jelentkezni
Hopp, megelőztél - ez nagyon hasonlít ahhoz, amit írtam alább...
- A hozzászóláshoz be kell jelentkezni
A du -bSd0 jó lenne, ebből "csak" a fájlokat tartalmazó könyvtár méretét kell levonni (ami persze változó lehet, nem feltétlenül 4096). :D
- A hozzászóláshoz be kell jelentkezni
Kifejtenéd bővebben?
$ find . -type f | xargs -d '\n' ls -l | awk '{sum=sum+$5;} END{print sum}'
14218598380
$ du -b -s
14220290028 .
$ du -bSd0
4096 .
Ez ugye annyit csinál, hogy kihagyja az összes alkönyvtárat és ha csak alkönyvtárak vannak, akkor remekül visszatér egy fix 4096 értékkel.
Ha csak fájlok vannak, akkor meg ugyanaz, mint amit írtam feljebb:
$ find . -type f | xargs -d '\n' ls -l | awk '{sum=sum+$5;} END{print sum}'
12337
$ du -b -s
16433 .
$ du -bSd0
16433 .
- A hozzászóláshoz be kell jelentkezni
A du -b -s összegzi az alkönyvtár(ak)ban lévő fájlok méretét is (ha van(nak) alkönyvtár(ak)), a du -bSd0 viszont csak az "adott könyvtár" fájlméreteit összegzi.
- A hozzászóláshoz be kell jelentkezni
Minden jel szerint nem jó válasz a 4096 egy olyan könyvtárra, amiben ~180GB van... nem?
- A hozzászóláshoz be kell jelentkezni
Már miért ne lenne jó? Azt jelenti hogy egy darab _fájl_ sincs az adott könyvtárban.
Az hogy az alkönyvtárakban vannak fájlok, az más kérdés. Kicsit félreérthetően fogalmaztál amikor "egy adott könyvtár alatti fájlok és csak a fájlok"-at írtál. Akkor ezek szerint rekurzívan értetted. Azt passzolom.
- A hozzászóláshoz be kell jelentkezni
Az intellektuális kihíváson kívül ennek amúgy mi értelme van?
Annyira nem rossz felülbecslés amit a du ad, pontosan kiszámolt helyre meg úgysem tudod elrakni mert a másik FS-en is fog kelleni plusz hely a foldereknek. Oké, S3-nál mondjuk nem kell számolni.
Esetleg mondhatnál picit többet a konkrét megoldandó problémáról hátha van másik megközelítés.
zászló, zászló, szív
- A hozzászóláshoz be kell jelentkezni
Nem túl komplex: sok kis fájl sok alkönyvtárban és az ott lévő sok adat aktuális mennyisége érdekel, nem az, hogy mennyi helyet foglal el valahol, mert ráadásul dedup+compression ZFS a fájlrendszer, szóval a du vagy hülyeséget ír vagy számomra használhatatlan.
- A hozzászóláshoz be kell jelentkezni
Hirtelen valami ilyesmi jutott eszembe:
find . -type f -exec stat -c %s {} \; | awk '{sum=sum+$1} END{print sum}'
- A hozzászóláshoz be kell jelentkezni
Scriptet én is tudok írni, de mivel lassú sok adaton, ezért a kérdés az, hogy van-e erre kész utility, mint a `du`, csak nem a `du`. :)
- A hozzászóláshoz be kell jelentkezni
A du is stat()-ot csinál odabenn...
- A hozzászóláshoz be kell jelentkezni
De nem egy interpretált shell hajtja végre egy shell pipeline-on keresztül, egyesével exec hívással, majd egy interpretált awk program összesíti:
real 0m33.749s
user 0m23.990s
sys 0m12.624s
vs
real 0m3.761s
user 0m1.447s
sys 0m2.305s
- A hozzászóláshoz be kell jelentkezni
Find - exec helyett xargs?
- A hozzászóláshoz be kell jelentkezni
Teljesen mindegy, nincs közöttük mérhető különbség, a du egy nagyságrenddel gyorsabb, sok fájl esetén ez a különbség növekszik.
- A hozzászóláshoz be kell jelentkezni
Már rég megírtad volna C-ben. Illetve megírták helyetted.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
A kérdés nem az, hogy meg tudom-e írni bármiben is, hanem hogy van-e ilyen kész tool. Bonyolítja az üzemeltetést és a rendszer karbantarthatóságát, ha saját kódból fordított saját programot kell erre használnom.
- A hozzászóláshoz be kell jelentkezni
A jelek szerint nincs ilyen kész tool. A built-in cuccokkal valószínűleg az az Elbandi féle megoldás lesz a leggyorsabb, csak a print format-ot kell még kisilabizálniuk a srácoknak...
- A hozzászóláshoz be kell jelentkezni
Az mennyire valid, hogy du-val lemered, utana egy masik paranccsal megszamolod, mennyi konyvtar van a strukturaban, es kivonsz belole annyiszor 4k-t?
- A hozzászóláshoz be kell jelentkezni
fisher@s0:/srv/data/tmp$ ls -ld x
drwxr-xr-x 2 fisher fisher 299319296 Jun 1 23:31 x
Ugye azt tudjátok, hogy egy könyvtár mérete vagy 4k, vagy nem, de az biztos?
- A hozzászóláshoz be kell jelentkezni
Így van, a könyvtár mérete attól függ, hogy mennyi fájl van benne, azoknak mennyi metaadata van.
- A hozzászóláshoz be kell jelentkezni
findnek van printf-je, ami kiirja a meretet: %s File's size in bytes.
find . -type f -printf "%s\n" | awk '{sum=sum+$1} END{print sum}'
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
Ez király!
- A hozzászóláshoz be kell jelentkezni
Ja:
# find . -type f -printf "%s\n" | awk '{sum=sum+$1} END{print sum}'
1,62243e+11
(MC: 162243121152)
- A hozzászóláshoz be kell jelentkezni
Az mc kapcsán jut eszembe, hogy én az ilyet mindig fájlkezelőkben néztem meg, jelenleg Vifm-ben. Ennek ellenére Elbandi megoldása király, szkriptből is használható, elteszem, előre láthatóan jól fog jönni. A du-ba tényleg jól jönne ehhez egy kapcsoló, ami csak a fájlokat számolja, hiszen ha olyan kapcsoló máris van, ami csak a mappákat nézi, akkor nem értem, hogy fordítva miért nem jött össze.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
hatbazki, tweakeld meg az awkot hogy rendesen irja ki :)
de akar csinalhatod igy is (bar a bc limitjeit nem ismerem annyira... talan mukodik akkor is ha 1M fajl es csilli PB-rol van szo):
(find -type f -printf "%s+"; echo 0)|bc
A vegtelen ciklus is vegeter egyszer, csak kelloen eros hardver kell hozza!
- A hozzászóláshoz be kell jelentkezni
Tweakeld meg te, te találtad ki ezt a sacc/kb. vackot!
"(find -type f -printf "%s+"; echo 0)|bc"
Na, ez már faszább, pár dolog kiderült belőle:
Nem számolja ugye bele a linkeket, de ez nem gond, ott a '-type l'.
Ha (a könyvtárak 98%-ánál) hozzáadjuk a -type l és a -type d összegeit, tökéletesen megfelel a 'du -bs'-nek, szóval hibátlam a módszer. (FIFO, socket nélkül.)
Az MC rosszul számol pl. a törött linkeknél. (Vagy pl. 324 bájt eltérést találtam a ~150 GB-os könyvtárban, de azt már tutira nem keresem meg.)
Az MC alap/egyszerű/hibátlan esetben nagyrészt hibátlanul számol.
A bc menő! :D
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy ez egy 32-bites awk volt? Esetleg { printf "%.0f\n", sum; }
- A hozzászóláshoz be kell jelentkezni
Erre gyanakszok én is. Nálam 64 bites rendszeren ilyen 100 gigás mappaméretnél is simán kiírta rendes számként, nem ilyen lebegőpontos közelítésként. Mindenféle külön konfigolás nélkül.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
# find . -type f -printf "%s\n" | original-awk '{sum=sum+$1} END{print sum}'
162395448620
# find . -type l -printf "%s\n" | original-awk '{sum=sum+$1} END{print sum}'
14
# find . -type d -printf "%s\n" | original-awk '{sum=sum+$1} END{print sum}'
15273984
# du -sb
162410722618 .
# echo 162395448620+14+15273984 |bc
162410722618
# find . -type f -printf "%s\n" | original-awk '{sum=sum+$1} END{print sum}'
162395448620
# find . -type f -printf "%s\n" | gawk '{sum=sum+$1} END{print sum}'
162395448620
# find . -type f -printf "%s\n" | mawk '{sum=sum+$1} END{print sum}'
1,62395e+11
/bin/gawk
/bin/gawk: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=85ba7115de4e224d8c6082720f119100ddaf45f4, for GNU/Linux 3.2.0, stripped
/bin/mawk
/bin/mawk: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c06fdf6c2d64e90576b6fa546ecf9570adb159d8, for GNU/Linux 3.2.0, stripped
/bin/original-awk
/bin/original-awk: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d0488e6afa71764cad5b67f1a23ae6daaec3d4ca, for GNU/Linux 3.2.0, stripped
- A hozzászóláshoz be kell jelentkezni
És ha a mawk-nál a `printf "%.0f", sum`-ot használod?
- A hozzászóláshoz be kell jelentkezni
# find . -type f -printf "%s\n" | mawk '{sum=sum+$1} END{printf "%.0f", sum}'
162395448620
# find . -type f -printf "%s\n" | gawk '{sum=sum+$1} END{printf "%.0f", sum}'
162395448620
# find . -type f -printf "%s\n" | original-awk '{sum=sum+$1} END{printf "%.0f", sum}'
162395448620
- A hozzászóláshoz be kell jelentkezni
A gdu jó lehet.
Ha json módban futtatod, akkor kiírja az összes file-ról és könyvtárról az adatokat json formátumba. És onnan már külön tudod választani csak a file-okat, ehhez persze kell némi json parse-olás.
- A hozzászóláshoz be kell jelentkezni
Próbáltad is és azt csinálja, amit kérdeztem? Mert ránézésre a readme szerint egy Go-ban írt párhuzamosított `du`, ha meg ugyanazt adja vissza, mint a `du` és akkor nekem nem jó...
- A hozzászóláshoz be kell jelentkezni
A json outputot néztem egyszer, akkor úgy tűnt, hogy használható arra, amire akarod.
- A hozzászóláshoz be kell jelentkezni
Itt hozzad hasonlo problemaval kuzdott valaki: https://unix.stackexchange.com/questions/22432/getting-size-with-du-of-…
- A hozzászóláshoz be kell jelentkezni
Off: mi a cél? vagyis milyen hasznot jelent, ha megvan ez a szám?
- A hozzászóláshoz be kell jelentkezni
Tudjam, hogy mennyi adat van ott. Nem az érdekel, hogy mennyi blokkot foglal a lemezen.
- A hozzászóláshoz be kell jelentkezni
A mar torolt, de meg nyitva tartott fileok ott vannak?
- A hozzászóláshoz be kell jelentkezni
A hardlink minek szamit?
---
tmp/1$ echo cucc > myfile
/tmp/1$ ln myfile mylink
/tmp/1$ ls -la
drwxr-xr-x 2 kubi kubi 4096 May 31 21:16 .
drwxrwxrwt 19 root root 12288 May 31 21:15 ..
-rw-r--r-- 2 kubi kubi 5 May 31 21:15 myfile
-rw-r--r-- 2 kubi kubi 5 May 31 21:15 mylink
/tmp/1$ find . -type f
./mylink
./myfile
- A hozzászóláshoz be kell jelentkezni
A hardlink minek szamit?
Nincs hardlink használatban.
- A hozzászóláshoz be kell jelentkezni
Mint írtam, nem a disk usage érdekel, hanem az ott lévő adatok mennyisége.
- A hozzászóláshoz be kell jelentkezni
Gyakorlati haszna akkor sincs sok. Felraktál volna egy ncdu-t vagy mc-t, hasonlót, azzal le tudtad volna mérni 3 mp. alatt. Jó az ncdu lehet beleszámolta volna a 4K-s mappákat, de ilyen több gigás nagyságrendnél az már összarányában nem egy nagy eltérés, képet úgy is kapsz az adatok mennyiségéről.
Persze, érdekességnek azért jó volt, lehetett belőle tanulni.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Az `ncdu` ugyanúgy rosszul számol, az mc-t meg nem tudom beletenni script-be, hogy csinálja automatikusan.
- A hozzászóláshoz be kell jelentkezni
Ez kétségtelen így van. Én viszont ilyenkor nem állok neki 4 kilobájtokon rugózni, mikor ilyen 100+ gigás tételeket mérek, du ilyenkor elég scriptből. Persze, elvi síkon igazad van, kéne lennie a du-ban ilyen kapcsolónak.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Ragaszkodsz hozzá, hogy valamelyik built-in parancssori program csinálja? Ha van lehetőség fordítani, akkor C-ből is megoldható a mérés:
#ifndef _DIRSIZE
#define _DIRSIZE 1
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int dirsize(char *path, size_t *size)
{
char opath[PATH_MAX];
DIR *d;
struct dirent *dir;
struct stat s;
size_t subsize;
int e;
if (size == NULL)
{
return 1;
}
if (getcwd(opath, sizeof(opath)) == NULL)
{
return 2;
}
if (chdir(path) == -1)
{
return 3;
}
d = opendir(".");
if (d == NULL)
{
chdir(opath);
return 4;
}
*size = 0;
while ((dir = readdir(d)) != NULL)
{
if (lstat(dir->d_name, &s) == 0)
{
if (!S_ISLNK(s.st_mode))
{
if (S_ISDIR(s.st_mode))
{
if ((strcmp(dir->d_name, ".") != 0) && (strcmp(dir->d_name, "..") != 0))
{
e = dirsize(dir->d_name, &subsize);
if (e != 0)
{
closedir(d);
chdir(opath);
return e;
}
*size += subsize;
}
}
else
{
*size += s.st_size;
}
}
}
}
closedir(d);
chdir(opath);
return 0;
}
#endif
- A hozzászóláshoz be kell jelentkezni
Headerként behúzott include-ra gondoltál? Vagy mi ez az ifndef-es történés, ami vigyáz arra, nehogy többször legyen?
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Tkp. igen, bár én inkább "unitnak" szoktam mondani, noha tudom, hogy az pascalos terminológia...de én minden nyelven Pascal kódot írok. :P (Kivéve a Pascalt, mert ott meg C kódot. :/ )
- A hozzászóláshoz be kell jelentkezni
"de én minden nyelven Pascal kódot írok" - Hátulgombolós... :-D
- A hozzászóláshoz be kell jelentkezni
Nyertél, ezt a megoldást nem lehet überelni, se futási sebességben, se memóriahasználatban, se portolhatóságra. Az a baj, hogy nem vagyok ilyen badass, hogy mindent C-ben írjak magamnak, egyszeri userként ilyenkor shell sckripttel szerencsétlenkedek, ami meg futási teljesítményben sokszor nem ideális.
“Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”
- A hozzászóláshoz be kell jelentkezni
Igazság szerint lehet még rajta optimalizálni.
Egyrészt arra a két db strcmp()
-re valójában nincs szükség, elég ez a makró:
#define DENSOP(P) (((P)[0] != '.') || (((P)[1] != 0) && (((P)[1] != '.') || ((P)[2] != 0))))
és akkor így módosul az érintett sor a két komparálással:
if ((strcmp(dir->d_name, ".") != 0) && (strcmp(dir->d_name, "..") != 0))
helyett
if (DENSOP(dir->d_name))
(És akkor dobható az include-ok közül a string.h
is.)
Másrészt - noha ez már valószínűleg nem jelent különbséget a kapott gépi kódban, mert a fordító úgyis kiszúrja - a kétszintű if
is felesleges a linkvizsgálatnál:
if (lstat(dir->d_name, &s) == 0)
{
if (!S_ISLNK(s.st_mode))
helyett
if ((lstat(dir->d_name, &s) == 0) && !S_ISLNK(s.st_mode))
De mondom, ezt a fordító valószínűleg amúgy is megfogta, ez csak magát a C kódot teszi egyszerűbbé és kisebbé.
- A hozzászóláshoz be kell jelentkezni
Igen, ez a macro sokat gyorsít.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni
Viszont az include-ok közé kell még egy #include <limits.h>
is. Linux alatt megy nélküle, de a BSD-k, vagy Solaris alatt nem fog; most próbáltam ki.
És ha már így össze lett rakva, meg ki lett próbálva, megcsináltam, hogy egy-egy flag-gel állítható legyen, hogy a könyvtárak 4096 byte-ját (vagy amennyi) azt számolja bele, vagy se, valamint, hogy oldja-e fel a symlinkeket, vagy se:
int dirsize(char *path, size_t *size, bool add_dir_sizes, bool follow_symlinks);
És úgy, hogy a flag-ek mentén négy rutinra szétbontva, hogy annyival is gyorsabb legyen (annyival kevesebb elágazás). Letölthető innen, ha valakinek kellene: http://oscomp.hu/?details/DirSize_unit_for_C_v1.0.0_(CP)_1604
- A hozzászóláshoz be kell jelentkezni
su da
- A hozzászóláshoz be kell jelentkezni
aaaa
- A hozzászóláshoz be kell jelentkezni
A sebesség miatt néztem meg Ruby-ban és gyorsan fut root-ként gyökérből indítva kb 7 sec alatt 1 szálon (6 éves noti, i5-5200U CPU @ 2.20GHz). A du parancs ugyanerre 3.3 sec alatt fut. Kb fele. Szerintem érdemes leprogramoznod a választott nyelveden és akkor olyan lesz amilyen neked kell.
Dir["**/**"].select{|f| File.file?(f) }.map{|f| File.size(f) rescue 0 }.sum
281729932533277
- A hozzászóláshoz be kell jelentkezni
"A `du` nem jó, mert az disk blokkméretben számol"
Miért, nem blokkosan tárulonk adatot?
- A hozzászóláshoz be kell jelentkezni
Gondolom, neki az adattartalom kell, nem pedig az, hogy a konkrét filerendszeren mennyi helyet foglal. Ha elmozgatod az adatot, máshol tárolod, akkor más lehet a foglalási egység is, tehát a nettó adatmennyiség a releváns.
tr '[:lower:]' '[:upper:]' <<<locsemege
LOCSEMEGE
- A hozzászóláshoz be kell jelentkezni