October, 2011 中的文章
我们知道 -c 的意思是 command,所以 bash -c 后面应该跟一个 command。连 bash 的 man page 中都这么说:
-c string If the -c option is present, then commands are read from string.
If there are arguments after the string, they are assigned to the positional parameters, starting with $0.
而实际上不对。我们看下面的例子:
% bash -c “echo a b c”
a b c
% bash -c echo a b c
% bash -cx “echo a”
+ echo a
a
如果 -c 后面跟一个参数 string的话,那么第三个例子中的 -cx 应该会报错,找不到x这个命令,而实际上没有报错,也就是说,-c 和 -x 一样,后面不跟任何参数。
再看上面第二个例子中,为什么只有换行输出?手册中说,如果后面还有参数的话,那么它们被赋值给$0,$1,$2等等,也就是说,bash -c echo a b c,实际上只执行了 bash -c echo,所以只输出了换行!我们可以看更好的例子:
% bash -c ‘echo “\$0 is $0, \$1 is $1, \$2 is $2″‘ foo bar biz
$0 is foo, $1 is bar, $2 is biz
% echo ‘echo “\$0 is $0, \$1 is $1, \$2 is $2″‘ > /tmp/args
% chmod +x /tmp/args
% bash -c /tmp/args foo bar biz
$0 is /tmp/args, $1 is , $2 is
% bash -c ‘/tmp/args; echo \$0 is $0, \$1 is $1, \$2 is $2′ foo bar biz
$0 is /tmp/args, $1 is , $2 is
$0 is foo, $1 is bar, $2 is biz
1. 入门的,《The Little Book of Semaphores》
The Little Book of Semaphores is a free textbook that introduces the principles of synchronization for concurrent programming.
The approach of this book is to identify patterns that are useful for a variety of synchronization problems and then show how they can be assembled into solutions. After each problem, the book offers a hint before showing a solution, giving students a better chance of discovering solutions on their own.
The book covers the classical problems, including “Readers-writers,” “Producer-consumer”, and “Dining Philosophers.” In addition, it collects a number of not-so-classical problems, some written by the author and some by other teachers and textbook writers.
可以在它的官方网站下载:http://greenteapress.com/semaphores/
2. RCU 的作者,大牛 Paul E. McKenney 写的书,《Is Parallel Programming Hard, And, If So, What Can You Do About It?》。这个比较猛,我还没时间看。它也是免费的,英文版可以在这里下载:
git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/perfbook.git
现在已经被翻译成中文了,叫《深入理解并行编程》:
http://download.csdn.net/detail/xiebaoyou/3552357
我在南京和布拉格的时候见过 Paul E. McKenney,他是一个非常和蔼、热心的人,没有一点儿牛人的架子。:-)

