我有一个包含一些脚本文件的目录:
/scripts
api.sh
time.sh
certificate.sh
docker.sh
nginx.sh
wifi.sh
...
这些脚本不是命令。它们只是包含一些功能。因此我无法添加/script
并$PATH
运行它们。例如api.sh
有这样的内容:
function isApi()
{
# body
}
function resetApi()
{
# body
}
function testDatabase()
{
# body
}
我需要将它们包含在当前会话中,然后调用它们的函数。
如果我将它们一一包括在内,. /scripts/x.sh
我就可以使用它们的功能。
但是当我运行loadScripts.sh
bash 脚本来加载它们时,它不起作用:
find /scripts -mindepth 1 |
while read scriptFile;
do
echo $scriptFile
source $scriptFile
done
如何在当前会话中包含目录的所有脚本?
答案1
只是:
for script in scripts/*.sh; do
. "$script"
done
特殊.
的 sh 内置命令告诉 shell 评估所提供文件中的代码。 csh 具有source
类似的命令,某些 shell 支持bash
这两种命令.
,source
有时语义略有不同。
您还需要确保在 上使用.
/ 。这样做会启动一个新的 shell 来解释脚本,因此在该短暂的 shell 中定义这些函数,而不是在调用的 shell 中。source
loadScripts.sh
./loadScripts.sh
还要确保 a包含在传递给/ 的/
路径中,例如通过在当前工作目录中运行 if ,否则其路径可能会在 中查找。.
source
. ./loadScripts.sh
$PATH
这样做find... | while read...; do . ...; done
是错误的,首先是因为上面提到的所有原因为什么循环查找的输出是不好的做法?,但也是因为在多个 shell 中,包括未启用bash
该选项时,循环将在子 shell 中运行,因此源文件中的函数只会在该子 shell 中定义。lastpipe
while
如果您想使用4.4 或更高版本find
,但要注意find
不对文件列表进行排序并包含隐藏文件bash
,您可以这样做:
while IFS= read -rd '' -u3 script; do
. "$script"
done 3< <(LC_ALL=C find scripts/ -mindepth 1 -maxdepth 1 -name '*.sh' -type f -print0)
这里添加一个-type f
(以限制类型的文件常规的)来证明使用的合理性find
。
如果使用zsh
而不是bash
,你可以这样做:
for script (scripts/*(ND.)) . $script
作为等效文件(.
仅限于常规文件,并D
包括隐藏文件)。
或者:
for script (scripts/*(ND.)) emulate sh -c '. $script'
如果这些脚本的sh
语法如.sh
扩展所建议的那样。
posix
¹ 无论该选项是否启用,bash 在这方面的行为都会有所不同。