一个调用自身并返回值的 Bash 脚本

一个调用自身并返回值的 Bash 脚本

我尝试计算目录内的文件数量,同时使用相同的脚本检查子目录并总结结果。

#!/bin/bash

var=0

var=$(ls -l $1 | grep "^-" | tr -s ' ' | cut -d ' ' -f 9 | wc -l)

 for x in `ls -lr $1 | grep "^d" | tr -s ' ' | cut -d ' ' -f 9`;
  do
        output="$($0 $x)"
        var=$((var+output)) 
 done
echo $var

但是我没有得到正确的结果。

我究竟做错了什么?

答案1

$1查找目录及其子目录中的常规文件总数:

find "$1" -type f -printf "1\n" | wc -l

要将该数字保存在变量中:

var=$(find "$1" -type f -printf "1\n" | wc -l)

即使文件或目录名称包含空格或其他困难字符,此方法也能起作用。

讨论

让我们考虑一下原始代码中的这一行:

 for x in `ls -lr $1 | grep "^d" | tr -s ' ' | cut -d ' ' -f 9`;

首先,应该永不解析 ls。它不可靠。 的输出ls会因版本而异。此外,由于特殊字符的处理方式, 显示的名称ls不一定是文件或目录的正确名称。

其次,使用 shell 变量时,例如$1,它们应该放在双引号中。否则,它们会被进行分词和路径名扩展,这会导致各种错误。

第三,形式如下:

for x in `...`

shell 将对命令替换的结果进行分词和路径名扩展。这也可能导致各种错误。

答案2

…我没有得到正确的结果。我做错了什么?

  1. 我不知道;你的脚本对我有用(在非常有限的测试中)。
  2. John1234 讨论了您的方法存在的问题。

我仍在尝试按照自己的方式做事

这是您的脚本的改编版,它(对我而言)有效并且使用更安全的机制:

#!/bin/bash

var=0
shopt -s nullglob

for x in "$1"/*
 do
      if [ -d "$x" ]
      then
            output="$($0 "$x")"
            var=$((var+output))
      else
            var=$((var+1))
      fi
 done
echo $var

这与您的不同之处在于,我的将计算除目录之外的所有目录条目,而您的将不计算非纯文本文件(例如,符号链接、设备节点、命名管道、文件系统套接字等)

shopt -s nullglob用于处理没有内容的目录。)

相关内容