Bash 是如何从环境变量中导入函数的
在上文中曾说到:
- 所谓的环境变量的真实面目其实就是个任意字符串
- 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 是如何从环境变量中导入函数的的更多相关文章
- ***LINUX添加PHP环境变量:CentOS下将php和mysql命令加入到环境变量中
CentOS系统下如何将PHP和mysql命令加入到环境变量中,在Linux CentOS系统上 安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到 ...
- 将python文件加入到python的环境变量中
在python中,把一个python文件加入到python环境变量中,以方便其他python文件调用.有两种方式,下面对其进行简单的介绍 方式一: 导入系统自带的sys模块,然后将文件的路径进行追加或 ...
- 将NuGet配置到环境变量中
https://docs.nuget.org/consume/command-line-reference Installing The NuGet command line may be insta ...
- linux系统下将php和mysql命令加入到环境变量中的方法
在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行 “php -v”命令查看当前php版本信息时时 ...
- linux CentOS 系统下如何将php和mysql命令加入到环境变量中
在Linux CentOS系统上安装完php和MySQL后,为了使用方便,需要将php和mysql命令加到系统命令中,如果在没有添加到环境变量之前,执行“php -v”命令查看当前php版本信息时时, ...
- python解释器的安装;python2与python3同时在环境变量中时的解决方案
新文档 html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,addres ...
- CentOS下将php和mysql命令加入到环境变量中的几种方法
Linux CentOS配置LAPM环境时,为了方便,将php和mysql命令加到系统环境命令,下面我们记录几种在linux下将php和mysql加入到环境变量中的方法. 如果在没有添加到环境变量之前 ...
- Anaconda下的python如何写入环境变量中
Anaconda是一个非常好的python管理软件,实际使用起来要比直接用python自带的管理工具更好. 若需要将Anaconda下的python.exe添入环境变量中,需要如下设置 如上图所示,需 ...
- 【转】Linux将composer的bin目录放到PATH环境变量中
将composer的bin目录放到PATH环境变量中 使用composer global config bin-dir --absolute查看composer的bin目录 输出类似 Changed ...
随机推荐
- IP分片重组的分析和常见碎片攻击 v0.2
IP分片重组的分析和常见碎片攻击 v0.2http://www.nsfocus.net/index.php?act=magazine&do=view&mid=584 作者:yawl ( ...
- [tem]高精度1
1 //倒着存 B取的低精最大值所以简化了一点 #include <iostream> #include <cstdio> #include <cstring> # ...
- Rect 和 Bounds
Rect 表示一个2D矩形区域 Bounds 表示一个3D的方块区域 http://www.cnblogs.com/crazylights/p/3977348.html
- 简单的angular购物车商品小计
<!DOCTYPE html> <html lang="en" ng-app="shopApp"> <head> <m ...
- Core functionality.md
核心功能 在Nginx配置文件总可以把配置文件的结构如下: main配置段 event { ... } http { ... server { server_name root location /u ...
- LeetCode "419. Battleships in a Board"
The follow-up question is fun: "Could you do it in one-pass, using only O(1) extra memory and w ...
- Intellij Idea中的Jetty报出Web application not found src/main/webapp错误的解决方案
今天在Intellij Idea中编译项目的时候,运行起来一直会报出如下的错误: Web application not found src/main/webapp 当时感觉应该是什么文件缺少了.所以 ...
- 让游戏以高性能GPU(独立显卡)运行
在EXE中导出全局变量: N卡: extern "C" { __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001 ...
- 微信支付开发(1) JS API支付
关键字:微信支付 微信支付v3 jsapi支付 统一支付 Native支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3 ...
- ts 格式化日期输出
功能 像C#中DateTime的ToString的格式化输出一样,在js/ts中输出格式化的日期字符串 网上很多正则的,不加分隔符就不行了,和C#的格式也不一样 刚接触js/ts没两月,可能会有问题. ...