Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2314823
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类: LINUX

2010-02-26 20:35:54



看到一段文字:
ust informational:

Internally, for forking, Bash stores the function definitions in environment variables. Variables with the content ”() ....”.

Something like the following works without “officially” declaring a function:

$ export testfn="() { echo test; }"
$ bash -c testfn
test
$

似乎是bash的一个undocumented的特性, 对这一特性的试验继而让我对bash中的变量管理困惑不已, 通过gdb
 一个调试版的bash终于把它搞明白, 这一过程中发生了很多诡异的事情:

* export testfn='() { echo test; }'
会在当前shell的环境变量中加入一项, 与普通A=B的变量无异, 注意这里说"环境变量"时, 是指任何一个进程
都会有的一个环境块, 不要与bash中非环境普通变量混淆.
* bash -c testfn
产生的新进程: 那个子bash, 从此开始, 就有一堆奇怪的事情:

echo $testfn
你看不到这个环境变量, 一般配置下, 输入
echo $testf 此时按会补齐这个环境变量名, 这是readline做的事, 但readline也不没有补齐, 这是怎么
回事?
type testfn
会看到在子bash中, 有一个testfn函数:

testfn is a function
testfn ()
{
echo test
}
至此, 你可能以为子bash对环境变量parse之后识别出这种特殊形式, 进而把它定义为一个函数, 同时把它
从环境变量中删除了.

但是, 它并未从环境变量中被删除:
env 或 printenv
可以看到它, 取值竟与父bash中略有不同, 把';'换成了一个换行符. 我一开始很怀疑是env 或 printenv 的问题,
但查看了coreutils中 printenv的源码后打消了我的疑惑, 代码很短, 直接显示所有的environ内容.

所以, 问题是出在bash!, 把bash的源代码抓回来, 发现靠静态地跟踪对这个问题的处理比较困难, 在variables.c
的unbind_func上加了断点, 证实了猜测:

unset -f testfn
时, 貌似只删除函数, 但同时也删除了作为该函数来源的环境变量, 这算什么事! 系统环境变量与函数名被bash
搞得如此混乱.

待续...

阅读(935) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~