find (fd) 使用自定义函数和多个参数执行

find (fd) 使用自定义函数和多个参数执行

我对 bash 脚本很陌生,所以请原谅我的脚本很粗糙。我正在编写一个简单的脚本,它会遍历所有包含.git目录的目录,并检查工作树是干净的还是脏的。有用,我想要3个参数:

  • rootDir:搜索 .git 目录的顶级目录。
  • status:clean|dirty|all它将根据目录的状态过滤输出
  • 分隔符:允许传递 null 来执行\0分隔符,以便我可以将此输出传递给xargs并进一步运行命令,同时支持带空格的路径。

我面临的问题是将参数从 传递fd exec到我的isRepoDirty函数。该$cleanOrDirty参数以某种方式进入,但该$separator参数不起作用。我的单引号、双引号知识在这里有点不稳定......如果我将参数放在单引号内,它们永远不会被扩展。

这是我所拥有的:

#!/bin/bash
# DOES NOT WORK IN ZSH!
# https://unix.stackexchange.com/questions/50692/executing-user-defined-function-in-a-find-exec-call

rootDir=$1
cleanOrDirty=$2
separator=$3

# echo "Root: $rootDir"
# echo "Clean or Dirty: $cleanOrDirty"
# echo "Separator: $separator"

function isRepoDirty() {
    if [[ $(git --git-dir "$1" --work-tree "$1/.." status --porcelain | wc -l) > 0 ]]; then
        status="dirty"
    else
        status="clean"
    fi

    # echo "Repo: $1, Status: $status"
    if [[ $2 == $status || $2 == "all" ]]; then
        # echo "Separator: $3"
        if [[ $3 == "null" ]]; then
            printf "%b" "$1/..\0"
        else
            echo "$1/.."
        fi
    fi
}
export -f isRepoDirty

fd --no-ignore --hidden -t d "\.git$" $rootDir -x /bin/bash -c 'isRepoDirty "{}" '$cleanOrDirty $separator

如果我的方法完全不对,请告诉我,因为我非常热衷于学习和做被认为是最佳实践的事情。呵呵,我传递的参数有点初级。我还没有找到一种简单的方法可以在 bash 中轻松处理参数-p并设置参数样式。--parameter-name

谢谢你的时间!

答案1

我遇到了类似的问题,并通过添加参数来修复它bash,如下所示:

bash -c 'command "$@"' bash arg1 arg2

正如 Stéphane Chazelas 所指出的,第一个参数被视为$0被调用的命令,因此这将使调试比_我最初的调试更容易。

对于你的情况,我认为答案如下:

fd --no-ignore --hidden -t d '\.git$' "$rootDir" -x /bin/bash -c 'isRepoDirty "$1" "$2" "$3"' bash {} "$cleanOrDirty" "$separator"

请注意,它假设$rootDir不以 开头-,并且$cleanOrDirty和都不$separator包含;或不包含{}, {/}, {//}, {.}, {/.}

为了避免这些情况,您可以使用--选项分隔符,这意味着在模式之前移动-x,并通过环境而不是参数传递这些额外变量的内容:

(
  export cleanOrDirty separator
  exec fd --no-ignore --hidden -t d -x /bin/bash -c '
    isRepoDirty "$1" "$cleanOrDirty" "$separator"
    ' bash {} ';' -- '\.git$' "$rootDir"
)

相关内容