Quoted closing brace in variable default expansion

2010-11-13 Thread Harald van Dijk

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

2010-11-13 Thread Jonathan Nieder
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

2010-11-13 Thread Harald van Dijk

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

2010-11-13 Thread Jilles Tjoelker
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"

2010-11-13 Thread Jilles Tjoelker
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

2010-11-13 Thread Harald van Dijk

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

2010-11-13 Thread ольга крыжановская
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

2010-11-13 Thread Harald van Dijk

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