On Mon, Aug 1, 2016 at 8:27 AM, Eric Blake <ebl...@redhat.com> wrote: > On 07/31/2016 06:36 PM, Jim Meyering wrote: > >> dash's printf builtin handles \e differently -- that's easy to work >> around: use \033, which *is* portable. >> More surprising is that this generates no output: >> >> dash -c 'f() { local t=$(printf '\''\t\t'\''); printf "$t"; }; f' > > That's because you made the classic mistake of using local AND assigning > to the variable at the same time. > > This works: > > dash -c 'f() { local t; t=$(...); printf "$t"; }; f' > > The difference? There is a notion of an assignment context: > http://austingroupbugs.net/view.php?id=351 > > Bash treats 'local' like 'export' in introducing an assignment context > (so "" around local t=$() is optional); but 'local' is not specified by > POSIX, so dash does NOT treat it as an assignment context. Since local > is a command name, you MUST use "" in all subsequent words, or else > defer the actual assignments to standalone statements, to get assignment > context. > >> >> I.e., piping it into wc -c prints 0. >> With bash, it prints the expected pair of TAB bytes. >> I found that I could work around this nonsensical behavior by hoisting >> the "tab=..." definition up/out of those two functions, or by adding >> standard-says-never-necessary double quotes like this: >> >> dash -c 'f() { local t="$(printf '\''\t\t'\'')"; printf "$t"; }; f' > > Umm, the standard is silent. local is not defined by the standard. > >> >> However, I prefer not to work around it here (and in every other test >> script where this comes up), and will insulate all of our test scripts >> by rejecting any shell with that misbehavior, so plan to adjust >> init.sh to select another shell when it finds this flaw. > > It's not a flaw in dash, but in your expectations.
Thanks for the explanation. This is a corner of the non-standard that I prefer not to have to remember and constantly work around. IMHO, bash and zsh get it right, and dash chose behavior that makes shell scripting with it harder than necessary.