因此,我正在创建一个脚本,以递归方式计算当前目录中所有文件以及子目录中所有文件的大小:
#!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 *
适合您?