O principal problema em seu código (além de usar expansões variáveis sem aspas e de estar em loop sobre a saída de ls
desnecessariamente) é que você não prefixará o nome do arquivo com o qual você executa ls -l
com o nome do diretório. Você também teria dificuldades em emparelhar a saída de tamanho com o diretório de que esse é o tamanho.
Você também está usando return
para retornar o tamanho da sua função. A declaração return
deve ser usada para retornar o status de saída da função (zero é sucesso, não-zero é falha, valores devem ser menores que 256).
Implementação da função shell:
#!/bin/bash
# Uses stat to get the total size in bytes of all files in the directory
# given on the function's command line. Assumes Linux "stat".
printdirsize () {
local dir="$1"
local sum=0
shopt -s dotglob nullglob
for filename in "$dir"/*; do
[ ! -f "$filename" ] && continue # skip non-regular files
size=$( stat -c %s "$filename" )
sum=$(( sum + size ))
done
printf 'Directory=%s\nSize=%d\n' "$dir" "$sum"
}
# Walks the directory tree from the given directory, calls printdirsize
# (above) and then descends into the subdirectories recursively.
dirwalker () {
local dir="$1"
printdirsize "$dir"
shopt -s dotglob nullglob
for filename in "$dir"/*; do
[ ! -d "$filename" ] && continue # skip non-directories
dirwalker "$filename"
done
}
# Start in the directory given on the command line, or use $HOME if
# nothing was given
dirwalker "${1:-$HOME}"
Isso daria o tamanho aparente de todos os diretórios. du
daria o tamanho real alocado no disco. A diferença está em como os arquivos esparsos seriam contados.
A mesma coisa, mas usando find
para gerar os nomes de caminho do diretório para a função printdirsize
(aqui extraída e usada como um script in-line chamado por find
):
#!/bin/sh
find "${1:-$HOME}" -type d -exec bash -O dotglob -O nullglob -c '
for dir do
sum=0
for filename in "$dir"/*; do
[ ! -f "$filename" ] && continue # skip non-regular files
size=$( stat -c %s "$filename" )
sum=$(( sum + size ))
done
printf "Directory=%s\nSize=%d\n" "$dir" "$sum"
done' bash {} +
A única diferença da função recursiva é que a ordem dos diretórios na saída pode ser diferente.