![如何使用其参数在多个目录上执行 bash 脚本?](https://linux22.com/image/166533/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%E5%85%B6%E5%8F%82%E6%95%B0%E5%9C%A8%E5%A4%9A%E4%B8%AA%E7%9B%AE%E5%BD%95%E4%B8%8A%E6%89%A7%E8%A1%8C%20bash%20%E8%84%9A%E6%9C%AC%EF%BC%9F%20.png)
答案1
(忽略问题标题中的“参数”,因为没有进一步解释)假设脚本app1.sh
位于当前目录中,并且您希望在当前目录中的每个目录和子目录中执行此脚本:
shopt -s globstar nullglob dotglob
runme=$PWD/app1.sh
for folder in ./**/; do
( cd "$folder" && "$runme" )
done
这使用**
通配模式(通过globstar
shell 选项启用)来查找所有目录。然后它循环遍历这些目录并使用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
您可以使用find
with-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" ";"