0

我有许多包含函数的不同文件的文件夹。我使用 declare 将这些功能发布给用户。这是我使用的示例函数:

space () { 
 df -h
} 
declare -f space

在用户 .bashrc 下,我添加了以下内容:

for FILE in $HOME/functions/* ; do source $FILE ; done

但是我收到此消息:

-bash: source: /home/user/functions/subdirectory: is a directory

谁能建议如何解决这个问题,或者有更好的方法将函数加载到 shell 变量而不是环境变量?

4

3 回答 3

4

只需检查文件是否存在。另外,引用变量扩展。首选小写变量。

for file in "$HOME"/functions/* ; do
     if [[ -f "$file" && -r "$file" ]]; then
        source "$file"
     fi
done

这可移植到 posix shell(只需更改[[[和) ]]]并且通常以这种方式编写。我相信你会在你的/etc/profile. 我在bash-completion脚本中发现了一些类似的东西。

于 2021-04-30T22:41:26.873 回答
2

我会这样纠正 xdhmoore 的回答:

while read -d $'\0' file; do
    source "$file"
done < <(find $HOME/functions -type f -print0)

实际上,使用管道将防止修改当前环境,这是该source命令的主要目标之一。

管道问题的示例:让我们~/functions/fff像这样创建文件(假设它是唯一的文件~/functions):

a=777

然后运行find ~/functions -type f | while read f; do source "$f"; done; echo $a:你将没有输出。

然后运行while read f; do source "$f"; done < <(find ~/functions -type f); echo $a:你会得到这个输出:777

该行为的原因是管道命令|正在子shell中运行,然后将修改子shell环境,而不是当前环境。

于 2021-04-30T21:48:29.650 回答
0

感谢所有答案,这是对我有用的更新。

MYFUNC=$(find ~/functions -type f)
for f in $MYFUNC ; do
source $f > /dev/null 2>&1
done

感谢帮助

于 2021-05-01T07:13:55.237 回答