razor 怎样使用session变量_Linux 环境变量(Environment Variable)

6ab4b3a31584f83180facd2e603ca845.png

Linux 环境

在 Linux Shell 登录成功以后,Linux 会从文件中获取一系列的数据为该次登录所用,这些数据会在某些指令或某些程序中被使用到。这些数据就称为 Linux Shell 运行时的环境。环境中的数据可以大致分为四种:环境变量,Shell 变量,别名(alias),Shell 函数。其中 Shell 变量,别名,Shell 函数在此不做详细说明。

环境变量里有什么?

可以直接用无参数的 printenv 命令来输出当前 session 的环境变量以及环境变量的值。若加上参数,则是输出某个变量的值。若想更方便地查看,可以将 printenv 的输出传给 less来查看环境变量(1):

printenv | less

下面是在我的 Linux 系统上的部分输出结果:

...
...
MANDATORY_PATH=/usr/share/gconf/cinnamon.mandatory.path
XDG_SESSION_ID=c2
XDG_GREETER_DATA_DIR=/var/lib/lightdm-data/rit
USER=rit
DESKTOP_SESSION=cinnamon
QT4_IM_MODULE=fcitx
GNOME_TERMINAL_SCREEN=/org/gnome/Terminal/screen/e9e1def3_9380_43b6_8ce3_7916861e45d2
DEFAULTS_PATH=/usr/share/gconf/cinnamon.default.path
QT_QPA_PLATFORMTHEME=qt5ct
PWD=/home/rit
HOME=/home/rit
...
...

可以看到,平时常接触到的PWD,HOME,USER等都在其中。

如果要在命令的参数中使用某个变量的值,可以输入 "$变量名" (2)。比如:

ls $HOME/bin

用户自定义变量

除了系统自带的变量,用户还可以自定义变量:

rit@rit-X405UA:~$ foo=FOO
rit@rit-X405UA:~$ hello='Hello World'
rit@rit-X405UA:~$ echo $foo
FOO
rit@rit-X405UA:~$ echo $hello
Hello World

注意到等号左右两边不留空格,因为空格在 shell 命令里面被视为分隔符,并不是无意义的符号。

注意到如果出现特殊字符,如空格,$,等等,要用引号扩起来(3)。

如果要让接下来在该 shell 运行的程序能够访问到该变量,则要使用 export 命令:

rit@rit-X405UA:~$ export foo hello

像这样在当前的 session 中定义的变量只在当前 session 有效,即退出再登录这个变量就不存在了。若要在每次登录到 shell 的时候都能使用到该变量,需将该变量定义到环境变量的配置文件中。

环境变量来自哪些文件?

如文章开头所述,Linux 会从文件中获取环境变量。那么是哪些文件在为 Linux Shell 提供环境变量呢?(后面再解释 login shell 与 non-login shell)

对于 login shell:

  1. /etc/profile,这个文件是 login shell 的全局环境变量配置文件,全局意味着对所有用户都有效
  2. ~/.bash_profile,~/.bash_login,~/.profile,这三个文件用于配置用户个人的环境变量,所以每个用户的 HOME 目录下都会有至少这三个文件中的一个(取决于 linux 的发行版本),读取时只会读取其中一个。login shell 登录时 linux 会先读取 /etc/profile 这个全局配置文件,再在HOME目录按照一定顺序寻找这三个文件,最后会读取找到的第一个文件。若与 /etc/profile 中定义的变量有冲突,会将该变量覆盖。

对于 non-login shell:

  1. /etc/bash.bashrc,这个文件是 non-login shell 的全局环境变量配置文件。(网上一些博客的介绍中,这个文件不是 /etc/bash.bashrc 而是 /etc/bashrc,或许这取决于发行版本)
  2. ~/.bashrc,这个文件是用户个人的 non-login shell 环境变量配置文件,与 login shell 相同,该文件在 /etc/bash.bashrc 后执行,有冲突时,该文件也会将冲突的变量重写。

以上关于文件读取顺序的描述参考于这篇文章。

