Bash 中的环境变量
在 Bash 里,可以通过 export 命令查看当前 Shell 进程的环境变量,这些环境变量一些是 Bash 自己创建的,还有一些是 Bash 从父进程继承来的,然而需要注意的是,父进程传给 Bash 的环境变量不一定是我们想象的那样。
在 C 语言层面,环境变量是存放在一个名为 environ 的全局变量里的,这个变量的值是一个字符串的数组,像这样:
{"foo=1", "bar=2"}
在父子孙一辈辈进程中传递的就是这么个数组,我们嘴里说的环境变量的原貌其实就是个字符串,而不是我们通常在高级语言里看到的键值对。然而操作系统并没有对环境变量字符串的格式做任何限制,environ 变量的值还可以是这样:
{"1=1", "=2", "="}
甚至这样:
{"foo\nbar=1"}
Bash 在启动的时候,会检查 environ 数组中的每个字符串,如果它包含 =,且 = 左边有任意的字符,就把它从 = 分割开,一个做变量名,一个做值,变成自己的变量。咦? "1=1" 也会导入成变量? 是的,在 Bash 的实现当中,是这样的,只是这样的变量会被加上特殊的属性标记。
变量名称合法的变量被添加的属性是:
att_exported | att_imported
一个表示是要导出给子进程的环境变量,一个表示是从环境变量导入的变量。
变量名不合法的变量被添加的属性是:
att_exported | att_imported | att_invisible
多了一个 invisible 属性,表示不可见。
在 Bash 启动之后,各个内部命令可以通过这个标记判断是不是自己想要的变量。比如 set 命令就不会输出 1 这个变量:
|
$ env -i 1=1 bash -c set | grep '1=' |
但 export 命令就会:
|
$ env -i 1=1 bash -c export declare -x 1 |
declare -x 1 显然是非法的,甚至还可以这样:
|
$ env -i $'foo\nrm -rf /=' bash -c export declare -x OLDPWD |
看起来很有风险的样子,不过目前 Bash 4.4 beta 版本,已经修复了这个问题,export 命令不再输出那些变量名不合法的变量了,下面是 export 命令源码做的改动:
+ /* If we imported a variable that's not a valid identifier, don't
+ show it in any lists. */
+ if ((var->attributes & (att_invisible|att_imported)) == (att_invisible|att_imported))
+ continue;
那 Bash 在启动其他程序的时候,会把这样的环境变量传递给子进程吗?答案是会的,我们可以通过在两个 env 命令中间插入一个 bash 命令来看出效果:
|
$ env -i 1=1 bash -c env PWD=/Users/admin |
Bash 在启动其他程序的时候,会把自己所有的变量中带有 att_exported 属性且值不是空的变量以及它们的值分别用 = 连接起来合成一个字符串数组,重新复值给 environ 变量,也就是做了和启动时导入环境变量相反的操作。
那些没有等号或者等号左边没有字符的环境变量,因为 Bash 在启动的时候就丢弃了,所以也就没法传递给它的子进程了。
Bash 中的环境变量的更多相关文章
- Linux中PATH环境变量的作用和使用方法
关于PATH的作用:PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径.比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根 ...
- 更优雅的配置:docker/运维/业务中的环境变量
目录 docker-compose 环境变量 .env 文件 env_file docker stack 不支持基于文件的环境变量 envsubst envsubst.py 1. 使用行内键值对 2. ...
- 设置与查看Linux系统中的环境变量
大家好,我是良许. 大家都知道,在 Linux 系统中,有环境变量和 Shell 变量这两种变量. 环境变量是在程序及其子程序中全局可用的,常常用来储存像默认的文本编辑器或者浏览器,以及可执行文件的路 ...
- Xcode 8:在 Active Compilation Conditions 中自定义环境变量
来源:没故事的卓同学 链接:http://www.jianshu.com/p/96b36360bb2d 在Xcode 7我们在 OTHER_SWIFT_FLAGS中配置环境变量.但是有一个不爽的地方就 ...
- bootargs中的环境变量说明和一些常用的uboot命令
bootargs中的环境变量说明和一些常用的uboot命令 一些常见的uboot命令:Help [command]在屏幕上打印命令的说明Boom [addr]启动在内存储器的内核Tftpboot通过t ...
- python 程序中设置环境变量
python 中调用系统命令有三种方法: 1.os.system('command') ,这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 ...
- 关于Lumen / Laravel .env 文件中的环境变量是如何生效的
.env 文件包含默认环境变量,我们还可自定义其他任何有效的变量,并可通过 调用 env() 或 $_SERVER 或 $_ENV 来获取该变量.那么env()是如何加载到这些变量的呢?在Lume ...
- 怎样在Ubuntu中设置环境变量
首先启动终端. 单击屏幕左上角的Ubuntu图标,在弹出的窗口中点击搜索栏,输入"terminal", 稍等片刻,终端就会赫然在目!二话不说,直接点击! 然后打开环境设置文 ...
- 解析docker中的环境变量使用和常见问题解决
docker容器中的环境变量 docker可以为容器配置环境变量.配置的途径有两种: 在制作镜像时,通过ENV命令为镜像增加环境变量.在容器启动时使用该环境变量. 在容器启动时候,通过参数配置环境变量 ...
随机推荐
- .replace(R.id.container, new User()).commit();/The method replace(int, Fragment) in the type FragmentTransaction is not app
提示错误:The method replace(int, Fragment) in the type FragmentTransaction is not applicable for the arg ...
- FutureTask的使用
package org.zln.thread.pool.ft;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.ut ...
- BIOS设置和CMOS设置的区别与联系
BIOS是主板上的一块EPROM或EEPROM芯片,里面装有系统的重要信息和设置系统参数的设置程序(BIOS Setup程序): CMOS是主板上的一块可读写的RAM 芯片,里面装的是关于系统配置的具 ...
- tomcat远程部署应用
Tomcat安装成功后,在ip地址:8080上就可以看见熟悉的首页,在这个首页中,上方有一个manage app按钮,点击就可以进行应用管理了.这样就不需要使用ftp把war包传上去了. 要想远程部署 ...
- LCS问题
最长公共子序列问题 1.这里pre数组表示回溯的方式,状态转移方程!!! #include <iostream> #include <algorithm> #include & ...
- 【jQuery api】isFunction()
<!doctype html> <html lang="en"> <head> <meta charset="utf-8&quo ...
- redis的数据类型和指令
1.全局key操作: 测试指令: 全局key操作命令:忽略与key关联的value的类型 删 flushdb 清空当前选择的数据库 del mykey mykey2 删除了两个 Keys 改 move ...
- python实现计算器
计算器功能 实现优先级解析,加减乘除四则运算 自定义小数位精度 实现思想: 先找到最里层括号,根据乘除,加减优先级,调用写好的乘除.加减运算函数算出括号内总值,再将原括号式用所得值替换,此过程循环进行 ...
- JavaMeloay配置用于系统监控
JavaMelody JavaMelody能够监控Java或Java EE应用程序服务器的运行状况,并以图标的方式显示:java内存.CPU使用情况.用户Session数量.JDBC连接数.http请 ...
- 创建django项目
python /usr/local/lib/python3.4/dist-packages/Django-1.9.10-py3.4.egg/django/bin/django-admin.py sta ...