上文中曾说到:

  • 所谓的环境变量的真实面目其实就是个任意字符串
  • 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. Postgresql扩展及UUID

    切换数据库 \connect $DBNAME 查看Postgresql的可用扩展 SELECT * FROM pg_available_extensions; 安装所需扩展 CREATE EXTENS ...

  2. 《In Search of an Understandable Consensus Algorithm》翻译

    Abstract Raft是一种用于管理replicated log的consensus algorithm.它能和Paxos产生同样的结果,有着和Paxos同样的性能,但是结构却不同于Paxos:它 ...

  3. 【读书笔记《Bootstrap 实战》】4.企业网站

    上一章有对个人作品站点进行一些优化.本章,轮到我们充实这个作品站点了,补充一些项目,从而展示我们的能力.换句话说,我们要构建一个相对复杂的企业网站主页. 下面有几个成功企业的网站: □ Zappos ...

  4. hibernate inverse属性的作用

    hibernate配置文件中有这么一个属性inverse,它是用来指定关联的控制方的.inverse属性默认是false,若为false,则关联由自己控制,若为true,则关联由对方控制.见例子: 一 ...

  5. Jsp 错题分析

    ArrayList删除元素通过RemoveAt(int index)来删除指定索引值的元素 运行时异常都是RuntimeException类及其子类异常,如NullPointerException.I ...

  6. MySQL 笔记2

    -- *************一.数据约束********************---- -- 1.1 默认值 CREATE TABLE student( id INT, NAME ), addr ...

  7. docker创建镜像

    手动创建: docker run -d -p mynginx:v2 nginx rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest- ...

  8. asp.net(C#)网站发布后 Global.asax 里 Application_Error 不执行的问题

    现象 在 Global.asax 用 Application_Error 捕捉了http的404,500等错误,在本机测试正常,发布后无效,几经周折终于解决了... 程序是这样设计的 Applicat ...

  9. 【转载】WEB前端开发规范文档

    本文转载自谈笑涧<WEB前端开发规范文档> 为 新项目写的一份规范文档, 分享给大家. 我想前端开发过程中, 无论是团队开发, 还是单兵做站, 有一份开发文档做规范, 对开发工作都是很有益 ...

  10. [Leetcode] Course Schedule

    There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...