1

我想找到当前工作目录及其子目录中的所有目录,它们要么是 git 存储库的根目录,要么根本不被 git 跟踪。

为此,我编写了这个 bash 脚本:

#!/bin/bash
export FOUND_UNTRACKED=0
export FOUND_TRACKED=
find . -type d \( \( -exec test -d {}\.git \; -exec /bin/bash -c "export FOUND_TRACKED=$1:$FOUND_TRACKED" {} \; -prune \) -o -exec echo Untracked directory: {} \; -exec /bin/bash -c "export FOUND_UNTRACKED=1" \; \)

echo $FOUND_UNTRACKED
echo $FOUND_TRACKED

find 工作正常,但不幸的是,对 exec 内部环境变量的更改没有传播。即,FOUND_TRACKED始终为空,FOUND_UNTRACKED为0。

知道如何让这些东西工作吗?

4

3 回答 3

1

进程从父进程继承环境。没有简单的机制来影响父环境:子进程可以改变自己的环境,但是当子进程退出时,它会被简单地丢弃。您 bash 脚本find在一个子进程中启动,而该子进程又在另一个子进程中启动另一个bash

解决此问题的一种方法是使子进程创建输出,然后父进程对其进行解释。这是一个简单的例子:

files="$( /bin/ls )"
if [ "$files" ]; then
    echo "found some files"
else
    echo "no files there"
fi

如果您需要来自子进程的更复杂的反馈,您可以mktemp在父进程中创建一个临时文件(使用 ),并让子进程将其输出保存到该文件,以便在子进程完成后您可以在父进程中处理输出.

于 2011-04-17T10:12:37.890 回答
0

将导出移到 find 之外,因为它将在子 shell 中运行,因此任何导出的变量都只会位于该 shell 中。

于 2011-04-17T10:12:54.307 回答
0

虽然我同意其他答案 - 我无法为 git 用户找到您的 find 表达式的实用程序。.git 目录仅位于根目录...因此您最终将 git 的子目录报告为“未跟踪”,这是不正确的。

这与 CVS 等其他 SCM 不同,其中每个目录级别都有一个 CVS 目录

于 2011-04-17T13:25:24.493 回答