
そこで、現在のディレクトリ内のすべてのファイルとサブディレクトリ内のすべてのファイルのサイズを再帰的にカウントするスクリプトを作成しています。
#!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 未満である必要があります)。
シェル関数の実装:
#!/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 *
これは役に立ちませんか?