Skript zum rekursiven Durchgehen von Verzeichnissen funktioniert nicht

Skript zum rekursiven Durchgehen von Verzeichnissen funktioniert nicht

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 vonlsunnö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, returnum die Größe Ihrer Funktion zurückzugeben. Die returnAnweisung 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. duwürde dietatsächlichauf der Festplatte zugewiesene Größe. Der Unterschied liegt darin, wie Sparse-Dateien gezählt werden.

Dasselbe, aber mit dem Befehl findzum Generieren der Verzeichnispfadnamen für die printdirsizeFunktion (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?

verwandte Informationen