一直以来,配置环境变量的时候都是管中窥豹,对于环境变量的配置似懂非懂。 如今就来认真补一补这方面的不足。java
主要内容包括:node
先来思考这些问题:python
专项学习环境变量以前的理解:雾里看花 java,node,go,python这些命令在SDK安装过程当中就会自动安装。 mysql,mongoDB bash环境变量须要手动添加到环境当中。 flutter shell 环境变量须要手动配置。 bash variable与shell variable最直观的区别在于:bash variable在bash terminal中访问;shell variable在shell文件中保存。mysql
专项学习环境变量以后的理解:洞若观火 发现环境变量居然包括以上如此多内容,最初的问题也能够一一找到答案。linux
接下来就来看看关于环境变量,到底有哪些须要掌握的知识点。git
这是一个指向用户的home目录的bash var。 格式为/Users/<username>
或/var/root
(macOS)。linux系统上为/home/<username>
。es6
// frank用户
echo $HOME // /Users/frank
// root用户
echo $HOME // /var/root
复制代码
引伸问题:github
在bash中,只有加上$之后,系统才会知道咱们要输出的是变量,不然会当作输出一个普通字符串处理。sql
取决于系统上有几个用户,有个用户就有几个HOME变量。 通常会有一个root用户和至少一个普通用户。docker
在~/.bash_profile中重写。(须要手动source才有效,当前session有效) 在bash session terminal中export HOME=/Users/frank/foo。(当前session有效) 关闭再打开或者新开一个tab,$HOME都会变为最原始的值。 不建议重写。具体缘由看缘由6。
能够。$HOME/tools // /Users/frank/tools
没有。空格在shell中有特殊含义。
/etc/profile //# System-wide .profile for sh(1)
由于大量的程序依赖HOME这个环境变量,因此覆盖系统默认变量是很危险的。 因此通常仅在当前session有效,若想永久覆盖,可参考PATH的加粗部分。
这个系统变量,会列出可执行程序的目录。 java,node,go,python这些命令在SDK安装过程当中就会自动安装的缘由就是这个,sdk会自动添加路径到PATH变量中。
mkdir $HOME/bin
新建本身的bin目录,并经过PATH=$PATH:$HOME/bin
将自定义的bin目录加入到PATH变量。要写在.bashrc(linux),.bash_profile(macOS)中,用source .bashrc可让文件当即生效。(亲测无卵用,.bash_profile仅在当前session生效,不过路径在.bash_profile中写是对的)source ~/.bash_profile
// bin目录间用冒号分隔
echo $PATH // /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
复制代码
➜ ~ foo=123
➜ ~ echo $foo
123
➜ ~ bash
bash-3.2$ echo $foo
复制代码
这个例子中的bash命令,会开启一个daughter process,在mother process中设定的自定义变量是没法访问的。
为何/usr/bin中会有java全家桶的bin呢?
难道java全家桶的命令不是存放在/Library/Java/JavaVirtualMachines/jdk-11.0.3.jdk/Contents/Home/bin吗?为何/usr/bin中也有。
经过ls -l /usr/bin | grep java
能够查实缘由。
lrwxr-xr-x 1 root wheel 74 5 4 17:12 java -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java
lrwxr-xr-x 1 root wheel 75 5 4 17:12 javac -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javac
lrwxr-xr-x 1 root wheel 77 5 4 17:12 javadoc -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javadoc
lrwxr-xr-x 1 root wheel 75 5 4 17:12 javah -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javah
lrwxr-xr-x 1 root wheel 75 5 4 17:12 javap -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javap
lrwxr-xr-x 1 root wheel 82 5 4 17:12 javapackager -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javapackager
lrwxr-xr-x 1 root wheel 76 5 4 17:12 javaws -> /System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/javaws
复制代码
soft link。 /usr/bin中的java全家桶命令只是/Library/Java/JavaVirtualMachines/jdk-11.0.3.jdk/Contents/Home/bin部分bin文件的soft link。
若是不懂soft link,能够移步[译]Soft and Hard links in Unxi/Linux
new_variable="Hello"
echo $new_variable
如何在bash daughter process中也能访问到自定义变量呢,也就是如何在进程间共享自定义变量呢?
➜ ~ export bar=456
➜ ~ bash
bash-3.2$ echo $bar
456
复制代码
从这个例子中能够看到,export就是干这个事情的。(es6中的export和这个也很相似,只有export的内容,其余模块才能得到数据。) 注意:在daughter process修改继承来的变量值,mother process不会被修改。(这个和编程语言中的继承很像。)
export -p
...
export USER=frank
export OLDPWD=/
export ZSH=/Users/frank/.oh-my-zsh
export bar=456
...
复制代码
OLDPWD这个变量指的就是最近一次访问的目录,经过cd -
访问到的其实就是这个目录。 一样,经过env
也能够直接得到全部的环境变量列表,不一样的地方在于不带export而且是环境变量的最终结果,export -p
会显示变量的详细配置(由于它有可能依赖其余环境变量)。