概述
文章目录
问题
知识点
问题分析及解决
补充
问题
在使用linux桌面环境(通常是ubuntu/debian/deepin等版本的linux)的时候,新增环境变量后,会使用source /etc/profile命令使新的环境变量立刻生效而不用重新启动系统。但经常会遇到使用source /etc/profile命令之后,新的环境变量只能在当前终端里面有效,而在新打开的终端中,使用新的环境变量就找不到了。
先通过操作来复现一下这个过程,我使用的linux分支是deepin(其他版本的类似),通过图形界面打开终端操作进入,准备添加一个新的变量testEnv。
# 查看系统中,是否已经存在名字为 testEnv 的环境变量,如果输出为空,表示环境变量不存在
echo $testEnv
# 环境变量不存在,就添加 testEnv 到环境变量
sudo bash -c "echo testEnv=888888 >> /etc/profile"
# 输出/etc/profile最后一行,查看是否添加成功
tail -1 /etc/profile
# testEnv=888888
# 使 testEnv 环境变量生效
source /etc/profile
# 查看环境变量 testEnv 的值,如果输出 888888 ,表示环境变量创建成功
echo $testEnv
# 888888
新建一个终端窗口,看下是否可以输出环境变量testEnv的值。
# 输出结果为空
echo $testEnv
但是,只要重启系统,一切就正常了。
问题在于为什么?
知识点
我们知道,linux中环境变量是通过配置文件添加的,在系统启动的时候,通过加载不同的配置文件来初始化环境变量,所以环境变量找不到的问题,归根结底是配置文件的加载问题。搞清楚linux中配置文件的加载顺序,上面遇到的问题也就不难理解了。
shell是用户与Linux系统进行交互的媒介,它在运行时具有两种属性,即“交互”与“登陆”,由此衍生出交互式登录和非交互式登录两种模式。
交互式登录shell进程是指直接通过某终端输入账号密码后登录打开的shell进程,如使用ssh或者堡垒机进行远程主机连接,或者使用 su - username 或者 su -l username 执行的登录用户切换等。
非交互式登录shell进程:图形界面下打开的终端、su username 执行的登录切换、直接运行脚本或者bash -c执行一段命令的时候。
linux 中常见的配置文件有/etc/profile、~/.bash_profile、~/.bashrc、/etc/bashrc和/etc/profile.d/*。
/etc/profile:此文件为系统的每个用户设置环境信息,系统中每个用户登录时都要执行这个脚本,如果系统管理员希望某个设置对所有用户都生效,可以写在这个脚本里,该文件也会从/etc/profile.d目录中的配置文件中搜集shell的设置。
~/.bash_profile:每个用户都可使用该文件设置专用于自己的shell信息,当用户登录时,该文件仅执行一次。默认情况下,他设置一些环境变量,执行用户的.bashrc文件。
~/.bashrc:该文件包含专用于自己的shell信息,当登录时以及每次打开新shell时,该文件被读取。
/etc/bashrc:为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取。
关于配置文件加载顺序的说法,网上有很多,看起来也不尽相同,其实主要区别在与不同的linux发行版,包含的配置文件也是有很大区别的,即使有名字相同的配置文件,配置文件里面的内容也是大相径庭。但是基本上所有的linux发行版都会包括/etc/profile(登录后读取的第一个配置文件)和~/.bashrc两个配置文件。
对于交互式登录shell来说,一定会读取的配置文件的顺序是/etc/profile --> ~/bashrc。
对于非交互式登录shell来说,一定会读取的配置文件属性是~/.bashrc,如果~/.bash_profile 存在的话,顺序是这样的~/.bash_profile --> ~/.bashrc 。
对于其他的各种常见配置文件的读取,以及是读取,主要取决于/etc/profile 或者 ~/bashrc 里面的具体内容,比如在centos7 的/etc/profile中有如下一段代码,是用来载入/etc/profile.d/*.sh配置文件的。
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
deepin系统中的.bashrc里面有一段代码,用来读取命令别名声明文件。
# Get the aliases and functions
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
所以,系统配置文件的读取顺序,需要根据系统版本的不同去了解读取顺序。
每次在配置文件中配置的新环境变量,只会对随后新启动的shell进程生效,如果想让配置文件立即生效,需要让shell进程重读配置文件,这就需要进行类似source /etc/profile 或者 . /etc/profile 这样的操作。
问题分析及解决
一般遇到本文开头说到的问题的同学,都是在图形界面下使用终端的配置的环境变量,然后通过source /etc/profile 重新读取配置文件,然后打开一个新的终端的时候,使用命令就是出现comand not found的问题。
结合上面的知识点看下,在图形界面下使用的终端属于非交互式登录的shell,以我使用的deepin系统为例,新开一个终端时,读取的配置文件应该是~/.bashrc。而新增的环境变量配置在/etc/profile,所以出现在新开终端找不到环境变量的问题。
解决办法:
在新开终端,执行source /etc/profile,比较麻烦
将环境变量配置在,~/.bashrc 中,可以解决
在~/.bashrc中添加source /etc/profile,这样就可以为每一个新开的终端重新读取一次/etc/profile配置文集,可以解决,多次读取/etc/profile没有发现有什么副作用。
补充
网上早期很多关于java、node等的环境变量配置的文章,感觉都是针对搭建centos服务器或者测试机的,他们之所以没有这个问题,是因为服务器基本都是通过ssh远程登录,是交互式登录模式的,每次打开一个新的远程连接,都会重新读取/etc/profile,所以不会有command not found的问题。而个人用的电脑,基本都是图形界面直接操作,所以会遇到比较多的这种问题。
最后
以上就是拼搏月饼为你收集整理的linux 重读环境变量,关于linux中使用source /etc/profile重新读取配置后,新的环境变量只能在当前终端里面有效,新开的终端提示 command not found...的全部内容,希望文章能够帮你解决linux 重读环境变量,关于linux中使用source /etc/profile重新读取配置后,新的环境变量只能在当前终端里面有效,新开的终端提示 command not found...所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复