kcov
kcov copied to clipboard
bash: Support korn shell as well
PS4 seems to be present, e.g., http://www.livefirelabs.com/unix_tip_trick_shell_script/apr_2003/04282003.htm, so this should be technically possible.
It would be nice to support zsh as well. Zsh support is the same as ksh support technically. So I comment here instead of creating a new issue.
The ksh and the zsh has PS4
, but they does not have a feature like BASH_XTRACEFD
. However, it can be implemented using the DEBUG trap they have.
Current kcov not support ksh and zsh officially, But I managed to get it working with ksh and zsh.
Here is DEBUG trap handler for ksh and zsh. Ksh has some bugs, so it needs a workaround. See this issue for details.
# For ksh
trap '(echo "kcov@${.sh.file}@${LINENO}@" >/dev/fd/$KCOV_BASH_XTRACEFD); IFS=$IFS' DEBUG
# For zsh
trap '
if [ ${#funcsourcetrace[@]} -gt 0 ]; then
echo kcov@${funcsourcetrace[1]%:*}@$((${funcsourcetrace[1]##*:}+LINENO))@
else
echo kcov@${0}@${LINENO}@
fi >&$KCOV_BASH_XTRACEFD
' DEBUG
BTW, I prefer using DEBUG trap instead of PS4 for coverage. Because trace information (statement to execute) is not needed for coverage. And its output and parsing causes a slow down.
Wow! Nice work!
So in order to add this, I guess the bash engine would have to recognise ksh and zsh "hash bangs" and use the specific helpers for them? Sounds like it should be a fairly easy change.
Hi @SimonKagstrom,
You should not use "hash bangs". Because /bin/sh
may be bash or may be dash. Even zsh and ksh scripts may use #!/bin/sh
.
A better way is use shell script to detect the shell. You can also put all debug handlers to one file.
if [ "${BASH_VERSION:-}" ]; then
trap ... DEBUG # for bash
elif [ "${KSH_VERSION:-}" ]; then
trap ... DEBUG # for ksh
elif [ "${ZH_VERSION:-}" ]; then
trap ... DEBUG # for zsh
fi
Another problem is BASH_ENV
. You should use different methods for ksh and zsh.
- ksh: Use
ENV
environment variable instead ofBASH_ENV
and run script byksh
with-E
option. - zsh: Zsh loads
$ZDOTDIR/.zshenv
automatically. Therefore create it to temporary directory (e.g.out-dir
), and setting that directory path toZDOTDIR
.
Currently kcov only detects the bash version, but it needs to detect the shell type in addition.
For example. (Use this script instead of bash -c 'echo "$BASH_VERSION"
)
if [ "${BASH_VERSION:-}" ]; then
echo "bash $BASH_VERSION"
elif [ "${KSH_VERSION:-}" ]; then
echo "ksh $KSH_VERSION"
elif [ "${ZH_VERSION:-}" ]; then
echo "zsh $ZH_VERSION"
fi
And after supporting zsh and ksh. Kcov options --bash-*
are not appiciate name. :smile:
It uses the existence of hash bangs to find out what "engine" it should use (as opposed to compiled programs and Python scripts), so it needs to use them. However, it's easy enough to add the ksh and zsh hash bangs.
Anyway, after that I guess the best way is to read the /bin/sh symlink to find out what shell it is if it's not explicitly given in the hash bang? And then adding your ksh/zsh-specific debug handlers to the bash-helper.sh (renamed to shell-helper.sh) or something.
I've started work on a branch issue-137-ksh-zsh-support with your suggestions, but I'll work sporadically on it for now.
I've updated the branch now, with some sort of basic first working version. At least I think it's working. There are some hardcoded paths (/bin/zsh, /bin/ksh) which are not good.
That is great! I will try.
Oh... sorry. I've made a mistake.
elif [ "${ZH_VERSION:-}" ]; then
echo "zsh $ZH_VERSION"
fi
Wrong: ZH_VERSION
Correct: ZSH_VERSION
You're the zsh expert so I just copied your code blindly :-)
Any news on that?
Unfortunately, I haven't been working on this. Daytime work plus life has intervened, so not much kcov work the last year.
I did update the branch were the work was started on though, so if you want to try it out it's in the
issue-137-ksh-zsh-support
branch. It's not finished, but at least via some basic testing it worked.
No problem at all, was just wondering if you were still considering it! I'll try to have a look soon