环境变量对我这种小白来说简直是谜一样的存在,经常莫名其妙import失败,找不到文件等。
1、变量分类
按变量的生存周期划分:
- 永久的:需要修改配置文件,变量永久生效。
- 临时的:使用export命令声明即可,变量在关闭shell时失效。
在配置永久的环境变量时,又可以按照作用范围分为
- 用户环境变量
- 系统环境变量。
系统环境变量对所有系统用户都有效,用户环境变量仅仅对当前的用户有效。
2、login & non-login shell
Linux系统自举时,内核会创建init进程,来进行一系列的系统初始化操作。每一个用户登录shell时,无论以伪终端登录:ssh,X11下控制台,还是tty控制台终端,都会读取相关相关的登录配置文件。linux 有两种登录shell:login和nologin:
- login shell:登录shell时需要完整的登录流程,称为 login shell。何为完整:输入用户名和密码。例如:走tty1-tty6控制终端,或走ssh等伪终端远程登入
- non-login shell:登入shell时不需要输入帐号信息。例如在X11下,打开伪终端,或者在shell下,进入shell子进程。
在下列情况下,我们可以获得一个login shell:
-
登录系统时获得的顶层shell,无论是通过本地终端登录,还是通过网络ssh登录。这种情况下获得的login shell是一个交互式shell。
-
在终端下使用--login选项调用bash,可以获得一个交互式login shell。
-
在脚本中使用--login选项调用bash(比如在shell脚本第一行做如下指定:#!/bin/bash --login),此时得到一个非交互式的login shell。
-
使用"su -"切换到指定用户时,获得此用户的login shell。如果不使用"-",则获得non-login shell。
这两种登入shell的区别是:在登入shell是,读取的配置文件不同。
ogin shell(bash)在登入时,会读取的配置文件:
- /etc/profile,全局配置
- ~/.bash_profile 或~/.bash_login 或 ~/.profile,个人配置。之所以有三个文件,是因为不同的shell有可能命名不同,只会按顺序读取其中的一个。login shell退出时读取并执行~/.bash_logout中的命令。
non-login shell(bash)在登入时,只会读取的配置文件:
交互式的non-login shell启动时读取~/.bashrc资源文件。非交互式的non-login shell不读取上述所有配置文件,而是查找环境变量BASH_ENV,读取并执行BASH_ENV指向的文件中的命令。
~/.bashrc。bashrc这个文件有时候不存在,需要自己创建,里面可以进行个性化的定制,不会影响到其他用户。
3、su&sudo
在我接触的Linux 发行版中,ubuntu在安装过程中不会提示root密码的设置,只有进入系统后才能在shell下通过passwd来设置root的密码,fedora,centos安装过程中多会要求设置root密码和建立一个常用的用户。可以看出linux的设计者们本身就期望用户以较低的权限来进行平时的操作,这是基于于安全的考虑。
但在shell环境下,由于各种工作的需要,我们经常需要进行用户权限的切换,最常用的就是获取root用户的权限。最常用的命令有su和sudo。
- su [-lc] [username]
- - , -l, --login : 表示使用以login shell的方式登录username,若username为空,则默认登录root。
- 如果没有该参数,则以nonlogin的方式登录
- -c, 仅执行一次命令 ,命令需要用引号括起来
这里要强调的就是su 和su -的区别,就是前面撤了一大串的login 和non-login的区别。
sudo命令的存在我觉得有两个原因:
- 使用su切换到root,需要是所有用户都知道root密码,不安全;
- 很多时候我们切换到root用户只是需要执行一条语句,尽管su -c可以完成,但每次都要敲个空格-c,而且每次都要输入root密码;
上面两个原因,就是sudo存在的理由。sudo可以让用户通过验证自己的密码来获得其他用户的权限,只需要root对/etc/sudoers进行相关的配置
4、设置环境变量
4.1 export命令
在shell的命令行下直接使用[export 变量名=变量值] 定义变量。该变量只在当前的shell(BASH)或其子shell(BASH)下是有效的,shell关闭了,变量也就失效了,再打开新shell时就没有这个变量,需要使用的话还需要重新定义。
4.2 修改系统环境变量
系统环境变量一般保存在下面的文件中
/etc/profile
全局(公有)配置,不管是哪个用户,登录时都会读取该文件。
处在shell配置文件的最顶端。这是系统shell环境的全局设定,例如PATH,MAIL很多环境变量。对它的修改,会影响到所有用户。
/etc/bash.bashrc
它也是全局(公有)的 bash执行时,不管是何种方式,都会读取此文件。
/etc/environment
不要轻易修改此文件
4.3 修改用户环境变量
用户环境变量通常被存储在下面的文件中:
~/.profile
若bash是以login方式执行时,读取~/.bash_profile,若它不存在,则读取~/.bash_login,若前两者不存在,读取~/.profile。
~/.bash_profile
或者~./bash_login
若bash是以login方式执行时,读取~/.bash_profile,若它不存,则读取~/.bash_login,若前两者不存在,读取 ~/.profile。
只有bash是以login形式执行时,才会读取.bash_profile,Unbutu默认没有此文件,可新建。 通常该配置文件还会配置成去读取~/.bashrc。
~/.bashrc
处在shell配置文件的最低端。这是针对每个用户shell环境的配置文件,我们的大部分个性化的定制,都可以直接修改在这个文件中。
当bash是以non-login形式执行时,读取此文件。若是以login形式执行,则不会读取此文件。
~/.bash_profile是交互式、login 方式进入 bash 运行的
~/.bashrc 是交互式 non-login 方式进入 bash 运行的通常二者设置大致相同,所以通常前者会调用后者。
通常我们要定制一些配置时,将配置写在~/.bashrc中,然后在~/.bash_profile中读取~/.bashrc,这样可以保证login shell和交互式non-login shell得到相同的配置。至于/etc/profile就不要轻易去改啦,毕竟会影响系统全局的配置。
5、修改环境变量配置文件
如想将一个路径加入到环境变量(例如$PATH)中,可以像下面这样做(修改/etc/profile):
sudo vi /etc/profile
以环境变量PATH为例子,环境变量的声明格式:
PATH=$PATH:PATH_1:PATH_2:PATH_3:------:PATH_N
export PATH
你可以自己加上指定的路径,中间用冒号隔开。环境变量更改后,在用户下次登陆时生效,如果想立刻生效,则可执行下面的语句:
$source /etc/profile
6、环境配置文件的区别
6.1 profile、 bashrc、.bash_profile、 .bashrc介绍
bash会在用户登录时,读取下列四个环境配置文件:
全局环境变量设置文件:/etc/profile、/etc/bashrc。
用户环境变量设置文件:~/.bash_profile、~/.bashrc。
读取顺序:① /etc/profile、② ~/.bash_profile、③ ~/.bashrc、④ /etc/bashrc。
① /etc/profile:此文件为系统的每个用户设置环境信息,系统中每个用户登录时都要执行这个脚本,如果系统管理员希望某个设置对所有用户都生效,可以写在这个脚本里,该文件也会从/etc/profile.d目录中的配置文件中搜集shell的设置。
② ~/.bash_profile:每个用户都可使用该文件设置专用于自己的shell信息,当用户登录时,该文件仅执行一次。默认情况下,他设置一些环境变量,执行用户的.bashrc文件。
③ ~/.bashrc:该文件包含专用于自己的shell信息,当登录时以及每次打开新shell时,该文件被读取。
④ /etc/bashrc:为每一个运行bash shell的用户执行此文件,当bash shell被打开时,该文件被读取。
6.2 bashrc和.bash_profile的区别
.bash_profile会用在登陆shell, .bashrc 使用在交互式非登陆 shell 。简单说来,它们的区别主要是.bash_profile是在你每次登录的时候执行的;.bashrc是在你新开了一个命令行窗口时执行的。
当通过控制台进行登录(输入用户名和密码):在初始化命令行提示符的时候会执行.bash_profile 来配置你的shell环境。但是如果已经登录到机器,在Gnome或者是KDE也开了一个新的终端窗口(xterm),这时,.bashrc会在窗口命令行提示符出现前被执行。当你在终端敲入/bin/bash时.bashrc也会在这个新的bash实例启动的时候执行。
6.3 建议
大多数的时候你不想维护两个独立的配置文件,一个登录的一个非登录的shell。当你设置PATH时,你想在两个文件都适用。可以在.bash_profile中调用.bashrc,然后将PATH和其他通用的设置放到.bashrc中。
要做到这几点,添加以下几行到.bash_profile中:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
现在,当你从控制台登录机器的时候,.bashrc就会被执行。