bash:在find';首席执行官

bash:在find';首席执行官,bash,find,environment-variables,env,Bash,Find,Environment Variables,Env,我希望找到当前工作目录及其子目录中的所有目录,它们要么是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 \) -

我希望找到当前工作目录及其子目录中的所有目录,它们要么是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\u TRACKED
始终为空,
FOUND\u UNTRACKED
为0


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

一个进程从父进程继承环境。没有一种简单的机制可以影响父进程的环境:子进程可以更改自己的环境,但当子进程退出时,它就会被丢弃。bash脚本在子进程中启动
find
,然后在另一个子进程中启动另一个
bash

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

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

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

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

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

这与其他SCM(如CVS)不同,后者在每个目录级别都有一个CVS目录