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命令为镜像增加环境变量.在容器启动时使用该环境变量. 在容器启动时候,通过参数配置环境变量 ...
随机推荐
- Android入门笔记(一)
第一部分,Android开发环境的搭建 1.去http://www.oracle.com/technetwork/java/javase/downloads/index.html下载最新版本jdk并安 ...
- JQuery记住用户名和密码的具体实现
代码如下: //初始化页面时验证是否记住了密码 $(document).ready(function() { if ($.cookie("rmbUser") == "tr ...
- 极客DIY:打造你的专属黑客U盘
简介 由于“Bad USB漏洞”的存在,USB闪存驱动器也成了常见的攻击目标.Bad-USB让黑客可以重新编程微控器作为一个“人机界面装置”(HID)或键盘,然后在目标机器上执行自定义键盘敲击.这种情 ...
- 第23章 java线程通信——生产者/消费者模型案例
第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...
- Easy UI常用插件使用
一.easy UI是类似于jQuery UI的插件库,它提供了丰富的各种常用插件:tree.datagrid... tree插件: 语法:$(selector).tree([settings]); 常 ...
- IntelliJ IDEA 乱码解决方案 (项目代码、控制台等)
IntelliJ IDEA 乱码解决方案 (项目代码.控制台等) 最近IDE从eclipse改成IntelliJ IDEA 了,原因是公司大部分人都在用这个IDE,而且一直推荐用,所以尝尝鲜.换的第一 ...
- 洛谷P1111 修复公路
题目背景 A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数N,和公路数M,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你什么时 ...
- Linux下安装VMware Tools 的方法
1.按下 CTRL + ALT 组合键,进入主操作系统,点击VMware虚拟机菜单下的安装虚拟机工具子菜单. 菜单:VM->Install VMware tools....(虚拟机->安 ...
- sql where and or优先级 待验证
where 后面如果有and,or的条件,则or自动会把左右的查询条件分开,即先执行and,再执行or.原因就是:and的执行优先级最高! 关系型运算符优先级高到低为:not and or 问题的解决 ...
- MVC架构模式分析与设计(一)---简单的mvc架构
首先 我要感谢慕课网的老师提供视频资料 http://www.imooc.com/learn/69 下面我来进行笔记 我们制作一个简单的mvc架构 制作第一个控制器 testController.cl ...