如何在不注销并重新登录的情况下重新加载.bashrc设置?

2164

如果我修改了.bashrc文件,如何在不注销并重新登录的情况下重新加载它?

18个回答

3430

您可以输入完整的命令:

source ~/.bashrc

或者您可以使用该命令的简短版本:

. ~/.bashrc

116
这并不完全等同于登录后退出。举个例子,如果你在.bashrc文件中有以下一行代码:export PATH=$PATH:foo,然后你把它改成了export PATH=$PATH:bar。如果你登录后退出,只有bar会在环境变量PATH中,但是如果按照你建议的做法,foobar都会在PATH中。你知道有什么解决方法吗? - HighCommander4
9
一种不太可靠的实现你想要的方法是执行"bash -l",但这实际上会创建一个新的子shell,在注销后会返回到包含"foo"在PATH中的原始shell。如果只关心PATH变量,可以执行"unset PATH",然后重新构建它,但更简单/更安全的方法是在加载.bashrc之前执行"PATH=/bin:/usr/bin"。在登录时如何构建PATH变量实际上是相当复杂的,至少涉及来自登录(参见"man login")和/etc/profile(参见"man bash")的输入。 - George Hawkins
2
@Alex,你可以通过将行“/.bashrc”添加到“/.bash_profile”中来自动化它,但我不知道这是否是一个好的做法。 - Vivek Gani
6
我建议创建一个别名(你可以将它存储在/.bashrc或/.bash_aliases中),用它打开.bashrc,并在编辑器退出后重新加载它。你可以通过结合两个命令来创建别名,比如这样(如果vim是你喜欢的编辑器,否则更换成其他编辑器):alias editbashrc='vim ~/.bashrc; source ~/.bashrc'。使用这个自定义别名编辑更加流畅,因为不需要考虑在编辑后重新加载文件。 - Samuel Lampa
15
它将 仅仅 影响当前的终端。 - matepal297
显示剩余11条评论

389

或者你可以使用:

exec bash

这样做的效果是一样的,而且更容易记住(至少对我来说是这样)。

exec 命令通过运行指定的命令行完全替换了 shell 进程。在我们的示例中,它使用更新的配置文件将当前的 shell 替换为一个新的 bash 实例。


17
可以,请问您解释一下 source .bashrc 命令和 exec bash 命令的区别吗?
  • source .bashrc 会读取当前用户主目录下的 .bashrc 文件,并将其中的命令执行,这些命令通常是设置环境变量、别名和函数等。
  • exec bash 会启动一个新的 Bash shell,并替换当前 shell 进程。这个新的 shell 会继承当前 shell 的环境变量、别名和函数等设置,但不会执行 .bashrc 文件中的命令。
- muradin
26
@muradin,“source”是一个内置的shell命令,它执行作为参数传递的文件的内容,_在当前的shell中_。因此,在您的示例中,它在当前的shell中执行“.bashrc”文件。而“exec”命令将shell替换为给定的程序,在您的示例中,它用更新的配置文件将您的shell替换为bash。 - WhoSayIn
7
在我超具体的情境下,这个方法非常有效。我的Dockerfile执行了一个安装脚本,修改了.bashrc文件。接着我需要重新加载该文件,但是在dash而不是bash中执行. ~/.bashrc命令会出现错误,因为缺少shopt。由于shell中找不到source命令,所以这个解决方法也不行。我尝试了这个方法后,Docker镜像构建很顺利! - m59
17
优雅,但“做同样的事情”并不完全正确。source ~/.bashrc将保留您的 整个 shell 环境(虽然可能会因为 ~/.bashrc 的源代码而被修改),而 exec bash 只会保留当前 shell 的 _环境变量_(任何针对当前 shell 的临时更改,如 shell 变量、函数、选项都会丢失)。根据您的需要,可以选择其中一种方法。 - mklement0
14
@SEoF,当你说“bash inception”,如果你所想的和我想的一样,我必须说你是错的。与电影不同的是,当你反复执行 exec bash 命令时,并不会像电影中那样不断地从bash进入到bash。在我们的情况下,exec 命令会用程序(即bash)替换 shell。因此,在终端中始终存在一个bash实例。 - John Red
显示剩余12条评论

171
为了补充和对比两个最受欢迎的答案:. ~/.bashrcexec bash
两种解决方案都有效地重新加载~/.bashrc,但存在差异:
- . ~/.bashrcsource ~/.bashrc保留您当前的 shell 会话: 除了重新加载(sourcing)~/.bashrc所做的修改之外,保留了当前 shell 进程及其状态,包括环境变量、shell 变量、shell 选项、shell 函数和命令历史记录。
- exec bash 或更稳健的方法是exec "$BASH" [1], 将用新实例替换您当前的 shell,因此只保留您当前 shell 的环境变量(包括您在会话中定义的临时变量)。 也就是说,在当前 shell 中进行过的任何临时更改,如 shell 变量、shell 函数、shell 选项和命令历史记录都将丢失。
根据您的需求,可能会更喜欢其中一种方法。
注意:上述内容类比于其它 shell也适用: - 要将exec应用于您的默认 shell ,请使用exec $SHELL - 同样,sourcing 方法要求您知道并指定 shell 特定的初始化文件的名称;例如,对于 zsh. ~/.zshrc

