【问题标题】:Bash Recursive Function Call on all elements in a directory [duplicate]Bash递归函数调用目录中的所有元素[重复]
【发布时间】:2018-03-21 01:54:23
【问题描述】:

StackOverflow 上的第一篇文章,第一次使用 Bash。

我目前正在尝试构造一个函数来读取文件,然后根据状态给我输出:

  • 如果是文件,则打印名称、大小和类型
  • 如果是符号链接,则打印名称和目标
  • 如果是目录,则递归调用每个项目的函数。
  • 否则返回“未知”

到目前为止,我知道代码很粗糙,但我真正需要帮助的是递归循环部分。如何使用 While 循环遍历目录的内容?

到目前为止,这是我的代码:

#!/bin/bash

function fileChecker f  {

    if [-e $1 ]; then
        if [ -f $1]; then 
            SIZE = 'du -k $1 | cut -f1'
            CONTENT = 'file $1 | cut -d':' -f2'
            echo $1 +" " +  $SIZE + " " + $CONTENT
    elif[ -h $1 ]; then
        LINK = get info from $1
        echo $1 + " " + "symbolic link " + $LINK
    elif [ -d $1 ]; then 
        while  [ ???? ]; do  
            fileChecker n
        do
    else
        echo $1 + "unknown"
    fi
fi 
}

提前致谢!

【问题讨论】:

  • 这里有一堆错误(与循环无关)shellcheck.net 将捕获。因为这是几个错误,而不是一个,所以单个问题的范围不是很大。
  • 能否请您链接到您提到的问题?我很想看看它的笔记...
  • randomir 实际上在指出特定问题方面做得非常好(另外,如果您通过 shellcheck.net 运行代码,请参阅结果中的 wiki 链接)。也就是说,我确实链接到了与最初呈现的代码中存在的特定错误有关的四个问题——请参阅上面的列表,在顶部的“这个问题已经有答案:”标题下。

标签: bash recursion while-loop directory


【解决方案1】:

没有什么能阻止你递归调用你的函数,像这样:

fileChecker() {
    # ...
    for f in "$1"/*; do
        fileChecker "$f"
    done
}

这是您的脚本,其中包含一些修复 (*),其行为与描述相同:

#!/bin/bash
fileChecker() {
    if [ -f "$1" ]; then 
        size=$(du -k "$1" | cut -f1)
        content=$(file "$1" | cut -d':' -f2)
        echo "$1 $size $content"
    elif [ -h "$1" ]; then
        link=$(readlink -f "$1")
        echo "$1 symbolic link $link"
    elif [ -d "$1" ]; then 
        for f in "$1"/*; do
            [ -e "$f" ] || [ -h "$f" ] && fileChecker "$f"
        done
    else
        echo "$1 unknown"
    fi
}

(*) 修复:

  • [ 命令前后的正确间距
  • 正确引用变量 ("$1")
  • 省略了对文件存在的冗余检查,因为-f 已经检查文件是否存在(并且是常规的)
  • 使用命令替换 $(cmd ...) 而不是反引号(更简单,更易读)
  • 字符串连接固定在echo
  • 使用readlink -f 作为符号链接目标
  • POSIX 合规性(函数定义)

请注意for f in "$1"/* 不会遍历以点开头的文件名(“隐藏文件”)。还要注意在调用fileChecker 之前检查[ -e "$f" ] || [ -h "$f" ],以防止在glob 不扩展的情况下在"$1"/* 上调用它(当目录"$1" 中没有文件时)。

【讨论】:

  • 嗯。可能想尝试更好地处理空目录 - 您将得到 unknown 打印的不存在的文件 * 其中由 glob 表达式返回。除此之外,LGTM。
  • @CharlesDuffy 谢谢,现在看看。有什么更好的处理方法(这似乎不太优雅)?
  • [ -e "$f" ] || [ -L "$f" ],如果我们想通过目标不存在的符号链接进行递归。如果您愿意 (set -- "$1"/*; [ -e "$1" ] || [ -L "$1" ] || return; for arg; do fileChecker "$arg"; done),您可以只测试 "$1"/* 的第一个结果,但我不确定这是否值得。
  • 嗯,是的。但我不认为在不存在的符号链接上递归是 OP 想要的。除此之外,好看吗?谢谢,查尔斯。
  • 是的,我想是的。这已经有一段时间了(自从您第一次编辑切换到符合 POSIX 的函数声明语法以来)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多