我对 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"
)