[1] exec bash 理论上可以执行一个不同于启动当前shell的可执行文件,如果它恰好存在于$PATH中较早列出的目录中。由于特殊变量$BASH始终包含启动当前shell的可执行文件的完整路径,因此exec "$BASH"保证使用相同的可执行文件。
关于"..."$BASH的注意事项:双引号确保变量值原样使用,而不是Bash解释;如果该值没有嵌入空格或其他shell元字符(在这种情况下很可能),您不严格需要双引号,但使用它们是一个好习惯。


1
你在我还没来得及问之前就回答了我的问题。这很好知道;我经常为单个会话设置我的CLASSPATH。 - swinefish
那么,即使我调用exec "$BASH",在我打开下一个shell(使用与当前会话相同的可执行文件)时,.bashrc设置的变量是否会被找到? - nitinr708
3
是的,执行exec $BASH会加载~/.bashrc文件,因此在新的会话中,您将看到对shell环境所做的更改。 - mklement0
这就是为什么我使用broadcast all + source。在我看来,这是最好的两全其美的选择。 - Nate T
@mklement0 所以如果我调用了 /path/to/different/executable/bash$BASH 将包含该路径,而 $SHELL 则不会在意并包含默认 shell,对吗? - i_want_more_edits
显示剩余3条评论

57

有人编辑了我的答案,添加了错误的英语,但这是原始答案,比被接受的答案差。

. .bashrc

32
只有当当前目录实际上是您的主目录时,这才有效。下面的命令可以生效:. ~/.bashrc - Brian Showalter
6
这是什么让它有效?当我执行“. .bashrc”时,实际上正在发生什么?谢谢! - Jed Daniels
58
“.”是BASH的一个快捷方式,用于调用“source”内置命令。因此,“. .bashrc”在BASH解释器中与“source .bashrc”相同。 - Brian Showalter
8
好的,谢谢。现在我知道了。 - Jed Daniels
3
我刚刚提交了一个编辑请求,添加了 ~/,但由于最佳答案同时显示了 source ~/.bashrc. ~/.bashrc,所以我想知道是否应该删除这个答案,因为它是多余的。 - Max Ghenis
1
@RandyProctor:虽然你指出你的答案比被接受的答案差,这是值得赞扬的,但如果你直接将其删除会更好,因为它不仅明显劣于被接受的答案(只有在当前目录恰好是当前用户的主目录时才有效),而且相反地,没有任何有趣的内容。 - mklement0

24

有了这个,你甚至不需要输入“source ~/.bashrc”:

将你的bashrc文件包含进来:

alias rc="vim ~/.bashrc && source ~/.bashrc"

每次您想编辑您的bashrc时,只需运行别名 "rc"


20

根据您的环境,只需键入

bash

也可能有效。


17
然而,这将在当前的shell内调用一个新的shell,因此会浪费资源。最好使用@WhoSayln的exec解决方案,该方案替换当前的shell为新调用的shell。 - Bernhard Wagner
1
是的,只需使用源代码。这完全是不必要和烦人的。 - dylnmc
除了@BernhardWagner的评论之外,如果您生成一个新的shell,还会丢失当前的bash历史记录。 - Peter Chaula
这是一个很好的解决方案,可以限制用户权限访问。 - Tunde Pizzle
1
调用子进程会增加一层复杂性,但并没有额外的价值。 - Alan Berezin

19

2
exec bash 仍然继承当前 shell 的环境变量。使用 exec env -i bash 可以更接近期望效果(如果您当前在登录 shell 中,则可以使用 exec env -i bash -l)。 - chepner

11

exec bash 是一个很好的重新执行并启动一个新的shell来替换当前shell的方法。只是为了补充答案,$SHELL 返回当前的shell,即bash。通过使用以下命令,可以重新加载当前shell,而不仅仅是bash。

exec $SHELL -l;

1
明确说明一下:$SHELL 反映了当前用户的默认 shell,因此这是用用户的默认 shell 替换当前会话的一种方法 - 无论它可能是哪个 shell 的进程。 -l 使新会话成为“登录”会话,在 macOS 上是适当的(默认只加载 ~/.bash_profile,而不是 ~/.bashrc),但在 Linux 上不是。 - mklement0

10
我使用EasyEngine在Vultr云服务器上搭建了网站。
我在/etc/bash.bashrc发现了我的bash文件。
所以,source /etc/bash.bashrc对我很有帮助!
更新
当设置一个裸机服务器(Ubuntu 16.04)时,如果你还没有设置用户名并通过root用户登录,则可以使用上述信息。
最好创建具有sudo权限的用户,并使用此用户名登录。
这将为您的设置创建一个目录,包括如上所述的.profile.bashrc文件。
现在,您需要编辑并(以及source~/.bashrc文件。
在我的服务器上,该文件位于/home/your_username/.bashrc
(其中your_username实际上是您上面创建的新用户名,并且现在使用该用户名登录)

6
根据您的环境,您可能想添加脚本以使 .bashrc 在打开 SSH 会话时自动加载。我最近迁移到运行 Ubuntu 的服务器,在那里,默认情况下会加载 .profile,而不是.bashrc.bash_profile。要运行 .bashrc 中的任何脚本,每次打开会话时都必须运行 source ~/.bashrc,这对于运行远程部署没有任何帮助。
要在打开会话时自动加载您的.bashrc,请尝试将以下内容添加到.profile:
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        . "$HOME/.bashrc"
    fi
fi

重新打开会话,它应该加载你在.bashrc中的任何路径/脚本。

我在“.profile”文件中设置了这个,但它没有生效——每次退出时,我都必须手动执行。有什么建议吗? - Wayne Smallman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接