Shell脚本递归行为异常

vqlkdk9b  于 2023-03-09  发布在  Shell
关注(0)|答案(3)|浏览(111)

我有一个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"

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

qlckcl4x

qlckcl4x1#

注意:递归壳函数方法在真实的生活中是次优的(假设有特定的实用程序,如du可以完成这项工作),但需要满足OP的特定要求。
演示了几种高级bash技术的代码修订版本;请注意,该函数已重命名为sumFileSizes,以更好地反映其用途:

  • 声明局部变量,包括使用-i将其类型指定为整数的变量
  • 将由带引号和不带引号的元素(通配符)组成的字符串用于安全全局绑定(路径名扩展)-"$1/"*
  • 使用**stdout输出“返回”所需结果**,并使用命令替换$(...))捕获它,而不是尝试“通过引用”传递变量(bash不直接支持)。
  • 通过stdin(< <(...))使用进程替换将命令的输出作为另一个命令的输入。
  • 显示控制globbing(路径名扩展)行为的相关shell选项(使用shopt设置)。
#!/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"
6yjfywim

6yjfywim2#

这一行是错误的:

for file in "$files"

它应该是:

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

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

yxyvkwin

yxyvkwin3#

如果你想递归地得到一个目录的大小,试试这个:

du -sh

-h表示人类可读,-s表示摘要

相关问题