见鬼的事怎么总是我碰上。
$ cat kshbug
{ return 0; } &
evil=$(/bin/true) # XXX: works fine without this line
wait $!
echo $?
$ ksh kshbug
127
$ ksh --version
version sh (AT&T Labs Research) 1993-12-28 r
The correct return code should be 0. Without the line of "eval=$(bin/true)"
everything works fine. The problem happens only when
- Execute a function or a clause in background, and
- A subshell is invoked between the background execution and the "wait", and
- An external command is executed in the subshell
I googled for a while, there's no ksh bug report so far, workaround could be use output text for return code check instead. Note there's a similar report for ksh on solaris but it's not the identical issue.
Pdksh (public domain ksh) doesn't have the problem. (See another bug.)
Update: this issue doesn't happen on Ubuntu ksh version "sh (AT&T Research) 93s+ 2008-01-31".
Nov 9, 2009 at 3:37pm | 1 Comment
Tags: ksh
用 TETware 做自动化测试框架,越来越觉得这玩意很差,至少是 ksh API 这部分,用我同事的话说,已经“out”了,在我手上改了不少,仍然不够好用。今天竟然发现一个记 log 的接口里面竟然会死循环,调查下去竟然是个 ksh93 的 bug,要不是这个接口写得这么烂,也许这个 bug 永远都见不到天日了。
废话扯完了,看看是什么 bug。
${parameter%pattern} 用来从 parameter 字符串中去掉 pattern 后缀,${parameter#pattern} 用来从 parameter 字符串中去掉 pattern 前缀,这两个经常用来取路径名中的目录和文件名。但是当 parameter 是个多行字符串并且 pattern 符合 “\n.*(.*).*” 模式时它们不干了:
$ cat ksh93bug
NL=$'\n'
PAT="$1"
A="Hello $NL$PAT"
echo "${A%$NL$PAT}"
A="$PAT$NL world"
echo "${A#$PAT$NL}"
$ ksh ksh93bug '()'
Hello
()
()
world
$ ksh ksh93bug 'a(b)c'
Hello
a(b)c
a(b)c
world
仅仅是 AT&T ksh93,包括最新版本都有这个问题,在 bash 和 public domain ksh 中没有问题:
$ bash ksh93bug '()'
Hello
world
$ bash ksh93bug 'a(b)c'
Hello
world
我们的例子是 out=$(mount) 接着 tet_infoline "$out"它就歇菜了,TETware 的 tetapi.ksh 在 tet_output 函数里面用 %% 在循环里面去处理多行文本,哪里想到后缀永远删除不掉,在我试图加 set -x 调试的时候迅速的将硬盘写满了:P
本想报告这个 bug,在 ksh93 主页 上没找到给谁报,懒得伺候了,先改 TETware 再说了。
Mar 16, 2009 at 6:44am | 0 Comments
Tags: ksh