忽然很想跟自己说声对不起,对不起总是让自己不开心
忽然很想跟自己说声对不起,对不起总是莫名其妙的忧伤
忽然很想跟自己说声对不起,对不起总是给自己太多的压力
忽然很想跟自己说声对不起,对不起总是忘了提醒自己好好照顾自己
忽然很想跟自己说声对不起,对不起总是不能为所欲为的做自己喜欢的事儿
忽然很想跟自己说声对不起,对不起总是和别人说对不起而忘了自己
忽然很想跟自己说声对不起,对不起因为悲观让自己不再相信生活
忽然很想跟自己说声对不起,对不起因为倔强让自己受了很多伤
忽然很想跟自己说声对不起,对不起因为伪装让自己活的很辛苦
忽然很想跟自己说声对不起,对不起因为年轻让自己疲惫了太久
忽然很想跟自己说声对不起,对不起因为悲伤麻烦了一些爱我的人
忽然很想跟自己说声对不起,对不起很久没有好好的照顾自己
忽然很想跟自己说声对不起,对不起很久没有好好的利用时间享受生活
忽然很想跟自己说声对不起,对不起很久没有给自己挑一份喜欢的礼物
忽然很想跟自己说声对不起,对不起曾经为了别人而难为自己
忽然很想跟自己说声对不起,对不起难过的时候只能让自己硬撑着
忽然很想跟自己说声对不起,对不起含泪微笑的时候我没有倾诉
忽然很想跟自己说声对不起,对不起心那么的疼还要假装着不在乎
忽然很想跟自己说声对不起,对不起让自己装了这么多年的无所谓
忽然很想跟自己说声对不起,对不起很多东西我没有学会好好珍惜
忽然很想跟自己说声对不起,对不起忘记了要搁浅
忽然很想跟自己说声对不起,对不起再也找不回原来的自己了
我弄丢了太多的东西、忘记了太多的事情、舍弃了太多的责任……
对不起,对不起,对不起,真的对不起……
不敢乞求自己的原谅,只有让自己活得更好才能对过去的生活有所补偿
忘记所有,重新开始
抬头仰望夜空,眼泪都已倒流,嘴角轻轻上扬
告诉自己
明天太阳依旧灿烂,生活却要华丽转身
(转自:http://www.douban.com/note/124817865/)
偶然在 dracut 的代码中发现一个使用重定向很巧妙的地方。见 modules.d/90kernel-modules/module-setup.sh 文件。
之前的老代码是这样的:
BASH:
-
##
-
local _f
-
while read _f; do case "$_f" in
-
*.ko) [[ $(< $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
*.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
esac
-
done
意思很清楚吧?就是在内核模块(注意是二进制格式)中匹配一些函数(字符串)。这样会很慢,因为 bash 要在庞大的二进制文件流中匹配一些指定字符串。
于是,就有人想了一个方法加速这个处理过程,把原来的单个数据流分成两个并行的数据流,同时进行匹配!很巧妙!
BASH:
-
##
-
function bmf1() {
-
local _f
-
while read _f; do case "$_f" in
-
*.ko) [[ $(< $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
*.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
esac
-
done
-
}
-
# Use two parallel streams to filter alternating modules.
-
local merge side2
-
( ( local _f1 _f2
-
while read _f1; do echo "$_f1"
-
if read _f2; then echo "$_f2" 1>&${side2}; fi
-
done \
-
| bmf1 1>&${merge} ) {side2}>&1 \
-
| bmf1 ) {merge}>&1
经过 refactor 之后的或许更好理解一些:
BASH:
-
# subfunctions inherit following FDs
-
local _merge=8 _side2=9
-
function bmf1() {
-
local _f
-
while read _f; do case "$_f" in
-
*.ko) [[ $(< $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
*.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
-
esac
-
done
-
}
-
function rotor() {
-
local _f1 _f2
-
while read _f1; do
-
echo "$_f1"
-
if read _f2; then
-
echo "$_f2" 1>&${_side2}
-
fi
-
done | bmf1 1>&${_merge}
-
}
-
# Use two parallel streams to filter alternating modules.
-
eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"
以前只知道 vlan 设备的名字都是像 bond0.77 这种格式,前两天拿到一台机器,上面的 vlan 是 vlan77,而且 ifcfg-vlan77 多了一个 PHYSDEV=bond0。这才明白原来 vlan 还可以这么配置。
可是我仍然想测一下之前的 bond0.77 这个格式的配置,因为 kdump 要解释这两个不同的格式。于是我把 ifcfg-vlan77 重命名为 ifcfg-bond0.77,并且把 DEVICE=vlan77 改为 DEVICE=bond0.77,结果重启之后出错。看了半天的 ifup 的代码也没找到问题出在哪里。忽然注意到 /proc/net/vlan 下面仍然是 vlan77,于是开始扒内核的源代码,终于在 net/8021q/vlanproc.c 里发现了问题的所在。
我忘记修改 VLAN_NAME_TYPE=VLAN_PLUS_VID_NO_PAD 这一项!看内核源代码很了然,VLAN_PLUS_VID_NO_PAD 就是说名字格式是 "vlan" + VLANID,而且没有填充0,也就是 “vlan77” 这种格式。VLAN_NAME_TYPE=DEV_PLUS_VID_NO_PAD 才是我想要的设备名+VLANID,比如 bond0.77。如果不加“NO_PAD”的话,VLAN_NAME_TYPE=DEV_PLUS_VID 就会把设备命名成 bond0.0077了。

去新疆之前路过成都的时候,杜姑娘推荐我看一下这本书。上火车之前,正好在成都的一家书店买到了它。
过多的评价用不着,我只想说一句,这本书是我读过的最最幸福的文字!一个在阿勒泰的角落里生活的裁缝,怎么能写出这么幸福这么朴实得打动人心的文字呢!:-) 这让我想起了《万物有灵且美》这本书,作者是一个英国的乡村兽医,同样是不怎么起眼的职业,他们写出的文字一点儿都不华丽,可就是这种朴实、乐观、幸福,足以打动每一个读者!
由此可见,幸福和职业无关,和金钱更是没有关系,“苦和甜来自外界,而体味幸福却来自内心”!这个在阿勒泰当裁缝的李娟足以让每一个生活在大城市还每天矫揉造作的人无地自容了。
我去新疆的时候也去了阿勒泰,去了那个“童话边的小城”布尔津,也去了那个“遍地都是宝石”的可可托海镇。从布尔津到可可托海真费了我不少功夫,先是坐车到阿勒泰市(后来才知道其实可以在北屯镇转车的),再转车到富蕴县,再转车到可可托海镇,要去景区的话还得转车……到了可可托海镇才发现,这么一个小地方就是李娟所谓的“算得上真正的城市”!天呐,她到底生活在阿勒泰的哪个小小小小角落里!
阿勒泰有很多哈萨克族人,他们应该是为数不多的现在还在过游牧生活的民族。我在去阿勒泰市的路上看到不少赶着骆驼、骑着马、放着羊的哈萨克人,而骆驼上驼着各种各种的东西,有桌子,帐篷,家具……要我说,他们才是真正的四海为家的人!
我们在禾木碰到过两个哈萨克小伙儿,都很幽默。其中一个小伙儿骑着马,主动上来跟我们当中的姑娘搭讪,用他那不太流利的汉语介绍说,“我——叫——哈——哈”。哈哈哈哈,我们一听就笑了!另一个小伙儿是住的客栈碰到的,叫克里木,他硬是从我这儿蹭走了一个打火机!我怎么觉得哈萨克族的小伙儿都是这么“脸皮厚”呢,哈哈!
打住,继续说这本书。书上还留了她的博客地址,看到下面的一句“进城不易,更新缓慢”,我又笑了!再看看她的微博上,“不见网友。不见读者。不签名”,看来还是李娟懂得什么是幸福!