我有一个脚本,比如说data.sh
,它获取同一目录中的许多数据文件并对其进行处理。我有许多包含不同文件的目录,但我在所有目录中都有相同的脚本。我可以定期转到每个目录并执行,data.sh
但这./data.sh
很繁琐。
我如何
data.sh
从父目录运行?我最初猜测的 ./parent/dir1/data.sh 不起作用。我想
data.sh
同时执行所有脚本。怎么做?我可以data.sh
通过父目录中的 find 命令找到所有脚本:find . -name data.sh
。如何处理-exec
它们?以下内容与我的第一点有相同的问题:find . -name data.sh -exec ./{} \;
答案1
显而易见的解决方案是改变data.sh
并使其接受一个或多个参数,这些参数是正在处理的文件(也许是目录)。
假设脚本当前包含:
#!/bin/bash
some-command ./* # ← this is where it works on all files
然后你将其更改为:
#!/bin/bash
some-command "$@"
这里,$@
是传递给的所有参数data.sh
,您只需像这样调用它:
/path/to/data.sh /path/to/another/directory/*
然后脚本将在其他目录中的所有文件上运行。当然,如果不知道确切的内部工作原理,data.sh
就不可能具体建议如何更改它。
如果要保持data.sh
原样,则每次调用时都需要更改当前目录。这将使您的脚本“认为”它在另一个目录中。
您可以通过从以下启动的 shell 中使用cd
(或pushd
/ ) 来实现此目的:popd
find
find . -name "data.sh" -exec sh -c 'cd "$(dirname "$0")" && ./data.sh' {} \;
或者你可以暂时cd
将目录放在子 shell 中(这是 周围的括号cd
),也许使用 glob,这样你可以跳过使用find
(**
将递归匹配所有目录):
shopt -s globstar
for script in **/data.sh; do
( cd "$(dirname "$script")" && ./data.sh )
done
如果你没有在上面的命令中使用子 shell,第二次cd
调用将会失败,因为它会尝试cd
从第一个找到的包含 的目录中进行操作data.sh
。你可以使用pushd
/来避免这种情况popd
:
for script in **/data.sh; do
pushd "$(dirname "$script")" && ./data.sh
popd
done