我的目录中有 shell 脚本~/Shell
,每当 Bash 作为我常用的用户帐户启动时,我都希望运行这些脚本。所以我所做的是将以下内容添加到~/.bashrc
:
for i in `find ~/Shell/ -name "*.sh"`
do
sh $i
done
.sh
但是,无论出于何种原因,我的目录中具有文件扩展名的文件中包含的函数~/Shell
都不会自动加载。例如,我abash
在~/Shell/bash.sh
文件中调用了一个函数,并abash
从新用户终端运行时出现错误,指出未找到该命令。
我知道我可以手动列出目录中的所有文件,~/Shell
并在它们前面加一个点,以便在 Bash 启动时执行它们。例如,我的文件中曾经有这样的内容~/.bashrc
:
. ~/Shell/bash.sh
. ~/Shell/cd.sh
. ~/Shell/emerge.sh
...
它工作得很好,但我宁愿用一个for
循环来执行此操作,因为这意味着如果我添加任何新的 shell 脚本,~/Shell
我不必担心将它们添加到~/.bashrc
.
我现在也尝试过:
for i in `find -name "~/Shell/*.sh"`
do
sh $i
done
和:
for i in "~/Shell/*.sh"
do
sh $i
done
和:
for i in `find -name '~/Shell/*.sh'`
do
sh $i
done
没有成功。
答案1
将其放入您的.bashrc
:
for rc in ~/Shell/*.sh
do
. "$rc"
done
然后你就可以去参加比赛了!
一些注意事项:
bash
(and zsh
etc)命令source
虽然可读,但不是通用的,并且不存在于dash
我所知道的最正确的 shell 中。就目前而言,相同的代码可用于将代码加载到几乎任何 bourne-shell 衍生产品中。
直接源自 shell 的文件的传统命名约定是使用后缀rc
or .rc
(如.bashrc
)。 rc
代表“运行命令”。该.sh
扩展名通常用于可执行脚本程序。 (这些都是仅有的约定——而不是规则。)
答案2
几个问题:
- 为了工作,波浪号需要取消引用。请改用 $HOME。
- 为了工作,* 也需要取消引用。查找时不需要。
/
文件名(“~/Shell/”)中不应该有用于查找的内容。- 由于文件需要加载而不是执行,所以sh应该改为source。
尝试这个:
for i in $(find "$HOME/Shell/" -iname "*.sh")
do
source "$i"
done
编辑:
上面的选项无法处理带有空格、换行符或有问题字符的文件名。为了解决这个问题,我们可以使用 find 的全部功能,如下所示:
while IFS= read -r -d $'\0' file; do
source "$file"
done < <(find "$HOME/Shell/" -name "*.sh" -type f -print0)
笔记:
带有简单星号的解决方案*
将不包含子目录。
使用星号的完整解决方案将以与 find 相同的方式包含子目录,看起来太复杂了:
resetextglob=$(shopt -p extglob) # store value of extglob
resetnullglob=$(shopt -p nullglob) # store value of nullglob
shopt +s extglob nullglob
for i in $HOME/Shell/*.sh $HOME/Shell/**/*.sh
do
source "$i"
done
$resetextglob # reset extglob to original value
$resetnullglob # reset nullglob to original value