.bashrc在SSH登录时的作用

470

当我通过ssh连接到运行Hardy 8.04的ubuntu-box时,我的.bashrc中的环境变量没有设置。

如果我执行source .bashrc,则变量被正确设置,一切正常。

.bashrc为什么不在登录时运行?


122
这怎么可能是“离题”的? - Jonah
15
我不是很苛刻,但我的猜测是这篇内容应该放在serverfault.com、superuser.com或者askubuntu.com上。 - Michael Butler
18
同意。不知道他们为什么不把它搬走而只是关闭它... - Luc
4
@Luc-问题只能在创建后的60天内移动。这个问题直到创建3年半后才被关闭为离题。我认为这个60天的规定与问题数据库何时备份有关......在备份发生后,迁移变得更加困难。 - ArtOfWarfare
3
我认为这是一个非常有用的问题。当我需要通过ssh进入A机器,以便通过A本地网络访问B机器时,遇到了这个问题。这教会了我一个实际的区别,即.bashrc.bash_profile之间的区别! - information_interchange
这里提供了一个很好的答案:https://unix.stackexchange.com/a/332533/393910。 - Sasan
6个回答

814

使用 SSH 登录时,.bashrc 不会被自动加载。您需要在 .bash_profile 中像这样手动加载:

if [ -f ~/.bashrc ]; then
  . ~/.bashrc
fi

45
这应该适用于任何使用Bash的健全的发行版,因此所有这些注释都已过时 :) - user529649
7
更正一下,是这样的 :) 存在一个不正常的 .bash_profile 文件,导致 .profile 被跳过。 - Lester Peabody
5
像@LesterPeabody一样,我的.bashrc在Ubuntu 12.04 LTS服务器上没有被调用,因为有一个流氓的.bash_profile。它是由RVM安装创建的。我将RVM命令移到了.profile文件中并删除了.bash_profile文件。现在一切都运行良好。 - Rod Daunoravicius
7
值得一提的是,Debian Jessie/8已经默认源码.bashrc文件了 - 但是它是从.profile而不是.bash_profile中读取的。 - underscore_d
3
为什么是. ~/.bashrc而不是source ~/.bashrc - PlasmaBinturong
显示剩余10条评论

108

我有类似于Hobhouse的情况。我想使用命令

ssh myhost.com 'some_command'

/var/some_location中存在some_command

我尝试通过编辑$HOME/.bashrc/var/some_location添加到PATH环境变量中,但这并没有起作用。因为默认情况下,在Ubuntu 10.4 LTS上,.bashrc会由于以下代码而提前退出:

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

如果你想要改变ssh非登录shell的环境,你需要在该行代码上方添加代码。


1
酷炫的技巧,我在从Jenkins运行脚本时遇到了这个陷阱。我通过SSH登录就可以运行成功,但是Jenkins以非交互方式登录就会失败。 - Krzysztof Jabłoński
1
为什么通常的解决方案是甚至不为非交互式 shell 设置新路径,这超出了我的理解。应该有相当多的内容在那个语句之上,就是为了这个原因。似乎只有别名和交互式工具的初始化应该放在那行下面... - BenPen
5
在其他版本的Ubuntu中,交互式检查看起来像这样:# 如果不是交互式运行,则不执行任何操作 case $- in *i*) ;; *) return;; esac - Sylvain
谢谢,这个解决了我的问题。要是我一个小时前看到就好了! - Justin Lawrence
man ssh: "如果指定了命令,则在远程主机上执行该命令,而不是登录shell。" 对于我在Fedora Core 29上运行命令时(并且没有命令调用),它既不调用.bashrc也不调用.bash_profile - Yaroslav Nikitenko
一直在寻找如何通过单个命令轻松部署我的应用程序。谢谢,伙计,我希望几个月前就能找到这个。我甚至开始编写一个应用程序来简化我的部署。 - Shahid Kamal

38

如果你想了解bash调用的工作原理、每个dotfile的作用,以及如何使用/配置它们,请阅读以下优秀资源:


关键句: "导致它读取 /etc/profile,然后是 .bash_profile 或 .bash_login 或 .profile 中的一个。" - Andy Hayden

37
如果 ayman 的解决方案无效,尝试将文件命名为 .profile 而非 .bash_profile。这对我起了作用。

2
太棒了。我在这个细节上浪费了15分钟。 - vmassuchetto
1
我认为 .profile 文件在 GUI 登录时加载,而 .bash_profile 文件则是用于终端登录。 - Razec Luar
这也适用于SSH登录到Debian Jessie Docker容器(使用数据容器进行持久存储)- 但您可能还想检查/etc/passwd以检查您的登录shell是否为/bin/bash而不是/bin/sh -------> /bin/dash。 - Stuart Cardall
2
@RazecLuar,无论登录 shell 是否打算生成 GUI,都会执行 .profile。您的评论完全与问题和答案相矛盾,这些答案明确表明 .profile 在 SSH 登录时被调用 - 这是一种明显非 GUI 的方法。 - underscore_d

1
我知道这是一个老问题,但我在Ubuntu 22.04上遇到了同样的问题。
我有两台完全相同的服务器,其中一台正确地源码了`~/.bashrc`,我通过ssh登录后可以看到颜色,而另一台则没有。
这两台服务器都有完全相同的`~/.bashrc`文件。
在我的情况下,问题出现在我使用单行命令在其中一台服务器上安装golang时,它添加了新的文件`~/.bash_profile`。
该文件只有三个导出路径设置,所以由于某种原因,当我通过ssh登录时,这个文件被源码,而不是`~/.bashrc`。
删除`.bash_profile`并只保留`.bashrc`对我来说解决了问题,或者你可以按照@swaz的建议保留两个文件。

0

和 @Loïc Wolff 类似,我在我的 $HOME/.bash_profile 中添加了以下内容 Ubuntu 16

if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
        echo "Executed .bash_profile , calling .bashrc"
        . "$HOME/.bashrc"
    fi
fi

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