
Daher erstelle ich ein Skript, das die Größe aller Dateien im aktuellen Verzeichnis und aller Dateien in den Unterverzeichnissen rekursiv zählt:
#!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 "$?"
Wenn ich das Skript ausführe, erhalte ich jedoch die folgende Ausgabe:
/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 ist eine Datei im Verzeichnis „dir“ und ich weiß nicht, warum dieses Problem auftritt, wenn es doch eindeutig ist, wenn ich „ls -l“ auf das Verzeichnis ausführe:
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 ~]$
Es zeigt, dass die Datei tatsächlich existiert.
Irgendwelche Ideen?
Antwort1
Das Hauptproblem in Ihrem Code (abgesehen davon, dass Sie überall Variablenerweiterungen ohne Anführungszeichen verwenden und dass SieSchleife über die Ausgabe vonls
unnötigerweise) ist, dass Sie dem Dateinamen, den Sie ausführen, nicht den Verzeichnisnamen voranstellen ls -l
. Sie hätten auch Schwierigkeiten, die Größenausgabe dem Verzeichnis zuzuordnen, dessen Größe dies ist.
Sie verwenden es auch, return
um die Größe Ihrer Funktion zurückzugeben. Die return
Anweisung sollte verwendet werden, um den Beendigungsstatus der Funktion zurückzugeben (Null bedeutet Erfolg, ungleich Null bedeutet Fehler, Werte sollten kleiner als 256 sein).
Implementierung der Shell-Funktion:
#!/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}"
Dies würde demersichtlichGröße aller Verzeichnisse. du
würde dietatsächlichauf der Festplatte zugewiesene Größe. Der Unterschied liegt darin, wie Sparse-Dateien gezählt werden.
Dasselbe, aber mit dem Befehl find
zum Generieren der Verzeichnispfadnamen für die printdirsize
Funktion (hier extrahiert und als Inline-Skript verwendet, das von aufgerufen wird 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 {} +
Der einzige Unterschied zur rekursiven Funktion besteht darin, dass die Reihenfolge der Verzeichnisse in der Ausgabe unterschiedlich sein kann.
Antwort2
Wenn Sie nur die Größe aller Dateien in Ihrem Verzeichnis möchten, wäre du -sh *
das für Sie nicht möglich?