Shell脚本递归不起作用

时间:2014-05-01 01:06:54

标签: bash shell

我有一个shell脚本,可以使用递归函数计算我的所有文件和目录大小 这是我的代码:

#!/bin/bash
count() {
  local file
  total=$2
  files=(`ls $1`)
  for file in "$files"
  do
    if [ -d "$1/$file" ]
    then
      count "$1/$file" $total
    else
      #size=`du $file | grep -o [0-9]*`
      #total=$(($2 + $size))
      echo "$1/$file"
    fi
  done
}
total=0
count . $total
echo "$total"

我有错误它只是进入第一个目录打印文件并停止。哪里是我的错误? :)

3 个答案:

答案 0 :(得分:3)

这一行错了:

for file in "$files"

应该是:

for file in "${files[@]}"

$files只是扩展到数组的第一个元素。

答案 1 :(得分:3)

注意:递归shell函数方法在现实生活中是次优的(假设有du等特定实用程序可以完成工作),但需要满足OP的特定要求。

更新:原始答案错误地只是计算文件而不是确定合并文件大小 - 这已得到纠正。

代码的修订版,演示了几种高级bash技术;请注意,该函数已重命名为sumFileSizes以更好地反映其用途:

  • 声明局部变量,包括-i的一个以将其键入为整数
  • 使用由引用和不引用元素(通配符)组成的字符串,用于安全通配(路径名扩展) - "$1/"*
  • 使用 stdout输出“返回”所需的结果并使用命令替换$(...))捕获它,而不是尝试传递变量“by reference”(bash不直接支持)。
  • 通过stdin(< <(...))使用进程替换来提供命令的输出作为另一个命令的输入。
  • 显示相关的shell选项(设置为shopt),用于管理 globbing (路径名扩展)行为。
#!/bin/bash

  # Recursive function to report the *combined size of all files* 
  # in the specified directory's *subtree*.
sumFileSizes() {
    # Declare the variable as an integer (-i) to ensure
    # that += assignments performs *arithmetic*.
  local -i size=0
  local file
    # Loop over all files/subdirectories      
  for file in "$1/"*; do
    if [[ -d $file ]]; then # item is a *directory*
      # Recurse, adding to the size so far.
      size+=$($FUNCNAME "$file")
    else # a *file*
      # Add this file's size to the size so far.
      # Note: `du` reports `{size} {file}`, so we need to 
      # extract the 1st token, which we do with `read` and
      # process substitution, followed by printing the 1st token 
      # and capturing the output via command substitution.
      size+=$(read thisSize unused < <(du -- "$file"); printf $thisSize)
    fi
  done
    # Output combined size.
  printf $size
}

  # Ensure that:
  # - globs expand to *nothing* in case there are *no* matching files/directories:
  #   option `nullglob`
  # - hidden files/directories (those whose names start with '.') are included:
  #   option `dotglob`
shopt -s nullglob dotglob

  # Make `du` report sizes in KB (this is the default on Linux).
export BLOCKSIZE=1024

  # Invoke the recursive function and capture
  # its outoput.
totalSize=$(sumFileSizes .)

  # Output combined size of all files
  # in multiples of 1KB.
echo "$totalSize"

答案 2 :(得分:1)

如果要以递归方式获取目录的大小,请尝试以下方法:

du -sh

-h用于人类可读,-s用于汇总