Quoted closing brace in variable default expansion
Hi all, It's probably best to start with the example: $ bash -c 'echo "${x:-"}"}"' } $ ksh -c 'echo "${x:-"}"}"' } $ dash -c 'echo "${x:-"}"}"' dash: 1: Syntax error: Unterminated quoted string $ busybox sh -c 'echo "${x:-"}"}"' sh: syntax error: unterminated quoted string It looks like dash and other ash derivatives stop the expansion with the first }, instead of the first unquoted }. I'm getting confused trying to figure out whether this is a bug in dash or in the script relying on it. A slightly modified example: $ dash -c 'echo "${x-"_{x}_"}"' dash: 1: Syntax error: Unterminated quoted string $ dash -c 'echo ${x-"_{x}_"}' _{x_} I don't understand how the last line works. The } is printed after the _, so the } that is printed must be the final }, and the } directly following the x stops the variable default. But this would lead to two double quote characters which have no way of matching up, yet no syntax error is given. Could you clarify? Cheers, Harald -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Quoted closing brace in variable default expansion
Hi Herald, Harald van Dijk wrote: > $ ksh -c 'echo "${x:-"}"}"' > } > $ dash -c 'echo "${x:-"}"}"' > dash: 1: Syntax error: Unterminated quoted string > $ busybox sh -c 'echo "${x:-"}"}"' > sh: syntax error: unterminated quoted string > > It looks like dash and other ash derivatives stop the expansion with > the first }, instead of the first unquoted }. I'm getting confused > trying to figure out whether this is a bug in dash or in the script > relying on it. The answer depends on how portable the script is meant to be. If the goal is to be portable to shells implementing future versions of the POSIX standard, there seems to be have been an interpretation[1] approved for the next major revision: http://austingroupbugs.net/view.php?id=221 note #399 which would make the example nonconformant because there are an odd number of unescaped double-quotes before the first unescaped closing brace. See http://thread.gmane.org/gmane.comp.shells.dash/262/focus=263 for a nice summary (thanks, Jilles!). Hope that helps, Jonathan -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Quoted closing brace in variable default expansion
On 13/11/10 17:41, Jonathan Nieder wrote: Harald van Dijk wrote: $ dash -c 'echo "${x:-"}"}"' dash: 1: Syntax error: Unterminated quoted string http://austingroupbugs.net/view.php?id=221 note #399 Thanks, that helps to clarify. Unfortunately, the valid alternative given there: sh -c 'echo "${x:-\}}"' seemingly incorrectly prints \} with dash and with bash, so that is a non-option at this time for me. -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Quoted closing brace in variable default expansion
On Sat, Nov 13, 2010 at 10:41:47AM -0600, Jonathan Nieder wrote: > Harald van Dijk wrote: > > $ ksh -c 'echo "${x:-"}"}"' > > } > > $ dash -c 'echo "${x:-"}"}"' > > dash: 1: Syntax error: Unterminated quoted string > > $ busybox sh -c 'echo "${x:-"}"}"' > > sh: syntax error: unterminated quoted string > > It looks like dash and other ash derivatives stop the expansion with > > the first }, instead of the first unquoted }. I'm getting confused > > trying to figure out whether this is a bug in dash or in the script > > relying on it. > The answer depends on how portable the script is meant to be. If > the goal is to be portable to shells implementing future versions of > the POSIX standard, there seems to be have been an interpretation[1] > approved for the next major revision: > http://austingroupbugs.net/view.php?id=221 > note #399 > which would make the example nonconformant because there are an odd > number of unescaped double-quotes before the first unescaped closing > brace. Correct. > See http://thread.gmane.org/gmane.comp.shells.dash/262/focus=263 for > a nice summary (thanks, Jilles!). Note that I have changed FreeBSD 9 sh since I wrote that. To preserve sanity in expand.c, a substitution now ends with the same quoting level as it started. Closing braces that do not conform to this are taken literally. Making the parole configure script do what the author expected was a bonus. The change was needed to implement word splitting in WORD in ${v+WORD}. For that, expand.c needs to know the quoted state of any character of a word in ${v+-word}. Like NetBSD sh and dash have done, I added a new magic character CTLQUOTEEND that shows the end of the quoted part and interpreted CTLQUOTEMARK as the start. If I now have something like ${v-abc${vv-def"ghi}jkl"} I would have to pass through the fact that the quotes were opened in ${vv-def"ghi} to the outer substitution, and I did not want that. The change avoids it. FreeBSD 9 sh is now very close to ksh93 in treatment of POSIX substitutions and I am happy with this. (One of the deliberate differences is that the above incorrect construct is flagged as an error (missing '}') while ksh93 treats it as an incomplete command.) As for the portable alternative, split up the command. Either put the '}'-containing thing in a variable and use that as alternative or use an explicit conditional. The Autoconf documentation has more information, for example. -- Jilles Tjoelker -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: dash "set -e" breaks "trap INT"
On Wed, Nov 10, 2010 at 03:49:19PM +0200, Dan Muresan wrote: > I've submitted a bug regarding trap + "set -e" on Ubuntu Launchpad > [1], but that's probably not the best place to talk about the issue. > I'm using dash 0.5.5.1-3ubuntu2 from Ubuntu Lucid on an x86 machine. > With "set -e", only the first command in an INT trap handler gets > executed -- UNLESS that first command is a call to a function that > returns 0. Here's an example of the problem: > --- 8-x --- > #!/bin/sh > set -e > > trap 'hnd' INT > trap 'echo EXIT' EXIT > > zero() { > return 0; > } > > hnd() { > #zero > echo "Ignored 1"; echo "Ignored 2" > sleep 1 > echo Back > } > > for i in 3 2 1; do > echo "$i" > sleep 1 # || true > done > > echo OUT > --- 8-x --- > If we uncomment either the call to zero, or the || true check, the > entire handler gets executed. A set +e inside the handler makes no > difference. > My workaround at the moment is to trap both INT and EXIT (I'm not > going to rely on the "zero" bit of magic). I suppose this workaround > will unfortunately have to stick around for a while -- even if this > bug gets fixed, scripts can't assume they are running on the latest > version of dash. > [1] https://bugs.launchpad.net/ubuntu/+source/dash/+bug/673119 I can reproduce this with v0.5.5.1 but not with v0.5.6 or master, so apparently it has been fixed. The exit after the INT trap has been executed also occurs in all other shells I tried (newer dash, FreeBSD sh, mksh, true Bourne shell), except ksh93 which does not execute the INT trap at all, only the EXIT trap. The cause is that sleep also gets the SIGINT and terminates on it, which can be seen by removing set -e and adding echo rc=$? after sleep. ksh93 has a sleep builtin, but this has no effect on above. Behaviour remains the same with /bin/sleep. -- Jilles Tjoelker -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: static vs. dynamic scoping
On 09/11/10 23:02, Eric Blake wrote: 2. User aspect: Is anyone aware of a script that intentionally uses the full power of dynamic scoping available through 'local' which would break if scoping switched to static? FWIW, some scripts use "local IFS" to reset IFS to a sane value, and have the shell take care of restoring it afterwards. This works with ksh's typeset, but because of the static scoping only so long as no other shell functions get called, or those other shell functions also take the effort to handle IFS correctly. In the scripts I have been able to find, other shell functions do get called, but they themselves set IFS too. Still, it may be worth keeping in mind, if only to serve as one of the few examples of when dynamic scoping would have been slightly more useful. -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: static vs. dynamic scoping
How is dynamic scoping in this case 'more useful'? Imagine function a written by author A and function b written by author B, both loaded into an application and each of them working independently, bound together by an api spec. Now function a uses typeset IFS="X" to set the field separator to "X" via a local variable IFS. If function b now uses "read foo1 foo2 foo3" to read a line of a database the concept of dynamic scoping *BITES*. Suddenly function b no longer works as author B intended it. Lots of surprise, lots of raised eyebrows by an unwanted interaction. Static scoping is in this case much *SAFER* because IFS is reset in function b to the (global) default. The issue isn't new but the issues with dynamic scoping are one major factor why there are so few shell function libraries: It is just hard to write such a library without running afoul dynamic scoping. Olga On Sun, Nov 14, 2010 at 12:22 AM, Harald van Dijk wrote: > On 09/11/10 23:02, Eric Blake wrote: >> >> 2. User aspect: >> Is anyone aware of a script that intentionally uses the full power of >> dynamic scoping available through 'local' which would break if scoping >> switched to static? > > FWIW, some scripts use "local IFS" to reset IFS to a sane value, and have > the shell take care of restoring it afterwards. This works with ksh's > typeset, but because of the static scoping only so long as no other shell > functions get called, or those other shell functions also take the effort to > handle IFS correctly. In the scripts I have been able to find, other shell > functions do get called, but they themselves set IFS too. Still, it may be > worth keeping in mind, if only to serve as one of the few examples of when > dynamic scoping would have been slightly more useful. > -- > To unsubscribe from this list: send the line "unsubscribe dash" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- , __ , { \/`o;-Olga Kryzhanovska -;o`\/ } .'-/`-/ olga.kryzhanov...@gmail.com \-`\-'. `'-..-| / http://twitter.com/fleyta \ |-..-'` /\/\ Solaris/BSD//C/C++ programmer /\/\ `--` `--` -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: static vs. dynamic scoping
On 14/11/10 00:54, ольга крыжановская wrote: Now function a uses typeset IFS="X" to set the field separator to "X" via a local variable IFS. If function b now uses "read foo1 foo2 foo3" to read a line of a database the concept of dynamic scoping *BITES*. The way I had seen "local IFS" used is to sanitise IFS -- to reset IFS to the default value, when IFS was set to, for example, : before the function was called, and the function wants to split on whitespace. In that case, you don't want b to get IFS=:. Both forms are used, and in your form, I agree, static scoping is more useful. -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html