Does anyone have access to FreeBSD, or know what shell heritage their /bin/sh has? This patch was extracted from reports on the git mailing list against the FreeBSD 6.1 /bin/sh, which I don't have access to. But I reproduced the issues using cygwin's ash, so I'm documenting them.
http://marc.info/?l=git&m=121073772610342&w=2 corrupted $? when combining && and | $ sh -c 'true && ! true | true; echo $?' 1 $ ash -c 'true && ! true | true; echo $?' 0 http://marc.info/?l=git&m=121066841020121&w=2 corrupted $? when entering function $ sh -c 'foo(){ echo $1 $?; }; (exit 2); foo $?' 2 2 $ ash -c 'foo(){ echo $1 $?; }; (exit 2); foo $?' 2 0 http://marc.info/?l=git&m=121066841020125&w=2 export of undefined variable creates empty variable $ sh -c 'export foo; env | grep foo' $ ash -c 'export foo; env | grep foo' foo= Of these three, the first two are definite bugs, but for the third, I found the wording in POSIX to be too ambiguous to determine if there was an actual compliance problem. >From 3ca7a51d0fa4e6ed467668503bd0246eb5d275c1 Mon Sep 17 00:00:00 2001 From: Eric Blake <[EMAIL PROTECTED]> Date: Wed, 14 May 2008 08:25:01 -0600 Subject: [PATCH] Document some FreeBSD shell bugs. * doc/autoconf.texi (Limitations of Builtins) <!>: Mention ! issue in compound pipe commands. <export>: Mention difference of exporting an undefined variable. (Shell Functions): Mention loss of $? in entry to shell functions. Extracted from the git mailing list. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> --- ChangeLog | 9 +++++++++ doc/autoconf.texi | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index dc02724..3782a5b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-05-14 Eric Blake <[EMAIL PROTECTED]> + + Document some FreeBSD shell bugs. + * doc/autoconf.texi (Limitations of Builtins) <!>: Mention ! issue + in compound pipe commands. + <export>: Mention difference of exporting an undefined variable. + (Shell Functions): Mention loss of $? in entry to shell functions. + Extracted from the git mailing list. + 2008-05-13 Stepan Kasal <[EMAIL PROTECTED]> Work around MSYS and Cygwin bugs when dealing with trailing space. diff --git a/doc/autoconf.texi b/doc/autoconf.texi index 645cc7b..fd60b7b 100644 --- a/doc/autoconf.texi +++ b/doc/autoconf.texi @@ -12297,7 +12297,7 @@ by all shells! Shell functions are considered portable nowadays, though Autoconf still does not use them (Autotest does). However, some pitfalls have to be -avoided for portable use of shell functions. +avoided for portable use of shell functions (@pxref{Shell Functions}). Some ancient systems have quite small limits on the length of the @samp{#!} line; for instance, 32 @@ -13704,6 +13704,19 @@ subshell if the last command of that subshell was @code {exit} or find a shell that does not exhibit the bug, zsh might be the only shell present on the user's machine. +Likewise, the state of @samp{$?} is not reliable when entering a shell +function. This has the effect that using a function as the first +command in a @command{trap} handler can cause problems. + [EMAIL PROTECTED] +$ @kbd{bash -c 'foo()@{ echo $?; @}; trap foo 0; (exit 2); exit 2'; echo $?} +2 +2 +$ @kbd{ash -c 'foo()@{ echo $?; @}; trap foo 0; (exit 2); exit 2'; echo $?} +0 +2 [EMAIL PROTECTED] example + Shell variables and functions may share the same namespace, for example with Solaris 10 @command{/bin/sh}: @@ -13762,6 +13775,16 @@ must use @samp{. ./foo}. The Unix version 7 shell did not support negating the exit status of commands with @command{!}, and this feature is still absent from some shells (e.g., Solaris @command{/bin/sh}). +Other shells, such as FreeBSD @command{/bin/sh} or @command{ash}, have +bugs when using @command{!} in compound commands: + [EMAIL PROTECTED] +$ @kbd{sh -c 'true && ! true | true; echo $?'} +1 +$ @kbd{ash -c 'true && ! true | true; echo $?'} +0 [EMAIL PROTECTED] example + Shell code like this: @example @@ -14138,8 +14161,18 @@ alternately @samp{foo} and @samp{bar}, although they should print only @samp{foo} and then a sequence of @samp{bar}s. Therefore you should @command{export} again each environment variable -that you update. +that you update; the export can occur before or after the assignment. + +Posix is not clear on whether the @command{export} of an undefined +variable causes the variable to be defined with the value of an empty +string, or merely marks any future definition of a variable by that name +for export. Various shells behave differently in this regard: [EMAIL PROTECTED] +$ @kbd{sh -c 'export foo; env | grep foo'} +$ @kbd{ash -c 'export foo; env | grep foo'} +foo= [EMAIL PROTECTED] example @item @command{false} @c ------------------ -- 1.5.5.1
