【问题标题】:how to find file and run as source script?如何查找文件并作为源脚本运行?
【发布时间】:2021-04-30 20:58:42
【问题描述】:

我的文件夹中有许多包含函数的不同文件。 我使用 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 变量而不是环境变量?

【问题讨论】:

  • …; do if [ -f "$FILE" ]; then source "$FILE"; fi; done.
  • 旁注:避免对FILE等局部变量使用全部大写,因为它应该为HOME等环境变量和RANDOM等特殊shell变量保留。

标签: bash function redeclare


【解决方案1】:

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

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

这可移植到 posix shell(只需将 [[ 更改为 []] 更改为 ])并且通常是这样编写的。我相信你会在/etc/profile 中找到这样的循环。我在bash-completion 脚本中发现了一些类似的东西。

【讨论】:

    【解决方案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 &lt; &lt;(find ~/functions -type f); echo $a:你会得到这个输出:777

    这种行为的原因是带有| 管道的命令正在子shell 中运行,那么子shell 环境 将被修改,而不是当前环境。

    【讨论】:

    • 酷,谢谢。我之前遇到过 subshel​​l 问题,但我一直认为是因为我使用的是 xargs。 Now I know
    【解决方案3】:

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

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

    感谢您的帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-11
      • 2021-04-14
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多