
Así que estoy creando un script que cuenta el tamaño de todos los archivos en el directorio actual y todos los archivos en los subdirectorios de forma recursiva:
#!bin/bash
Count () {
size=0
items=`ls "${1}/"`
for item in $items
do
if [ ! -d $item ]
then
cursize=`ls -l $item | awk '{ print $6 }'`
size=$[$size+$cursize]
else
echo "$1/$item"
Count $1/$item
size=$[$size+$?]
fi
done
echo "Done"
return $size
}
Count ~
echo "$?"
Sin embargo, cuando ejecuto el script obtengo el siguiente resultado:
/home/161161/backup
Done
/home/161161/dir
ls: xoe1.txt: No such file or directory
script.sh: line 11: 28+: syntax error: operand expected (error token is "+")
1
xoe1.txt es un archivo dentro del directorio dir y no sé por qué genera este problema cuando claramente hago un ls -l en el directorio:
ls -l dir
total 4
-rw-r--r-- 1 161161 domain users 23 Jun 2 22:55 test1.txt
-rw-r--r-- 1 161161 domain users 0 Jun 2 15:27 test2.txt
-rw-r--r-- 1 161161 domain users 0 Jun 2 15:27 test3.txt
-rw-r--r-- 1 161161 domain users 0 Jun 2 22:42 xoe1.txt <--
-rw-r--r-- 1 161161 domain users 0 Jun 2 22:42 xor1.txt
[161161@os ~]$
Muestra que el archivo de hecho existe.
¿Algunas ideas?
Respuesta1
El problema principal en su código (aparte de usar expansiones de variables sin comillas en todo momento y que estárecorriendo la salida dels
innecesariamente) es que no antepone el nombre del archivo que ejecuta ls -l
con su nombre de directorio. También tendría dificultades para emparejar el tamaño de salida con el directorio cuyo tamaño es.
También está utilizando return
para devolver el tamaño de su función. La return
declaración debe usarse para devolver el estado de salida de la función (cero es éxito, distinto de cero es fracaso, los valores deben ser menores que 256).
Implementación de la función 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}"
Esto daría laaparenteTamaño de todos los directorios. du
daría elactualtamaño asignado en el disco. La diferencia está en cómo se contarían los archivos dispersos.
Lo mismo, pero usándolo find
para generar los nombres de ruta del directorio para la printdirsize
función (aquí extraído y usado como un script en línea llamado 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 {} +
La única diferencia con la función recursiva es que el orden de los directorios en la salida puede ser diferente.
Respuesta2
¿Si solo desea que el tamaño de todos los archivos en su directorio du -sh *
no funcione para usted?