在Ubuntu中遇到了.profile和.bashrc的问题

4

我是初学者,对Linux不太熟悉。目前正在网上学习如何设置Kafka。教程指出需要将Kafka二进制文件所在路径添加到 .profile 文件中,如下所示:

# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi

# set PATH so it includes user's private bin directories
DOCKER="/usr/local/bin/docker-compose"
PATH="$HOME/bin:$HOME/.local/bin:$PATH:$DOCKER"
# Ubuntu make installation of Ubuntu Make binary symlink
PATH=/home/username/.local/share/umake/bin:$PATH
cat ~/.ssh/config.d/* > ~/.ssh/config
PATH="$PATH:/home/username/softwares/kafka/kafka_2.11-1.0.0/bin"

接着,我在$PATH上执行了echo命令,我可以看到kafka路径已经添加到了$PATH变量中。然后,我输入了kafka并按下tab键,然后我就可以看到与kafka相关的可选命令。

教程随后告诉我们要编辑.bashrc文件。它已经存在了,而且是一个相当大的文件。按照教程的要求,我在文件末尾添加了以下行:

. ~/.profile

此后,按照教程,我打开了另一个终端,以便查看在kafka和tab之后仍然能够获得与kafka相关的所有选项。我发现终端上没有显示我的用户名,只有一个空白的终端窗口。然后,我编辑了.bashrc文件以删除我添加的行,并尝试打开一个新的终端,这时可以在终端上看到我的用户名。接着,我关闭了所有终端,打开了一个新的终端并输入kafka和tab,但是没有像之前一样出现任何选项。然后,我打开了.profile文件,并发现kafka路径仍然被添加了。然后,我尝试执行echo $PATH命令,但是这次却没有看到kafka路径。
我非常困惑这里发生了什么。您能否请解释一下,并告诉我如何每次打开终端都加载.profile文件,以及为什么在对PATH执行echo时不再看到kafka路径?

在你添加任何内容到 .bashrc 后,你必须source你的 .bashrc 才能看到更改。因此,在进行更改后,在命令提示符下输入. ~/.bashrc(这是“点空格 ~/.bashrc”)。 - David C. Rankin
当我执行此操作时,命令没有结束,我不得不按Ctrl + C退出。然后我尝试打开一个新终端,但我又得到了一个空白终端。 - T Anna
这意味着您在.bashrc文件中弄乱了一些东西,导致它无法清洗源代码。以root (或另一个用户和su)的身份登录,然后切换到您的用户目录并编辑您的~/.bashrc文件,删除有问题的内容即可。 - David C. Rankin
1个回答

9

正在发生什么:

源码:

当你运行 . somefile 命令时,它会将该文件源到当前的 shell 中,这基本上意味着它在当前的 shell 中运行 somefile 文件中的每个命令。

某些文件在特定条件下会自动被 source。

Shell 类型:

交互式 Shell:用于输入命令和接收输出的 Shell。在 bash 中,你可以通过以下方式创建一个交互式 Shell:

  1. 使用 bash Shell 登录
  2. 从终端运行 bash

登录 Shell:第一次登录时创建的 Shell。即当你首次 ssh 进入服务器或登录到没有 GUI 的机器时获得的 shell。

非登录交互式 Shell:不是登录 Shell 但是具有交互性质的 Shell。即在打开桌面终端应用程序或在使用 ssh 登录后运行 bash 获得的 shell。

~/.profile 和 ~/.bash_profile,以及 ~/.bash_login 可以被登录 Shell 自动 Source。所以,当你第一次登录或手动 Source(.).profile 时,可能会得到这个路径。

请注意,如果 .bash_profile 存在且可读,则 Bash 不会读取 .bash_login 或 .profile。https://askubuntu.com/questions/98433/run-a-script-on-login-using-bash-login

登录 Shell 会查找 '~/.bash_profile,~/.bash_login 和 ~/.profile',按照这个顺序读取并执行命令。'man bash'(cred: cdarke)

你可能是在桌面终端或次要 bash shell 中尝试打开 bash,并且由于非登录交互式 Shell 仅会 source ~/.bashrc 而不是 ~/.profile,因此你没有这个 PATH 指令在你的 ~/.bashrc 中,因此无法得到新的路径。

解决方案:

PATH="$PATH:/home/username/softwares/kafka/kafka_2.11-1.0.0/bin" 添加到你的 ~/.bashrc 中,而不是添加到 ~/.profile

参考:

https://serverfault.com/questions/261802/what-are-the-functional-differences-between-profile-bash-profile-and-bashrc

注意:

不用担心它不会显示在登录 Shell 中,因为正如你所看到的,.profile 调用了 .bashrc

# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi

感谢cdarke关于术语的纠正和有关登录配置工作方式的说明。

谢谢,你的解决方案有效,但我不理解它。当你说登录子shell时,你是指我作为特定用户登录到我的系统,并且对于特定的用户,只读取.bashrc而不是.profile吗?但是,然后,你说.profile调用.bashrc。抱歉,我很困惑。你能简单地解释一下吗? - T Anna
你分享的链接说:.profile 是为那些不特定于 Bash 的事情准备的,例如环境变量 PATH 等,并且应该随时可用。那么为什么我们要将 Kafka 路径添加到 .bashrc 中呢? - T Anna
我重写了它,请告诉我现在是否清晰。有不同种类的Shell。Bash只是大多数现代系统中的默认选项。在我所知道的Ubuntu系统中,仅在登录Shell中调用.profile。因此,默认情况下在桌面终端中不会调用它。 - yosefrow
3
如果你有一个名为.bash_profile的文件(即使它是空的),那么.profile就不会被执行。根据man bash的解释:在读取了该文件后,Bash会按照顺序查找~/.bash_profile~/.bash_login~/.profile这三个文件,并从第一个存在且可读的文件中读取并执行命令。 - cdarke
@cdarke,我在网上找了很久,你的评论正是我需要的。非常感谢。 - sk001
显示剩余4条评论

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