各种 linux 发行版都带有一个命令 su,若直接 "su 用户名",则会以 non-login shell 登录到该用户,若加上选项 "-" 或是 "-l" 或是 "--login",则会以 login shell 登录到该用户。各位读者若想更清楚的感受这些文件的读取过程,可以利用这个命令,通过修改这些文件来进行测试。

login shell 与 non-login shell

登录 Linux Shell 有两种方法:login shell 与 non-login shell。login shell 通常会作为第一个登录的shell(比如开机时的登录),而 non-login shell 通常是开机后从GUI直接启动的 shell。 通过这两种方法登录的环境变量会有一些区别。

1. non-login shell 会继承上一个进程(通常是 login shell)中的一些环境变量

可以通过一个简单测试来验证。

首先,在当前 shell 中自定一个变量 foo=FOO,并export(为了让子进程也能使用这个变量,而 shell 本身就是一个程序):

rit@rit-X405UA:~$ foo=FOO
rit@rit-X405UA:~$ export foo

接着,以 login shell 登录到另一个账户 bob,并尝试查看 foo 变量:

rit@rit-X405UA:~$ su - bob
Password: 
bob@rit-X405UA:~$ echo $foo

bob@rit-X405UA:~$

结果 foo 变量为空,在这里说明 foo 未被定义。

接着,以 non-login shell 登录到另一个账户 bob,并查看 foo 变量:

rit@rit-X405UA:~$ su bob
Password: 
bob@rit-X405UA:/home/rit$ echo $foo
FOO

结果 foo 变量与 rit 这个用户的 shell 中的定义一致。

说明 non-login shell 继承了上一个进程的用户自定变量,而 login shell 没有继承。

2. PWD,HOME,USER,PATH

在 1 中的例子就可以注意到,login shell 的 PWD 变成了 当前用户的 HOME 目录(~),而 non-login shell 则继承了父进程的工作目录。

若使用 echo 来查看 HOME 与 USER,我们会发现两种登录方式登录之后这两个变量都切换到了当前用户对应的 home 目录与 user name。

对于两种登录方式的 PATH 的区别,可以在 ~/.bash_profile(或是 ~/.bash_login,~/.profile)中找到部分线索。前面说过,这三个文件是在 login shell 中读取的,如果我们仔细比对它们与 ~/.bashrc,就会发现 ~/.bash_profie 中多了这么两行:

...
PATH="$HOME/bin:$PATH"
...
PATH="$HOME/.local/bin:$PATH"
...

所以在用两种方式登录之后,用 echo 查看 PATH 变量可以看到区别如下:

non-login shell:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

login shell:

/home/rit/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

里面不包含 $HOME/bin 是因为 home 目录没有这个文件夹。

仔细观察可以发现还有别的区别,但那些区别的出处就不太好找了。

注释

(1)linux shell 提供一种叫 pipeline 的特性,意味着可以将一个命令的输出重定向至下一个命令的输入(即把某个命令的输入当作时另一个命令的输入),不过前提是该指令要能够接受输入或产生输出。常见的指令有 cat,less,grep等。输入输出用 "|" 来拼接。

(2)linux shell 在读取到 $ 这个符号时,会先将它后面紧挨着的的字符视作变量名,并将$与变量名替换成变量的值,然后再将替换后的参数传给命令。这属于 shell 的特性 expansion 中的 parameter expansion,除了 parameter expansion 之外,还有 pathname expansion,brace expansion,command substitution。

(3)与(2)相反,如果要忽略掉特殊符号,可以在两侧加引号。双引号会屏蔽除 "","`","$" 以外的所有特殊符号。单引号会忽略掉所有特殊符号。

参考

除了环境变量文件读取顺序是参考网站的博客,其它内容皆参考自书本:The Linux Command Line 2nd Edititon A Complete Introduction

勘误校正

  1. 2019年7月4日:(1)自定义变量时等号左右两边都不能留空格。修改前我只提到了等号左边不能留空格。(2)parameter expansion 会将 "$变量名" 替换成变量的值。修改前的描述为把 "$变量名" 转化为变量名。(3)escape character 不属于 expansion 特性。修改前我把它归类到了 expansion 里。

新增内容

  1. 2019年7月4日:在“用户自定义变量”部分的末尾新增对自定义变量作用范围的描述。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值