Calcolo spazio occupato cartella

di il
9 risposte

Calcolo spazio occupato cartella

Ciao a tutti
Ho 2 metodi per calcolare lo spazio occupato da una cartella.
Il primo è velocissimo rispetto al secondo, però è impreciso, perché mi segna di meno rispetto a quanto è realmente.
Il secondo è più lento ed è precisissimo al byte.
Mi piacerebbe riuscire a sistemare il primo ma non ci riesco, è già un miracolo questo
(è un server linux)

PRIMO METODO
    
    $dir = $PERCORSO_CARTELLA_FOTO_UPLOAD;
    $io_open = popen ( '/usr/bin/du -sk ' . $dir, 'r' );
    $size = fgets ( $io_open, 4096);
    $size = substr ( $size, 0, strpos ( $size, "\t" ) );
    pclose ( $io_open );
    echo 'Directory: ' . $dir . ' => Size: ' . $size;
SECONDO METODO

echo str_replace(",", ".", number_format(getdirectory($PERCORSO_CARTELLA_FOTO_UPLOAD)));
function getdirectory($dir){
    $b = 0;
    $dir = realpath($dir);
    if($dir!==false && $dir!='' && file_exists($dir)){
        foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)) as $object){
            $b += $object->getSize();
        }
    }
    return $b;
}

