Linux环境
在LinuxShell登陆成功之后,Linux会从文件中获取一系列的数据为该次登陆所用,这种数据会在个别指令或个别程序中被使用到。那些数据就称为LinuxShell运行时的环境。环境中的数据可以大致分为四种:环境变量,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命令上面被视为分隔符,并不是无意义的符号。
注意到假如出现特殊字符红帽linux系统下载,如空格,$,等等,要用冒号扩上去(3)。
假如要让接出来在该shell运行的程序才能访问到该变量,则要使用export命令:
rit@rit-X405UA:~$ export foo hello
登录后复制
像这样在当前的session中定义的变量只在当前session有效,即退出再登陆这个变量就不存在了。若要在每次登入到shell的时侯都能使用到该变量,需将该变量定义到环境变量的配置文件中。
环境变量来自什么文件?
如文章开头所述,Linux会从文件中获取环境变量。这么是什么文件在为LinuxShell提供环境变量呢?(前面再解释loginshell与non-loginshell)
对于loginshell:
/etc/profile,这个文件是loginshell的全局环境变量配置文件,全局意味着对所有用户都有效~/.bash_profile,~/.bash_login,~/.profile,这三个文件用于配置用户个人的环境变量,所以每位用户的HOME目录下就会有起码这三个文件中的一个(取决于linux的发行版本)linux修改用户环境变量,读取时只会读取其中一个。loginshell登陆时linux会先读取/etc/profile这个全局配置文件linux内存管理,再在HOME目录根据一定次序找寻这三个文件,最后会读取找到的第一个文件。若与/etc/profile中定义的变量有冲突,会将该变量覆盖。
对于non-loginshell:
/etc/bash.bashrc,这个文件是non-loginshell的全局环境变量配置文件。(网上一些博客的介绍中,这个文件不是/etc/bash.bashrc而是/etc/bashrc,其实这取决于发行版本)~/.bashrc,这个文件是用户个人的non-loginshell环境变量配置文件,与loginshell相同,该文件在/etc/bash.bashrc后执行,有冲突时,该文件也会将冲突的变量重画。
以上关于文件读取次序的描述参考于这篇文章。
各类linux发行版都带有一个命令su,若直接”su用户名”,则会以non-loginshell登陆到该用户,若加上选项”-“或是”-l”或是”–login”,则会以loginshell登陆到该用户。诸位读者倘若更清楚的体会这种文件的读取过程,可以借助这个命令,通过更改那些文件来进行测试。
loginshell与non-loginshell
登陆LinuxShell有两种方式:loginshell与non-loginshell。loginshell一般会作为第一个登陆的shell(例如开机时的登陆),而non-loginshell一般是开机后从GUI直接启动的shell。通过这两种方式登陆的环境变量会有一些区别。
1.non-loginshell会承继上一个进程(一般是loginshell)中的一些环境变量
可以通过一个简单测试来验证。
首先,在当前shell中自定一个变量foo=FOO,并export(为了让子进程也能使用这个变量,而shell本身就是一个程序):
rit@rit-X405UA:~$ foo=FOO rit@rit-X405UA:~$ export foo
登录后复制
接着,以loginshell登陆到另一个帐户bob,并尝试查看foo变量:
rit@rit-X405UA:~$ su - bob Password: bob@rit-X405UA:~$ echo $foo bob@rit-X405UA:~$
登录后复制
结果foo变量为空,在这儿说明foo未被定义。
接着,以non-loginshell登陆到另一个帐户bob,并查看foo变量:
rit@rit-X405UA:~$ su bob Password: bob@rit-X405UA:/home/rit$ echo $foo FOO
登录后复制
结果foo变量与rit这个用户的shell中的定义一致。
说明non-loginshell承继了上一个进程的用户自定变量,而loginshell没有承继。
2.PWD,HOME,USER,PATH
在1中的事例就可以注意到,loginshell的PWD弄成了当前用户的HOME目录(~),而non-loginshell则承继了父进程的工作目录。
若使用echo来查看HOME与USER,我们会发觉两种登陆形式登陆以后这两个变量都切换到了当前用户对应的home目录与username。
对于两种登陆形式的PATH的区别,可以在~/.bash_profile(或是~/.bash_login,~/.profile)中找到部份线索。上面说过,这三个文件是在loginshell中读取的,假如我们仔细比对它们与~/.bashrc,都会发觉~/.bash_profie中多了如此两行:
... PATH="$HOME/bin:$PATH" ... PATH="$HOME/.local/bin:$PATH" ...
登录后复制
所以在用两种方法登陆以后,用echo查看PATH变量可以看见区别如下:
non-loginshell:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
登录后复制
loginshell:
/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)linuxshell提供一种叫pipeline的特点,意味着可以将一个命令的输出重定向至下一个命令的输入(即把某个命令的输入当成时另一个命令的输入),不过前提是该指令要才能接受输入或形成输出。常见的指令有cat,less,grep等。输入输出用”|”来拼接。
(2)linuxshell在读取到$这个符号时,会先将它前面紧挨到的的字符视作变量名,并将$与变量名替换成变量的值,之后再将替换后的参数传给命令。这属于shell的特点expansion中的parameterexpansion,不仅parameterexpansion之外,还有pathnameexpansion,braceexpansion,commandsubstitution。
(3)与(2)相反,假如要忽视掉特殊符号,可以在右侧加破折号。双冒号会屏蔽除””,”`”,”$”以外的所有特殊符号。单冒号会忽视掉所有特殊符号。
参考
不仅环境变量文件读取次序是参考网站的博客linux修改用户环境变量,其它内容皆参考自书本:TheLinuxCommandLine2ndEdititonACompleteIntroduction。
勘误校准2019年7月4日:(1)自定义变量时等号左右两侧都不能留空格。更改前我只提及了等号右边不能留空格。(2)parameterexpansion会将”$变量名”替换成变量的值。更改前的描述为把”$变量名”转化为变量名。(3)escapecharacter不属于expansion特点。更改前我把它归类到了expansion里。新增内容2019年7月4日:在“用户自定义变量”部分的末尾新增对自定义变量作用范围的描述。
以上就是Linux环境变量来自哪些文件?的详细内容,更多请关注小闻网其它相关文章!
评论(0)