Como obter um mapa de uso de disco no linux?

0

Eu gostaria de criar um mapa dos arquivos que estão gravados no disco rígido. Ele deve produzir algo como uma árvore de diretórios e, para cada arquivo, uma lista de setores ([10-20], [80-90], [60-70]) que se juntam para compor o arquivo inteiro. por exemplo. para criar uma visualização como o desfragmentador de disco do Windows da velha escola:

Existe alguma ferramenta disponível para isso?

    
por Scott 14.02.2018 / 20:17

2 respostas

2

A ferramenta padrão nas derivações do Debian é Disk Usage Analyser ( baobab ), mas isso não mostrará fragmentação.

A única maneira que eu sei de mostrar fragmentação é usar um processo de linha de comando em uma base arquivo a arquivo, usando uma das ferramentas descritas em esta resposta .

Para esse fim, escrevi um script usando hdparm --fibmap : -

#!/bin/bash
#
# frags MountPoint SkipFrags    Reports all files under MountPoint with more than SkipFrags fragments
#       MountPoint defaults to / (root file system)
#       SkipFrags  defaults to 1 (report all files with more than one fragment)
#                  (setting to 0 will report all files, including unfragmanted)
#
# The report is sorted in fragment count order and must be run as root 
#
[ "${1:0:1}" == "-" ] && \
    echo 'frags MountPoint SkipFrags    Reports all files under MountPoint with more than SkipFrags fragments' && \
    echo '      MountPoint defaults to / (root file system)' && \
    echo '      SkipFrags  defaults to 1 (report all files with more than one fragment)' && \
    echo '                 (setting to 0 will report all files, including unfragmanted)' && \
    echo 'The report is sorted in fragment count order and must be run as root' && \
    { return 1 2>/dev/null; exit 1; }
[ "$(whoami)" != "root" ] && { echo 'Must be run from "root"' >&2; return 13 2>/dev/null; exit 13; }
eof='***EOF***'    ; # End-of-file marker
{ find "$1"/ -mount -type f; echo "$eof"; } | \
    while read -r f; \
        do  [ "$f" == "$eof" ] && { echo -ne "\e[K" >&2; continue; }; \
            r=$(hdparm --fibmap "$f" | grep -E "^[ 0-9]+$" | wc -l); \
            [ $r -gt "${2:-1}" ] && { echo -ne "\e[K--- $r: ${f::$(($COLUMNS-${#r}-6))}\r" >&2; echo "$r: $f"; } \
        done | \
sort -nt :

Observe que, embora eu tenha documentado o script como um disco inteiro do seu ponto de montagem, você pode obter os resultados classificados para um diretório específico, e eu recomendo fazer isso inicialmente em um diretório pequeno para ter certeza de que ele fornece resultados sensatos.

O processo é bastante lento, e a classificação significa que você não obtém nenhum resultado até que cada arquivo tenha sido varrido, então eu adicionei um diagnóstico em stderr à medida que cada arquivo a ser reportado é encontrado. A seqüência de escape é para xterm e depende de $COLUMNS sendo definido por shopt -s checkwinsize; export COLUMNS in ~/.bashrc (ou outro arquivo de inicialização). Evitar feeds de linha impede que o script seja atrasado rolando.

Eu usei [ ... ] && em vez de if [ ... ]; then para reduzir o aninhamento e abreviar o script. A sequência return 1 2>/dev/null; exit 1; é um truque que eu escolhi para retornar um código de erro, independentemente de o script ser chamado normalmente ou de um comando . / source .

    
por 15.02.2018 / 21:28
0

Eu normalmente escrevo em python, então se alguém estiver interessado em uma versão python da resposta do AFH. Mina depende do comando filefrag . Isso percorre a árvore de diretórios, iniciando no argumento cli root e coleta o nome do arquivo, o tamanho do arquivo e as extensões do bloco. Pode ser útil adicionar argumentos para especificar o tamanho do bloco e, se necessário,

import subprocess
import os
import re
import argparse

size = re.compile("(\d+) \(\d+ block")

def get_extents(root):
    for root, dirs, files in os.walk(root):
        for f in files:
            fullpath = os.path.abspath(os.path.join(root, f))
            output = subprocess.check_output(["filefrag", "-e", "-v", fullpath]).decode("utf-8")
            lines = output.splitlines()
            sizeline = lines[1]
            extentlines = lines[3:-1]
            print(fullpath)
            print("size in bytes:", size.search(sizeline).group(1))
            extents = []
            for extentline in extentlines:
                stuff = extentline.split()
                lower = stuff[3].strip(".")
                upper = stuff[4].strip(":")
                extents.append((lower, upper))
            print("extents:", extents)

if __name__ == "__main__":
    parser = argparse.ArgumentParser("get the extents of all the files")
    parser.add_argument("root", type=os.path.expanduser, help="the root folder to examine recursively on")

    args = parser.parse_args()
    get_extents(args.root)
    
por 20.02.2018 / 18:15