如何使用其参数在多个目录上执行 bash 脚本?

如何使用其参数在多个目录上执行 bash 脚本?

我有一个 shell 脚本app1.sh和一棵文件夹树,但我不知道如何在每个文件夹内执行此 shell。这是app1.sh脚本

该脚本接收一个字符串、一个整数和一个文件作为工作参数。这个想法是在一个目录内的 4 个文件夹中执行它。

感谢你的帮助 :)

答案1

(忽略问题标题中的“参数”,因为没有进一步解释)假设脚本app1.sh位于当前目录中,并且您希望在当前目录中的每个目录和子目录中执行此脚本:

shopt -s globstar nullglob dotglob

runme=$PWD/app1.sh

for folder in ./**/; do
    ( cd "$folder" && "$runme" )
done

这使用**通配模式(通过globstarshell 选项启用)来查找所有目录。然后它循环遍历这些目录并使用cd将目录更改为每个目录,然后将该目录作为当前工作目录执行脚本。

如果您只想处理最顶层的目录(而不是其子目录),请删除globdot并更改./**/./*/.

shellnullglob选项设置为如果模式不匹配(没有目录)则根本不执行循环,并且dotglob设置 shell 选项以便我们也匹配隐藏目录。

循环体周围的括号将命令括在子 shell 中。当前工作目录是子 shell 的本地目录,这意味着cd执行脚本后我们不必“再次退出”。


使用find

runme=$PWD/app1.sh

find . -type d -exec sh -c '
    runme=$1; shift
    for folder do
        ( cd "$folder" && "$runme" )
    done' sh "$runme" {} +

这做了同样的事情(几乎;这不会解析目录的符号链接,并且它还会找到当前的目录)。对于批量找到的目录,它调用一个简短的内联 shell 脚本。该脚本选择要运行的脚本的路径名,然后迭代剩余的参数(找到的目录),更改为目录,并运行脚本。

如果您只想处理最顶层的目录(而不是其子目录),请将-maxdepth 1测试添加到命令中find

find . -maxdepth 1 ...as before...

如果您不想处理当前目录,请按照与上面类似的方式将-mindepth 1或添加-name . -prune -o到命令中。另一种方法是使用find ./*/ ...当前目录中的所有目录作为搜索路径,但如果您有以下情况,则会失败并出现“参数列表太长”错误数千当前目录中的目录(如果您只想要这些顶级目录,则还必须更改-maxdepth 1为,但在这种情况下我会诚实地使用普通的 shell 循环)。-maxdepth 0

-mindepth都是-maxdepth非标准测试,但普遍实施。

有关的:

答案2

您可以使用findwith-type d来实现:

$ PWD=$(pwd); SCRIPT=/full/path/to/script.sh; find . -type d -exec bash -c "cd {}; $SCRIPT; cd $PWD" ";"

一用-execdir就能避免cd $PWD

$ SCRIPT=/full/path/to/script.sh; find . -type d -execdir bash -c "cd {}; $SCRIPT" ";"

相关内容