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. -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org
signature.asc
Description: OpenPGP digital signature