上文中曾说到:

  • 所谓的环境变量的真实面目其实就是个任意字符串
  • Bash 在启动时会将 environ 数组中包含 = 号的字符串导入成为自己的变量
  • Bash 在启动外部命令时会将自己内部标记为环境变量的变量重组成字符串数组赋值给 environ

本文中继续深入讲三点:

  • environ 数组中可能存在 = 左边名字相同的元素,也就是同名的环境变量,Bash 是怎么导入的?
  • Bash 还可以从环境变量中导入函数,甚至同时导入两个同名的变量和函数
  • Bash 还可以同时导出两个同名的变量和函数

如果有两个同名的环境变量,很简单,那么后面的值会覆盖前面的:

$ env foo=1 foo=2 bash -c 'echo $foo'

2

上篇文章中我们没有提到过函数,Bash 其实是可以从环境变量中导入函数的,比如下面这样:

$ foo() { echo foo函数; }

$ export -f foo

$ bash

$ foo

foo函数

上一级的 Shell 把函数传给了它的 child shell,Bash 是怎么实现的呢?我们用 env 命令演示一下:

$ env 'BASH_FUNC_foo%%=() { echo foo函数; }' bash -c 'foo'

foo函数

其实 Bash 就是把满足 "BASH_FUNC_函数名%%=(){ 函数体" 格式的环境变量作为函数源码解析并导入。所以两个同名的变量和函数并不会冲突,可以同时导入,像这样:

$ env 'foo=1' 'BASH_FUNC_foo%%=() { echo $1; }' bash -c 'foo $foo'

1

既然可以同时导入,那么导出更没问题了:

$ foo=1

$ foo(){ echo foo函数; }

$ export foo;export -f foo

$ env

...

foo=1

BASH_FUNC_foo%%=() { echo foo函数

}

...

Bash 4.3.30 之前的版本

注意,本文所讲的表现仅适用于 Bash 4.3.30 及之后的版本,之前的 Bash 版本在导出函数时不会给函数名加上 BASH_FUNC_ 前缀和 %% 后缀,在导入时也不会识别前缀后缀,只要看到 = 右边是 "() {" 这四个字符,就按函数导入,像这样:

$ env 'foo=() { echo foo函数; }' bash -c 'foo'

foo函数

由于环境变量字符串的转换和识别规则不同,假如你在 Bash 4.3.30 中打开一个 Bash 3.2.25,后者是无法继承到前者导出的函数的:

$ bash4.3.30

$ foo() { echo foo函数 ; }

$ export -f foo

$ bash3.2.25

$ foo

bash3.2.25: foo: command not found

反之亦然,同时 foo 会被导入成一个变量:

$ bash3.2.25

$ foo() { echo foo函数 ; }

$ export -f foo

$ bash4.3.30

$ foo

bash3.2.25: foo: command not found

$ echo $foo

() { echo foo函数 }

Bash 是如何从环境变量中导入函数的的更多相关文章

  1. ***LINUX添加PHP环境变量:CentOS下将php和mysql命令加入到环境变量中

    CentOS系统下如何将PHP和mysql命令加入到环境变量中,在Linux CentOS系统上 安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到 ...

  2. 将python文件加入到python的环境变量中

    在python中,把一个python文件加入到python环境变量中,以方便其他python文件调用.有两种方式,下面对其进行简单的介绍 方式一: 导入系统自带的sys模块,然后将文件的路径进行追加或 ...

  3. 将NuGet配置到环境变量中

    https://docs.nuget.org/consume/command-line-reference Installing The NuGet command line may be insta ...

  4. linux系统下将php和mysql命令加入到环境变量中的方法

    在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行 “php -v”命令查看当前php版本信息时时 ...

  5. linux CentOS 系统下如何将php和mysql命令加入到环境变量中

    在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行“php -v”命令查看当前php版本信息时时, ...

  6. python解释器的安装;python2与python3同时在环境变量中时的解决方案

    新文档 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addres ...

  7. CentOS下将php和mysql命令加入到环境变量中的几种方法

    Linux CentOS配置LAPM环境时,为了方便,将php和mysql命令加到系统环境命令,下面我们记录几种在linux下将php和mysql加入到环境变量中的方法. 如果在没有添加到环境变量之前 ...

  8. Anaconda下的python如何写入环境变量中

    Anaconda是一个非常好的python管理软件,实际使用起来要比直接用python自带的管理工具更好. 若需要将Anaconda下的python.exe添入环境变量中,需要如下设置 如上图所示,需 ...

  9. 【转】Linux将composer的bin目录放到PATH环境变量中

    将composer的bin目录放到PATH环境变量中 使用composer global config bin-dir --absolute查看composer的bin目录 输出类似 Changed ...

随机推荐

  1. Apache配置

    redhat6.4企业版用的centos的yum源. 下面进行apache的安装与配置. 1.yum在线安装Apache 一般不采用yum在线安装因为如果apache坏掉了,yum安装过程中会有依赖的 ...

  2. [转]Python 字符串操作实现代码(截取/替换/查找/分割)

    原文地址:http://www.jb51.net/article/38102.htm ps:好久没更新python代码了,这次用到了字符串,转来看看 Python 截取字符串使用 变量[头下标:尾下标 ...

  3. 使用Struts框架,实现用户登陆功能

    前言:本篇文章是本人这周学习的一个小结,在自我总结的同时,希望也能够给其他同学带来一点帮助.本文主要知识是参照书本上的知识点以及网上其他博客文章,在上机操练后的所得,具体源码主要来自http://bl ...

  4. 疑似easyui本身bug:easyui时间控件问题,试了几个版本都不行

    最近发现easyui时间控件的值格式不支持带斜杠的日期(2016/10/31),必须是2016-10-31这类的才能正常使用,否则默认初始化为当前时间 <input id="Retur ...

  5. 关于laravel基础知识

    laravel任务管理知识点 1.配置数据库环境 首先要找到congif/app.php,在这里会发现一些全局的系统设置,包括语言,时区等. 重要的是会发现前几个数组都使用了env()这个函数,这个时 ...

  6. Flooded!

    Flooded! Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 5955   Accepted: 1800   Specia ...

  7. 导出本地和远程SVN项目, Export remote SVN repository

    在有服务器控制权的情况下, 源服务器上 sudo svnadmin dump ironbank/ > ~/ironbank.svn.dump 在目的服务器上 sudo svnadmin crea ...

  8. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 实现缓存预热

    因为大型应用系统可能有几十个子系统,为了减轻数据库频繁读写压力.提高系统的运行速度.反映速度,大型应用系统都需要采用缓存机制提高运行效率.Redis 缓存预热实现将来大家很多基础数据都可以缓存获取,不 ...

  9. C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - .NET商业化成品成熟各种数据权限的需求对应例子代码

    还是我上次提出的那个问题问题:假设一个订单表,1.角色A可以看自己的2.角色B可以看工作组的3.角色C可以看金额是1000元以下的(自定义条件是否可行?如果可以,请详细说明)4.角色D可以看整个部门的 ...

  10. DOCKER是什么,它解决了什么问题?(转)

    Docker 虚拟机 1. docker与虚拟机性能比较 2. 如日中天的Docker解决了什么问题?