腳本不適用於遞歸地遍歷目錄

腳本不適用於遞歸地遍歷目錄

因此,我正在創建一個腳本,以遞歸方式計算當前目錄中所有文件以及子目錄中所有文件的大小:

#!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 "$?"

但是,當我運行腳本時,我得到以下輸出:

/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 是 dir 目錄中的一個文件,當我在目錄上執行 ls -l 時,我不知道為什麼會出現此問題:

 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 ~]$

它表明文件確實存在。

有任何想法嗎?

答案1

程式碼中的主要問題(除了在整個過程中使用不帶引號的變數擴展以及您循環輸出ls不必要地)是您沒有在運行的檔案名稱ls -l前面添加目錄名稱。您還將很難將大小輸出與該大小的目錄配對。

您也可以使用return函數傳回大小。此return語句應用於傳回函數的退出狀態(零表示成功,非零表示失敗,值應小於 256)。

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}"

這將給出明顯的所有目錄的大小。 du會給實際的磁碟上分配的大小。差別在於稀疏文件的計數方式。

相同的事情,但用於find生成函數的目錄路徑名printdirsize(此處提取並用作由 呼叫的內聯腳本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 {} +

與遞歸函數的唯一區別是輸出中目錄的順序可能不同。

答案2

如果您只想知道目錄中所有檔案的大小du -sh *對您來說不起作用?

相關內容