как получить свободное место на жестком диске

Я хочу получить свободный размер жесткого диска в удаленной системе с помощью ssh.
Я нашел следующие способы:
1-do it via command line: hdd's totalsize - sum of partitions size on that hdd + sum of free spaces on all partitions on that hdd;
С этим способом есть некоторые проблемы.
Во-первых, я предпочитаю не использовать команды, т.к. это усложнится, будет полно конвертации типов друг в друга. например, строка для плавания и ... во-вторых, с запущенной командой у меня не может быть свободного места на несмонтированных разделах.
третья проблема в том, что может быть размонтирован сам жесткий диск! другой способ:
2-using statvfs structure.
Опять же, с этой структурой вы можете смонтировать свободное место на жестком диске. код, который я использую:

#include <stdio.h>
#include <sys/statvfs.h>
int main(int argc, const char *argv[])
{

    const unsigned int GB = (1024 * 1024) * 1024;
    struct statvfs buffer;
    int ret = statvfs(argv[1], &buffer);

    if (!ret) {
        const double total = (double)(buffer.f_blocks * buffer.f_bsize) / GB;
        const double available = (double)(buffer.f_bfree * buffer.f_bsize) / GB;
        const double used = total - available;
        const double usedPercentage = (double)(used / total) * (double)100;
        printf("Total: %f --> %.0f\n", total, total);
        printf("Available: %f --> %.0f\n", available, available);
        printf("Used: %f --> %.1f\n", used, used);
        printf("Used Percentage: %f --> %.0f\n", usedPercentage, usedPercentage);
    }
    return ret;
}

Я видел эту ссылку: Получить свободное место на жестком диске в Linux
но выходные данные stat не похожи на числа, которые я вижу в выводе команды df.
Я использую Qt, и моя ОС — Ubuntu 18.04.
когда я запускаю этот код, я получаю это:

heydari.f@swkb-dev2:~/projects/cpptest/build-cpptest-Desktop-Debug$ ./cpptest .
Total: 31.570432 --> 32
Available: 15.594684 --> 16
Used: 15.975748 --> 16.0
Used Percentage: 50.603513 --> 51

и мой вывод df выглядит следующим образом:

heydari.f@swkb-dev2:~$ df -H ~/projects/cpptest/build-cpptest-Desktop-Debug
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1        32G   16G   14G  54% /

РЕДАКТИРОВАТЬ:

heydari.f@swkb-dev2:~/projects/cpptest/build-cpptest-Desktop-Debug$ ./cpptest .
Total: 31.570432 --> 32
Available: 13.967569 --> 14
Used: 17.602863 --> 17.6
Used Percentage: 55.757435 --> 56

person fa7eme    schedule 19.07.2020    source источник


Ответы (1)


вы не даете результатов, которые у вас есть, поэтому я вижу две причины:

Во-первых, у вас может быть переполнение при выполнении buffer.f_blocks * buffer.f_bsize и buffer.f_bfree * buffer.f_bsize, потому что ваши unsigned long находятся на 32b, например:

const double total = ((double) buffer.f_blocks) * buffer.f_bsize / GB;
const double available = ((double) buffer.f_bfree) * buffer.f_bsize / GB;

Второе значение для df 1 ГБ равно 1000*1000*1000, а не 1024*1024*1024.

Если я выполню вашу версию на своем 2Gb PI4, я получу:

pi@raspberrypi:/tmp $ ./a.out .
Total: 3.338009 --> 3
Available: 0.439247 --> 0
Used: 2.898762 --> 2.9
Used Percentage: 86.841044 --> 87
pi@raspberrypi:/tmp $ 

после модификации, чтобы избежать переполнения, я получаю

pi@raspberrypi:/tmp $ ./a.out .
Total: 27.338009 --> 27
Available: 16.439247 --> 16
Used: 10.898762 --> 10.9
Used Percentage: 39.866699 --> 40
pi@raspberrypi:/tmp $ 

в то время как df -H . дает:

pi@raspberrypi:/tmp $ df -H .
Sys. de fichiers Taille Utilisé Dispo Uti% Monté sur
/dev/root           30G     12G   17G  42% /

но

pi@raspberrypi:/tmp $ bc
30*1000*1000*1000/1024/1024/1024
27
pi@raspberrypi:/tmp $ 
person bruno    schedule 19.07.2020
comment
Я изменил эти две строки, но не изменился. а также заменил значение ГБ и все еще такое же. возможно, есть проблема с тем, что я сказал о несмонтированных жестких дисках. при тестировании я даю этот путь: /dev/sda.. Я думаю, что с этим что-то не так. - person fa7eme; 19.07.2020
comment
Я увидел ваш отредактированный см сейчас. так вы говорите, что этот код правильно дает бесплатное хранилище жесткого диска? так почему в моей системе странные результаты?! - person fa7eme; 19.07.2020
comment
@fatemehheydari, вы не даете нам вывод, который у вас есть, и вывод, данный df, и у меня нет волшебного хрустального шара, чтобы угадать все это. Вы используете Ubuntu 64b, чтобы иметь 64b unsigned long? В целом да, для меня результаты в порядке, даже небольшие раунды, сделанные df - person bruno; 19.07.2020
comment
моя убунту 64б. Я добавил эти выводы в вопрос. - person fa7eme; 19.07.2020
comment
@fatemehheydari вместо того, чтобы делать просто df, можете ли вы отредактировать свой вопрос с результатом df ~/projects/cpptest/build-cpptest-Desktop-Debug и/или df -H ~/projects/cpptest/build-cpptest-Desktop-Debug? которые удаляют ненужные строки и позволяют быть уверенным, что вы сравниваете один и тот же раздел - person bruno; 19.07.2020
comment
результат не странный (это было в моем случае из-за переполнения), а просто 14, а не 16, может быть, df использует другой способ получить доступный размер? - person bruno; 19.07.2020
comment
Я снова отредактировал свой вопрос с новым выводом кода. Вы можете видеть, правильно ли это сейчас? - person fa7eme; 19.07.2020
comment
@fatemehheydari, как вы можете видеть, размеры сильно изменились между двумя запусками вашей программы, это означает, что /home быстро меняется из-за других пользователей, если вы хотите сравнить, вам нужно выполнить свою программу и немедленно df (команды могут быть указаны в одной строке, разделенной ';') - person bruno; 19.07.2020
comment
Я также изменил f_bfree на f_bavail в своем коде. Я прочитал здесь: stackoverflow.com/questions /4965355/ что df использует f_bavail вместо f_bfree. большое спасибо. - person fa7eme; 19.07.2020
comment
@RavinderSingh13 спасибо, если не через программу на C, достаточно использовать df - person bruno; 23.07.2020