递归脚本中的目录深度

时间:2018-04-25 18:40:04

标签: linux bash shell

嗨,我想得到一些关于我的linux bash homeworks的帮助。 我必须创建一个获取目录的脚本并返回最深子目录的深度(每个目录+1)。 我必须递归地做。 我必须使用'list_dirs.sh'来获取可行的目录并回显它的子目录。

这就是我到目前为止所得到的:

dir=$1
sub=`source list_dirs.sh`

((depth++)) 

for i in $sub
do
  if [ -n "$sub" ] ; then
      ./depthScript $dir/$i
  fi
done

if ((depth > max)) ; then
   max=$depth
   echo $max
fi

用dir测试后回来3我得到了insted:

1
1
1
1

似乎我的深度计数器忘记了以前的值,我得到了输出    每个目录..需要一些帮助!

2 个答案:

答案 0 :(得分:0)

您可以使用bash functions创建递归函数调用。

理想情况下,您的函数在基本情况下回显0,在没有子目录的目录中调用1+$(getDepth $subdir),在存在某些子目录$subdir的情况下回显> T_df <- data.frame(a = runif(101994), b = runif(101994), c = runif(101994)) > object.size(T_df) 2448752 bytes > str(T_df) 'data.frame': 101994 obs. of 3 variables: $ a: num 0.248 0.504 0.197 0.634 0.407 ... $ b: num 0.226 0.686 0.556 0.629 0.412 ... $ c: num 0.959 0.122 0.214 0.666 0.23 ... > > write.csv(T_df,"TFile.csv") 。有关框架,请参阅this question on recursive functions in bash

答案 1 :(得分:0)

当您正常运行脚本时(即它在您的PATH中并且您只需输入其名称,或者输入显式路径,如./depthScript),它将作为子进程运行目前的shell。这很重要,因为每个进程都有自己的变量。变量也有两种:shell变量(仅在一个进程中可用)和环境变量(其值导出到子进程但不从它们备份)。根据您希望变量值可用的位置,有三种不同的方法来定义它们:

# By default, variables are shell variable that's only defined in this process:
shellvar=something

# `export` puts a variable into the environment, so it'll be be exported to subprocesses.
# You can export a variable either while setting it, or as a separate operation:
export envvar=something
export anotherenvvar
anotherenvvar=something

# You can also prefix a command with a variable assignment. This makes an
# environment variable in the command process's environment, but not the current
# shell process's environment:
prefixvar=something ./depthScript $dir/$i

鉴于上述任务:

  • shellvar在当前shell进程中定义,但不在任何其他进程中定义(包括为运行depthScript而创建的子进程)。
  • envvaranotherenvvar将由子进程(及其子进程以及后续命令的所有子进程)继承,但在这些子进程中对其进行的任何更改在当前都没有任何影响过程
  • prefixvar在为运行depthScript(及其子进程)而创建的子进程中仅 ,但不在当前shell进程或其任何其他子进程中。

简短摘要:由于流程结构的原因,它很混乱,因此最好避免尝试在变量之间传递值(或同一脚本的不同调用) 。使用环境变量进行设置,以便您希望一般可用(但不需要进行太多更改)。将shell变量用于特定脚本调用的本地事务。

那么,你应该如何传递深度值?嗯,标准方法是每个脚本(或命令)将其输出打印到&#34;标准输出&#34;,然后使用脚本的任何东西都可以将其输出捕获到文件({{1 }}或变量(command >outfile)。在这种情况下,我推荐后者:

var=$(command)

其他一些建议:

  • 考虑您的控制和数据流。当前脚本循环遍历所有子目录,然后在最后运行对最深子目录的单个检查。但您需要单独检查每个子目录,看它是否比当前最大值更深,最后报告最深处。
  • 双引号变量引用(就像我上面的depth=$(./depthScript "$dir/$i") if ((depth > max)) ; then max=$depth fi 所做的那样)。不带引号的变量引用受到分词和通配符扩展的影响,这是令人悲伤的根源。看起来您需要保留"$dir/$i"不加引号,因为您需要将其拆分为单词,但这会使脚本无法处理带空格的目录名称。请参阅BashFAQ #20: "How can I find and safely handle file names containing newlines, spaces or both?"
  • $sub测试无关紧要。如果if [ -n "$sub" ] ; then为空,则循环将永远不会运行。
  • 在shell脚本中,相对路径(如$sub)相对于父进程的工作目录,到脚本的位置。如果有人从另一个目录运行您的脚本,./depthScript将无效。请改用./depthScript。请参阅BashFAQ #28: "How do I determine the location of my script? I want to read some config files from the same place."
  • 尝试对脚本进行故障排除时,可以帮助将"$BASH_SOURCE"放在麻烦的部分之前。这使得shell在运行时打印每个命令,因此您可以看到正在进行的操作。
  • 通过shellcheck.net运行您的脚本 - 它会指出很多常见错误。