在 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 OLDPWD
declare -x PWD="/Users/admin"
declare -x SHLVL="1"

declare -x 1 显然是非法的,甚至还可以这样:

$ env -i $'foo\nrm -rf /=' bash -c export

declare -x OLDPWD
declare -x PWD="/Users/admin"
declare -x SHLVL="1"
declare -x foo
rm -rf /

看起来很有风险的样子,不过目前 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
SHLVL=1
1=1
_=/usr/bin/env

Bash 在启动其他程序的时候,会把自己所有的变量中带有 att_exported 属性且值不是空的变量以及它们的值分别用 = 连接起来合成一个字符串数组,重新复值给 environ 变量,也就是做了和启动时导入环境变量相反的操作。

那些没有等号或者等号左边没有字符的环境变量,因为 Bash 在启动的时候就丢弃了,所以也就没法传递给它的子进程了。

Bash 中的环境变量的更多相关文章

  1. Linux中PATH环境变量的作用和使用方法

    关于PATH的作用:PATH说简单点就是一个字符串变量,当输入命令的时候LINUX会去查找PATH里面记录的路径.比如在根目录/下可以输入命令ls,在/usr目录下也可以输入ls,但其实ls这个命令根 ...

  2. 更优雅的配置:docker/运维/业务中的环境变量

    目录 docker-compose 环境变量 .env 文件 env_file docker stack 不支持基于文件的环境变量 envsubst envsubst.py 1. 使用行内键值对 2. ...

  3. 设置与查看Linux系统中的环境变量

    大家好,我是良许. 大家都知道,在 Linux 系统中,有环境变量和 Shell 变量这两种变量. 环境变量是在程序及其子程序中全局可用的,常常用来储存像默认的文本编辑器或者浏览器,以及可执行文件的路 ...

  4. Xcode 8:在 Active Compilation Conditions 中自定义环境变量

    来源:没故事的卓同学 链接:http://www.jianshu.com/p/96b36360bb2d 在Xcode 7我们在 OTHER_SWIFT_FLAGS中配置环境变量.但是有一个不爽的地方就 ...

  5. bootargs中的环境变量说明和一些常用的uboot命令

    bootargs中的环境变量说明和一些常用的uboot命令 一些常见的uboot命令:Help [command]在屏幕上打印命令的说明Boom [addr]启动在内存储器的内核Tftpboot通过t ...

  6. python 程序中设置环境变量

    python 中调用系统命令有三种方法: 1.os.system('command') ,这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 ...

  7. 关于Lumen / Laravel .env 文件中的环境变量是如何生效的

    .env 文件包含默认环境变量,我们还可自定义其他任何有效的变量,并可通过  调用 env() 或 $_SERVER 或 $_ENV  来获取该变量.那么env()是如何加载到这些变量的呢?在Lume ...

  8. 怎样在Ubuntu中设置环境变量

    首先启动终端. 单击屏幕左上角的Ubuntu图标,在弹出的窗口中点击搜索栏,输入"terminal", 稍等片刻,终端就会赫然在目!二话不说,直接点击!     然后打开环境设置文 ...

  9. 解析docker中的环境变量使用和常见问题解决

    docker容器中的环境变量 docker可以为容器配置环境变量.配置的途径有两种: 在制作镜像时,通过ENV命令为镜像增加环境变量.在容器启动时使用该环境变量. 在容器启动时候,通过参数配置环境变量 ...

随机推荐

  1. Maven设置代理服务器

    在setting.xml中设置以下信息即可,请修正对应信息 <proxies> <proxy> <id>optional</id> <active ...

  2. hdfs 通过NFSV3 加载至本地目录

    常常会有这种需求,把HDFS的目录MOUNT到本地目录,然后方便使用LINUX下面的命令直接操作. FUSE也可以达到同样的效果,但是配置比较复杂,新的HADOOP版本都建议使用NFS3来完成这个需求 ...

  3. 理解 OpenStack 高可用(HA)(3):Neutron 分布式虚拟路由(Neutron Distributed Virtual Routing)

    本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...

  4. 双11遇上ZBrushCore,如此优惠还等什么!

    对不起!让大家久等了,ZBrush简体中文版ZBrushCore这次是真的来了,恰逢双11,老板说了,钱不是问题,你们开心就好,特别是热爱3D的单身狗们!你们那么热爱这个行业,1099元/套终身授权使 ...

  5. 适配iOS10的哪些事 ---- 学习笔记八

    一. 上传了一个版本,为什么没有构建版本? 解:info.plist中的Bundle version 与上一个版本一致或少于上一个版本,上线新版本时,Bundle version和Bundle ... ...

  6. mybatis传入多个参数

    一.单个参数: public List<XXBean> getXXBeanList(String xxCode); <select id="getXXXBeanList&q ...

  7. CWMP开源代码研究3——ACS介绍

    声明:本文涉及的开源程序代码学习和研究,严禁用于商业目的. 如有任何问题,欢迎和我交流.(企鹅号:408797506) 本文介绍自己用过的ACS,其中包括开源版(提供下载包)和商业版(仅提供安装包下载 ...

  8. c3p0数据源的使用初步及Mysql8小时问题解决

    原文:http://blog.csdn.net/xby1993/article/details/23707775 c3p0号称是java界最好的数据池. c3p0的配置方式分为三种,分别是 1.set ...

  9. 招聘前端、Java后端开发、测试、Mysql DBA

    公司介绍: http://www.lagou.com/gongsi/43095.html http://www.yamichu.com 简历发到: zhuye@yamichu.com 招聘职位: JA ...

  10. jquery版楼层滚动特效

    <!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>楼 ...