在大家初次接触到Linux系统中,相信环境变量会让你头疼不已。习惯了在Windows设置PATH的你,被Linux上各种文件可以设置环境变量头疼不已!对于可以在当前用户执行的命令,但是sudo就无法执行困惑不堪!下面,我们就系统的和大家讲解下Linux的环境变量,让大家豁然开朗;
一、什么是环境变量
1.在Linux中,很多程序和脚本都通过环境变量来获取系统信息、存储临时数据和配置信息;
2.bash shell使用环境变量来存储有关shell会话和工作环境信息;
允许你在内存中存储数据,以便运行在shell的程序和脚本访问;
是存储永久数据的一种简单方法,用来识别用户账户、系统、shell的特性,以及任何你需要存储的数据;
3.在bash shell中,环境变量分为:
全局变量:不仅对shell会话可见,对所有shell创建的子进程也可见; ;
局部变量:只对创建它们的shell可见;
二、全局环境变量
1.Linux在你开始bash会话之前就设置了一些全局的环境变量;
2.系统环境变量一律使用大写字母以区别普通用户的环境变量;
3.printenv命令查看全局环境变量,大部分都是系统在用户登录系统时设置的;
pengcx@pengcx-Ubuntu:~$ printenv //查看所有全局环境变量
XDG_SESSION_ID=1
TERM=vt100
SHELL=/bin/bash
SSH_CLIENT=192.168.1.102 50167 22
SSH_TTY=/dev/pts/27
USER=pengcx
MAIL=/var/mail/pengcx
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
QT_QPA_PLATFORMTHEME=appmenu-qt5
PWD=/home/pengcx
LANG=zh_CN.UTF-8
NODE_PATH=/usr/lib/nodejs:/usr/lib/node_modules:/usr/share/javascript
SHLVL=1
HOME=/home/pengcx
LANGUAGE=zh_CN:zh
LOGNAME=pengcx
SSH_CONNECTION=192.168.1.102 50167 192.168.1.104 22
XDG_RUNTIME_DIR=/run/user/1000
_=/usr/bin/printenv
4.echo命令显示单个环境变量的值;pengcx@pengcx-Ubuntu:~$ echo $HOME //显示HOME单个全局环境变量
/home/pengcx
5.在当前shell会话的子进程中也是可见的;pengcx@pengcx-Ubuntu:~$ bash
pengcx@pengcx-Ubuntu:~$ echo $HOME //在子进程中显示HOME全局环境变量
/home/pengcx
三、局部环境变量1.Linux系统也默认定义了标准局部环境变量;
2.set命令查看某个特定进程的所有环境变量,这也包含全局环境变量(通过printenv命令能看到的全局环境变量都出现在了set命令的输出中,但是set命令输出中还有一些其它的环境变量,这就是局部环境变量;
四、设置环境变量
1.一旦启动bash shell(或者执行一个shell脚本),你就能创建这个shell进程可见的局部环境变量;
pengcx@pengcx-Ubuntu:~$ test=testing
pengcx@pengcx-Ubuntu:~$ echo $test
testing
//如果变量赋一个含有空格的字符串值,必须用单引号来界定字符串的开始和末尾,没有单引号的话,bash shell会以为下个字符串是另一个命令
pengcx@pengcx-Ubuntu:~$ test2=testing a long string
a:未找到命令
pengcx@pengcx-Ubuntu:~$ test2='testing a long string'
pengcx@pengcx-Ubuntu:~$ echo $test2
testing a long string
//如果创建了另外一个shell,它在子shell中就不可用了
pengcx@pengcx-Ubuntu:~$ bash
pengcx@pengcx-Ubuntu:~$ echo $test2
//如果你返回原shell局部环境变量仍然存在
pengcx@pengcx-Ubuntu:~$ exit
exit
pengcx@pengcx-Ubuntu:~$ echo $test2
testing a long string
2.设置全局环境变量,先创建一个局部环境变量,然后再把它导入到全局变量中;pengcx@pengcx-Ubuntu:~$ bash
pengcx@pengcx-Ubuntu:~$ echo $test
pengcx@pengcx-Ubuntu:~$ exit
exit
pengcx@pengcx-Ubuntu:~$ export test
pengcx@pengcx-Ubuntu:~$ bash
pengcx@pengcx-Ubuntu:~$ echo $test
testing
五、删除环境变量1.使用unset命令来删除环境变量;
pengcx@pengcx-Ubuntu:~$ echo $test
testing
pengcx@pengcx-Ubuntu:~$ unset test //删除test环境变量
pengcx@pengcx-Ubuntu:~$ echo $test //读取test环境变量无效
pengcx@pengcx-Ubuntu:~$
2.处理全局环境变量时,如果你是在子进程中删除了一个全局环境变量,它只对子进程有效,该全局环境变量在父进程中依然有效;pengcx@pengcx-Ubuntu:~$ test=testing //先创建局部变量
pengcx@pengcx-Ubuntu:~$ export test //导入全局变量
pengcx@pengcx-Ubuntu:~$ echo $test //在父进程中查看test全局变量
testing
pengcx@pengcx-Ubuntu:~$ bash //进入子进程
pengcx@pengcx-Ubuntu:~$ echo $test //在子进程中查看test全局变量
testing
pengcx@pengcx-Ubuntu:~$ unset test //在子进程中删除test全局环境变量
pengcx@pengcx-Ubuntu:~$ echo $test //在子进程中test全局变量无效
pengcx@pengcx-Ubuntu:~$ exit //回到父进程
exit
pengcx@pengcx-Ubuntu:~$ echo $test //在父进程中读取test全局变量有效
testing
七、设置PATH环境变量1.PATH环境变量定义了命令行输入命令的搜索路径;
//通常应用会把可执行程序放到不在PATH环境变量中的目录,那么必须保证PATH环境变量包含了所有存放应用的目录;
pengcx@pengcx-Ubuntu:~$ mycmd.sh
mycmd.sh:未找到命令
pengcx@pengcx-Ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
//PATH的目录之间是用冒号分隔的,只需引用原来的PATH值,然后在给字符添加新的目录就行了;
pengcx@pengcx-Ubuntu:~$ PATH=$PATH:/mycmd
pengcx@pengcx-Ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mycmd
//现在可以在任何目录下执行mycmd脚本了
pengcx@pengcx-Ubuntu:~$ mycmd.sh
running mycmd...
pengcx@pengcx-Ubuntu:~$
2.通常使用单点符也加到PATH环境变量里,单点符代表当前目录; pengcx@pengcx-Ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mycmd
pengcx@pengcx-Ubuntu:~$ PATH=$PATH:.
pengcx@pengcx-Ubuntu:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/mycmd:.
八、定位系统环境变量
1.在你登录Linux系统启动一个bash shell时,默认情况下bash在几个文件中查找命令,这几个文件成为启动文件;
2.bash检查的启动文件取决于你启动bash shell的方式,启动bash shell有3中方式:
登录时当做默认登录shell;
作为非登录shell的交互shell,在命令行中输入bash;
作为运行脚本的非交互shell,在shell脚本中执行shell;
3.当你登录Linux系统时,登陆了shell会从4个不同的启动文件里读取命令:
/etc/profile:bash shell的主启动文件,每个用户登录都会执行这个启动文件;
$HOME/.bash_profile:用户专用启动文件;
$HOME/.bash_login:用户专用启动文件;
$HOME/.profile:用户专用启动文件;
4./etc/profile文件
pengcx@pengcx-Ubuntu:~$ cat /etc/profile
# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).
if [ "$PS1" ]; then
if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
# The file bash.bashrc already sets the default PS1.
# PS1='\h:\w\$ '
if [ -f /etc/bash.bashrc ]; then
. /etc/bash.bashrc
fi
else
if [ "`id -u`" -eq 0 ]; then
PS1='# '
else
PS1='$ '
fi
fi
fi
# The default umask is now handled by pam_umask.
# See pam_umask(8) and /etc/login.defs.
//逐一访问/etc/profile.d目录的每个文件,为Linux提供了一个集中存放用户登录时要执行的应用专属的启动文件
if [ -d /etc/profile.d ]; then
for i in /etc/profile.d/*.sh; do
if [ -r $i ]; then
. $i
fi
done
unset i
fi
pengcx@pengcx-Ubuntu:/etc/profile.d$ ls -al
总用量 32
drwxr-xr-x 2 root root 4096 5月 4 16:40 .
drwxr-xr-x 147 root root 12288 5月 4 16:40 ..
-rw-r--r-- 1 root root 40 4月 15 2014 appmenu-qt5.sh
-rw-r--r-- 1 root root 663 4月 7 2014 bash_completion.sh
-rw-r--r-- 1 root root 89 4月 1 14:19 nodejs.sh
-rw-r--r-- 1 root root 1947 11月 22 2013 vte.sh
5.$HOME目录下的启动文件 剩下的3个启动文件都起着同一个作用:提供一个用户专属的启动文件来定义用户专有的环境变量;
$HOME/.bash_profile;
$HOME/.bash_login;
$HOME/.profile;
.bash_profile文件;
pengcx@pengcx-Ubuntu:~$ cat .profile
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
//检查HOME目录中的是不是还有另外一个叫.bashrc启动文件
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin if it exists
//在HOME目录底下提供了一个放置可执行文件的通用位置
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
6.交互式shell
如果你在命令行提示符敲下bash命令,你启动的shell称作为交互式shell;
如果bash是作为交互式shell启动的,它就不会去访问/etc/profile文件,而会去用户的HOME目录检查.bashrc是否存在;
.bashrc文件有两个作用;
查看/etc目录下的公用bashrc文件;
而是为用户提供了一个定制自己的命令别名和私有脚本函数的地方;