在.bashrc中包含其他文件
1. 概述
我们知道.bashrc 文件将在 Bash shell 交互启动时执行。
它初始化一个交互式 shell 会话。通常,.bashrc文件是放置别名和预定义函数的好地方。
在这个快速教程中,让我们看看如何在*.bashrc*文件中包含其他文件。
2. 问题介绍
有时,为了更容易维护,我们可能希望将一些 Bash 设置或函数保存在单独的文件中,并将它们包含在*.bashrc*中。
但是,如果我们没有正确包含文件,这将失败。让我们看一个例子来快速理解问题。
2.1.附加脚本文件
假设我们有一个脚本文件additional_script.sh:
$ cat /home/kent/bin/additional_script.sh
#!/bin/bash
echo "Loading the additional_script.sh file"
CONF_LOADED=true
alias lecho="echo 'Linux Rocks!'"
#function to print local times of 3 citites
function world_clock {
echo "New York Time:" $(TZ="America/New_York" date +"%F %H:%M:%S")
echo "Paris Time :" $(TZ="Europe/Paris" date +"%F %H:%M:%S")
echo "HongKong Time:" $(TZ="Asia/Hong_Kong" date +"%F %H:%M:%S")
}
echo "additional_script.sh loaded."
在additional_script.sh文件中,我们定义了一个变量、一个别名和一个函数。
2.2. 尝试在*$HOME/.bashrc文件中包含additional_script.sh*
现在,让我们让additional_script.sh文件可执行并在*$HOME/.bashrc*文件中附加一行:
$ tail -1 ~/.bashrc
/home/kent/bin/additional_script.sh
接下来,让我们启动一个新的 Bash shell 并检查 Bash 是否包含了additional_script.sh文件:
$ bash
Loading the additional_script.sh file
additional_script.sh loaded.
我们已经看到了日志消息。似乎 Bash 已找到并包含该文件。伟大的!
让我们做一些测试来验证我们定义的变量、别名和函数是否按预期工作:
$ echo $CONF_LOADED
$ lecho
bash: lecho: command not found
$ world_clock
bash: world_clock: command not found
如上面的输出所示,它们都不起作用。
接下来,让我们弄清楚为什么会发生这种情况以及如何解决问题。
3. 在*$HOME/.bashrc文件中正确包含additional_script.sh*
我们已尝试 通过将脚本文件路径附加到 .bashrc文件来将additional_script.sh文件包含在*.bashrc*中。但它没有按预期工作。
当我们调用或包含另一个脚本文件时,这是一个很常见的陷阱。那么接下来,让我们弄清楚它为什么会发生。
3.1. 执行脚本和采购脚本的区别
当 Bash 看到文件名*/home/kent/bin/additional_script.sh*时,它将执行脚本。
此外,**当 Bash 执行一个脚本时,它会在一个新的 shell 进程中运行它。**这个新的 shell 进程是当前 shell 的子进程。因此,我们也可以将这个新的 shell 称为“子shell”。
如果执行的脚本产生输出,则输出将被复制回当前 shell。这就是我们看到日志消息的原因。
但是,如果脚本导致环境发生任何更改,例如更改变量或声明新的别名或函数,这些更改只会在子shell中生效。 在 Bash 执行完脚本后,子 shell 进程将被终止。因此,对子shell 的更改自然也会丢失。这就解释了为什么变量、新别名和函数在我们当前的 shell 中不起作用。
我们想要实现的是将这些对环境的更改应用到当前 shell。因此,*source *命令正是我们正在寻找的。
简单地说,与执行脚本不同,获取脚本将在当前 shell 中运行脚本中的命令。因此,对环境的所有更改都将在当前 shell 中生效。
3.2. 使用source命令
我们可以使用两种形式中的任何一种来获取脚本:
source SCRIPT_FILE
. SCRIPT_FILE
两种形式的工作方式完全相同。在本教程中,我们将使用第一个。
现在,让我们使用 source命令修复*$HOME/.bashrc*文件中的问题:
$ tail -1 ~/.bashrc
source /home/kent/bin/additional_script.sh
接下来,让我们启动一个新的 Bash shell 并检查脚本文件是否正确包含:
$ bash
Loading the additional_script.sh file
additional_script.sh loaded.
$ echo $CONF_LOADED
true
$ lecho
Linux Rocks!
$ world_clock
New York Time: 2021-09-26 19:07:22
Paris Time : 2021-09-27 01:07:22
HongKong Time: 2021-09-26 07:07:22
这一次,正如我们所见,不仅打印了日志消息,而且CONF_LOADED变量、 lecho别名和world_clock函数都已加载到当前 shell。 所以,我们已经解决了这个问题。
4. 错误处理和包含多个文件
到目前为止,我们已经学会了使用source命令在*.bashrc*中包含一个额外的脚本。
**在我们获取文件之前检查文件是否存在是一个很好的做法。**因此,我们可以这样改进 source命令:
if [ -f /home/kent/bin/additional_script.sh ];
then
source /home/kent/bin/additional_script.sh
else
echo "File Not Found: /home/kent/bin/additional_script.sh"
# ... other error handlings
fi
此外,我们可能希望在*.bashrc*中包含多个文件。我们可以使用循环和数组来检查并包含它们,而不是多次复制“ if ”块:
files_to_source=("/path/to/script1" "/path/to/script2")
for file_to_source in ${files_to_source[@]}
do
if [ -f "$file_to_source" ];
then
source "$file_to_source"
echo "Loaded $file_to_source"
else
echo "File Not Found: $file_to_source"
# ... additional error handlings
fi
done