9 Risposte

  • Re: Calcolo spazio occupato cartella

    Dopo un po' di ricerche sono riuscito a fare in modo che la prima desse il risultato preciso che dava la seconda, pur mantenendo la velocità.
    ho aggiunto
    popen( "ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r' );
    ma l'ho trovato su Internet, e sinceramente non so proprio cosa faccia tutta questa roba, però funziona!
    Adesso potete spararmi per ciò che ho detto
  • Re: Calcolo spazio occupato cartella

    Non esiste un modo semplice per avere la dimensione di una cartella.
    Personalmente mi sono scritto la mia versione semplificata del comando dir di Windows
  • Re: Calcolo spazio occupato cartella

    Io sto usando questo
    function getdirectory($path){
    	$path = strval($path);
    	$io = popen("ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r');
    	$size = intval(fgets($io, 80));
    	pclose($io);
    	return $size;
    }
    
    è veloce, ci impiega meno di 1 secondo a leggere 15gb di file
    ma in tutta sincerità non ho capito nulla di tutto ciò che vuol dire ogni singolo di quei comandi
    soprattutto questo
    $io = popen("ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r');
    li sto cercando ad uno ad uno su internet cercando di unire i punti e capirlo nel complesso ma non riesco a capirlo
    anche perché mi piacerebbe capire se è possibile modificarlo per renderlo ancora più veloce, ma per farlo dovrei capire ognuna di quelle.
  • Re: Calcolo spazio occupato cartella

    È semplicemente il comando ls (simile a dir di Windows) che però non dà il totale, che viene fatto inviando lo output a un ulteriore comando awk che somma man mano le righe.
    Non troverai nulla di più veloce, ma è ovviamente un sistema non portabile (non funziona su Windows) ed è una voragine di sicurezza (esegui da php un programma del sistema operativo)
  • Re: Calcolo spazio occupato cartella

    In che senso non dà il totale?
    Sto caricando le foto dal mio pc Windows al server Linux.
    Lo spazio che mi segna su Windows e lo stesso identico che mi segna la funzione.

    Sì, non è portatile perché funziona solo su Linux

    In che senso è una voragine di sicurezza?
    Come potrei richiamare quella funzione in php senza passare per php??

    che poi fgets, il secondo parametro, è la lunghezza di bytes da leggere?
    c'è scritto 80... in assenza di 80 ho letto che è 1024
    ma in funzione del calcolo dello spazio che occupano i file, quell'80 costa sta a significa?? Nel senso che più è alto più cosa??
    sarà meglio toglierlo?
    Perché in funzione del calcolo dello spazio non capisco perché 80...
    perché fgets() parla della lettura di un file aperto con fopen, un file di testo, quindi legge sino a 80bytes... ma sul calcolo dello spazio cosa centra?
  • Re: Calcolo spazio occupato cartella

    melixo ha scritto:


    In che senso non dà il totale?
    Il comando ls di Linux/Unix non dà il totale della dimensione dei singoli file.
    
    root@f-server:~ # ls -l
    total 162
    drwx------  3 root  wheel       3 Dec 16  2017 .cache
    drwx------  4 root  wheel       4 Oct 22  2018 .config
    -rw-r--r--  2 root  wheel     957 Oct 22  2018 .cshrc
    -rw-------  1 root  wheel   36869 Apr 25 19:02 .history
    -rw-------  1 root  wheel       0 Jan 28 21:17 .history.1231905
    -rw-------  1 root  wheel   10878 Jan 28 21:52 .history.1745969
    -rw-------  1 root  wheel   17800 Jan 28 21:17 .history.1832579
    -rw-------  1 root  wheel   17687 Jan 25 20:11 .history.186006
    -rw-------  1 root  wheel       0 Jan 28 21:52 .history.2036858
    -rw-------  1 root  wheel       0 Jan 23 19:01 .history.418518
    -rw-------  1 root  wheel   18152 Jan 23 19:01 .history.547573
    -rw-------  1 root  wheel       0 Jan 25 20:11 .history.642695
    -rw-------  1 root  wheel   28062 Jan 23 18:15 .history.930132
    -rw-r--r--  1 root  wheel     149 Oct 22  2018 .k5login
    -rw-------  1 root  wheel      28 Oct 15  2019 .lesshst
    drwx------  3 root  wheel       3 Dec 16  2017 .local
    -rw-r--r--  1 root  wheel     395 Oct 22  2018 .login
    -rw-------  1 root  wheel    3269 Apr 21 18:29 .lsof_f-server
    -rw-------  1 root  wheel      17 Dec 23  2017 .mysql_history
    -rw-r--r--  1 root  wheel     327 Jan 23 16:40 .nsmbrc
    -rw-r--r--  2 root  wheel     251 Mar 10  2018 .profile
    drwx------  2 root  wheel       6 Dec 25  2017 .ssh
    -rw-------  1 root  wheel   35478 Apr 25 14:57 .viminfo
    drwx------  3 root  wheel       3 Oct 23  2018 VirtualBox VMs
    -rw-------  1 root  wheel      22 Jan  7  2018 dead.letter
    -rw-------  1 root  wheel  217283 Nov  5  2019 mbox
    drwxr-xr-x  8 root  wheel      95 Apr 21 19:10 script
    
    Quanti byte ci sono nella cartella ? Non lo sai

    Questo è ad esempio il mio programmello simil dir
    
    ==== Scanning dir <<./>>
    2021-04-25 17:02:27 <DIR>               ./
    2017-12-16 15:36:06 <DIR>               ./.cache/
    2018-10-22 16:43:58 <DIR>               ./.config/
    2018-10-22 16:40:37                 957 ./.cshrc
    2021-04-25 17:02:27              36.869 ./.history
    2021-01-28 20:17:47                   0 ./.history.1231905
    2021-01-28 20:52:07              10.878 ./.history.1745969
    2021-01-28 20:17:47              17.800 ./.history.1832579
    2021-01-25 19:11:59              17.687 ./.history.186006
    2021-01-28 20:52:07                   0 ./.history.2036858
    2021-01-23 18:01:41                   0 ./.history.418518
    2021-01-23 18:01:41              18.152 ./.history.547573
    2021-01-25 19:11:59                   0 ./.history.642695
    2021-01-23 17:15:08              28.062 ./.history.930132
    2018-10-22 16:40:39                 149 ./.k5login
    2019-10-15 16:12:51                  28 ./.lesshst
    2017-12-16 15:36:06 <DIR>               ./.local/
    2018-10-22 16:40:39                 395 ./.login
    2021-04-21 16:29:49               3.269 ./.lsof_f-server
    2017-12-23 10:04:45                  17 ./.mysql_history
    2021-01-23 15:40:10                 327 ./.nsmbrc
    2018-03-10 14:29:32                 251 ./.profile
    2017-12-25 08:38:29 <DIR>               ./.ssh/
    2021-04-25 12:57:57              35.478 ./.viminfo
    2018-10-23 13:01:52 <DIR>               ./VirtualBox VMs/
    2018-01-07 14:19:31                  22 ./dead.letter
    2019-11-05 07:44:01             217.283 ./mbox
    2021-04-21 17:10:16 <DIR>               ./script/
            21 File                 387.624 byte
             7 directory 199.741.997.056 bytes ( 186.02 GB) free
    
    In che senso è una voragine di sicurezza?
    Stai lanciando un programma eseguibile del sistema operativo da PHP.
    Se ti sostituisco quel programma con un virus o quello che vuoi (con lo stesso nome) il tuo programma PHP lo eseguirà
    Come potrei richiamare quella funzione in php senza passare per php??
    Contare i file richiede un'enumerazione ricorsiva, che è tipicamente lenta, molto lenta, soprattutto su linguaggi interpretati.
    Non c'è un "vero" modo per avere la lista dei file in cartelle e sottocartelle in modo rapido, più rapido di ls o di un programma C (tipo il mio)
    che poi fgets, il secondo parametro, è la lunghezza di bytes da leggere?
    c'è scritto 80... in assenza di 80 ho letto che è 1024
    ma in funzione del calcolo dello spazio che occupano i file, quell'80 costa sta a significa?? Nel senso che più è alto più cosa??
    sarà meglio toglierlo?
    Perché in funzione del calcolo dello spazio non capisco perché 80...
    perché fgets() parla della lettura di un file aperto con fopen, un file di testo, quindi legge sino a 80bytes... ma sul calcolo dello spazio cosa centra?
    Non calcola nulla
  • Re: Calcolo spazio occupato cartella

    
    ls -ltrR .
    questo comando Linux/Unix mostra, per ogni cartella, l'elenco dei file presenti e la relativa dimensione
    -l è il formato lungo
    -R è ricorsivo
    -tr ordina (inversamente)

    L'output è qualcosa così
    
    -rw-r--r--  1 root  wheel   16 Apr  4 19:32 pkg-plist
    -rw-r--r--  1 root  wheel  326 Apr  5 13:02 pkg-descr
    -rw-r--r--  1 root  wheel  367 Apr  5 13:22 Makefile
    -rw-r--r--  1 root  wheel  161 Apr  5 13:37 distinfo
    L'output viene "pipato" (col |) verso awk, che in prima battuta prende la quinta colonna output (awk '{print \$5})
    Come puoi vedere la quinta colonna è composta proprio dalle dimensioni, cioè
    16,326,367 e 161 nell'esempio.
    Queste righe vengono inviate, di nuovo, ad awk (sempre un programma eseguibile) il quale fa una sorta di ciclo e poi ne sputa fuori il risultato, cioè la dimensione (sum) della dimensione dei file.

    Questo output viene "intercettato" da PHP dentro $io
    
    $io = popen("ls -ltrR {$path} |awk '{print \$5}'|awk 'BEGIN{sum=0} {sum=sum+\$1} END {print sum}'", 'r');
    A quel punto viene letto in formato stringa (fgets) fino a un massimo di 80 caratteri (perchè 80? boh mica l'ho fatto io, ovviamente è eccessivo, intval potrebbe facilmente andare in errore con una eventuale stringa così lunga).

    In sostanza l'output da lavorare sarà qualcosa del tipo "123456789012" (in stringa), da convertire in testo.
    Chiaramente, nel tuo caso, fino a 80 caratteri vengono letti (cioè una dimensione tipo
    12345678901234567890123456789012345678901234567890123456789012345678901234567890 che mi pare leggermente eccessiva)

    Infine viene convertito in intero, e messo in $size
    
    $size = intval(fgets($io, 80));
    E' una tecnica molto diffusa: intercettare l'output di un comando eseguibile ed interpretarlo (in questo caso male, non c'è verifica degli errori etc).

    Usando un altro programma avresti potuto ottenere direttamente il dato
    
    Get directory size, ignoring .zfs and :$DATA
    30/04/2021 17:00:44 Scan dir <</tmp/>>
    Free 0           217.127.645.184      202.22 GB    <</tmp/>>
    
    =============================================
    Dir 0              3.994.805.780           69  0.003 <</tmp/>>
    =============================================
                       3.994.805.780           69  0.003 sec (3.72 GB)
    
    0.003 seconds (all OK)
    O magari con altre tecniche (du, tree e chi più ne ha ne metta).

    Se ti chiedi perchè ls non scriva il totale della dimensione dei file, almeno come opzione, ti assicuro che stai colpendo nel segno uno dei grandi misteri dell'informatica, che non ho mai capito
  • Re: Calcolo spazio occupato cartella

    Ti ringrazio per la risposta lunghissima che mi hai dato, che ancora non ho letto bene, leggerò adesso con calma perché è un complesso.
    Ad una prima lettura ho capito cosa intendi sulla sicurezza... beh sì, se qualcuno mi ci infila un altro comando praticamente userebbe la console del server attraverso php... dovrei fare un controllo su quel comando (sempre da php) e controllare che sia solamente il comando che voglio che esegua...
    Ma come me lo potrebbero infilare un altro comando? Quel comando comunque non è collegato a nessun GET o cose simili... Dovrebbero bucarmi il server, ma tanto vale userebbero direttamente la consolle...
    Ma parlo da ignorante in materia di sicurezza, anche se mi interessa molto, perché sono molto paranoico... e magari il server ha tanti di quelle vulnerabilità che nemmeno so... per quanto mi riguarda qualcuno potrebbe esserci pure entrato... a parte che ricevo continuamente tutti i giorni decine di volte visite da programmi di scanning. Solamente su index.php. Perché tutto il resto delle cartelle le ho in sottocartelle rinominate. In genere non uso mai index.php come nome dei file.
    Su index registro tutte le visite...
    Il server è su Aruba, spero ci abbiano già pensato abbastanza i loro esperti a rendere i server difficilmente attaccabili... anche se so che non esiste un server inattaccabile. Forse nemmeno quelli spenti...

    Nei prossimi giorni risponderò, vediamo cosa avrò capisco
    Ti ringrazio molto
  • Re: Calcolo spazio occupato cartella

    La questione della sicurezza è "in profondità".
    A "cipolla".
    Cioè si mettono tanti strati, uno sull'altro, sperando che uno di questi blocchi infine gli attacchi.
    I sistemi sono composti da programmi così complessi che l'esistenza di errori, anche voragini, va data per scontata.
    Dunque non puoi/devi "trustare" niente e nessuno, o almeno il meno possibile.

    Ad esempio quello che non c'è (cioè la funzione o il programma che NON usi, o che meglio ancora non c'è proprio) non si può "rompere" o usare per un attacco.
    Sembra banale, ma non lo è, la storia è piena di "oooppppsss" anche molto gravi
Devi accedere o registrarti per scrivere nel forum
9 risposte