Martijn Dekker | 3 Jun 13:29 2015

[BUG] ${#var} returns length in bytes, not characters

> ${#parameter}
> String Length. The length in characters of the value of parameter
> shall be substituted. [...]

dash does not expand the length in characters; it expands the length in
bytes instead. That is invalid for locales that include multi-byte
characters, such as the now ubiquitous UTF-8 set.

Test case:

$ locale
$ word='bètatest'	# length: 8
$ echo ${#word}

Expected output: 8
Got output: 9

(bash, ksh93, mksh, and zsh all do this correctly.)

(Continue reading)

Felix Dietrich | 2 Jun 22:55 2015

[MAN] Fix description of getopts when last argument reached

When I read the getopts description in the man-page I got stumped by the
following part:

    getopts optstring var


        If there are no remaining arguments, getopts will set var to
        special option, “--”, otherwise, it will set var to “?”


After I was unable to get getopts to store "--" in var, I asked for help
on [1] where it was pointed out to me that actually the
POSIX description of getopts [2] does not include a special option "--";
dash's behaviour of setting var to "?" after the last argument is
correct and that this is most likely an error in the documention.

In case this is not an error: Under what circumstances will var be set
to "--"?  Could you provide an example?


 src/dash.1 | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/dash.1 b/src/dash.1
index 693c970..832eae7 100644
(Continue reading)

Martijn Dekker | 28 May 20:54 2015

getopts doesn't properly update OPTIND when called from function

I'm writing a shell function that extends the functionality of the
'getopts' builtin. For that to work, it is necessary to call the
'getopts' builtin from the shell function.

The POSIX standard specifies that OPTIND and OPTARG are global
variables, even though the positional parameters are local to the
function.[*] This makes it possible to call 'getopts' from a function by
simply passing the global positional parameters along by adding "$ <at> ".

My problem is that dash does not properly update the global OPTIND
variable when getopts is called from a function, which defeats my
function on dash. It updates the global OPTIND for the first option but
not for subsequent options, so OPTIND gets stuck on 3. (It does
accurately update the global OPTARG variable, though.)

I made a little test program that demonstrates this; see below the
footnote. It succeeds on bash, ksh93, pdksh, mksh, and yash, but not
(d)ash or zsh[*2].

The output of my test script seems consistent with the hypothesis that
OPTIND is reinitialized to 1 whenever a function is called. It should
only be initialized when the shell is initialized.

I suspect this is an old bug as other versions of ash, including Busybox
ash and NetBSD's /bin/sh, share it.


- Martijn

(Continue reading)

Fredrik Fornwall | 18 May 01:15 2015

[PATCH] Set LC_ALL instead LC_COLLATE in mkbuiltins

In mkbuiltins LC_COLLATE is set, but since "The value of the LC_ALL
environment variable has precedence over any of the other environment
variables starting with LC_"
(, this
has no effect when LC_ALL is set.

This breaks when having e.g. LC_ALL=en_US.UTF-8 during make, which
causes the test case
    dash -c :
to fail, probably due to broken ordering in builtins.c. The patch
corrects that by setting LC_ALL instead of LC_COLLATE.


diff -u -r ../dash-0.5.8/src/mkbuiltins ./src/mkbuiltins
--- ../dash-0.5.8/src/mkbuiltins 2014-09-28 04:19:32.000000000 -0400
+++ ./src/mkbuiltins 2015-05-17 19:08:00.076452891 -0400
 <at>  <at>  -78,7 +78,7  <at>  <at> 
  if ($i ~ /^-/)
  line = $(++i) "\t" line
  print line
- }}' $temp | LC_COLLATE=C sort -k 1,1 | tee $temp2 | awk '{
+ }}' $temp | LC_ALL=C sort -k 1,1 | tee $temp2 | awk '{
  opt = ""
  if (NF > 2) {
  opt = substr($2, 2)
 <at>  <at>  -97,7 +97,7  <at>  <at> 

(Continue reading)

Alex Waite | 25 Mar 14:51 2015

Pattern matching faster than math


This isn't a problem per-se, but I'm curious if anyone can shed some 
light on why this is so.

I have a script where I'm checking if the contents of a variable is an 
integer. An easy/hacky way to do this is

[ "$var" -ge 0 2> /dev/null ] || echo "is not int"

But this caused posh to segfault, so I went for a pattern matching 
solution instead:

[ -z "${var##*[!0-9]*}" ] && echo "is not int"

This works well, and it makes posh happy. But what's surprising to me is 
that it's faster.

I have more of a write-up in a commit message:

Any thoughts or insight? Am I making some faulty assumption here?

Thanks for your time.


To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majordomo <at>
(Continue reading)

jacinta jacinta | 22 Mar 15:00 2015



I, am miss jacinta,interested in you, and wish to have you as my friend,
please could you get back to me for more details of my self and all maybe
necessary in this relationship,including my picture,if this interest you
get back to address(jacinta.jac <at>
yours jacinta

To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majordomo <at>
More majordomo info at

Damian Wrobel | 20 Jan 18:01 2015

Re: Inconsistent behaviour between 'jobs' and 'echo "$(jobs)"'

On 01/20/2015 09:44 AM, Seb wrote:
> On Mon, Jan 19, 2015 at 07:01:53PM +0100, Damian Wrobel wrote:
> Hello,
>> I'm observing an inconsistent behaviour between:
>>   jobs
>> and
>>   echo "$(jobs)"
> It's because the command is ran in a sub-shell, where there is indeed no
> running job.
> Bash has a special mechanism to handle this and get the current shell
> context returned, that's why you may feel some inconsistency here (like
> I myself did :)

There is an application usage [1] where this case is specifically mentioned with 
a suggestion that: "For this reason, jobs is generally implemented as a shell 
regular built-in."

I basically planned to use the following construction to kill all running jobs:

$ kill $(jobs -p)

Now it looks that even the following doesn't work in a dash:

$ jobs -p | xargs kill

I would prefer not to code something like the following:
(Continue reading)

Damian Wrobel | 19 Jan 19:01 2015

Inconsistent behaviour between 'jobs' and 'echo "$(jobs)"'


I'm observing an inconsistent behaviour between:
  echo "$(jobs)"

Here is the short example:

$ rpm -qv dash
$ /bin/dash
$ sleep 1000 &
$ jobs
[1] + Running                    sleep 1000
$ echo "$(jobs)"

$ echo `jobs`

$ jobs 2>/dev/null
[1] + Running                    sleep 1000


Have a nice day,
To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majordomo <at>
More majordomo info at
(Continue reading)

Pádraig Brady | 15 Jan 18:40 2015

incorrect handling of quoted escapes

bash, ksh, zsh all support $'\n\x0a\012'

The POSIX discussion is at:

It would be great if dash supported it too.

I tested dash 0.5.8

To unsubscribe from this list: send the line "unsubscribe dash" in
the body of a message to majordomo <at>
More majordomo info at

Harald van Dijk | 9 Jan 18:17 2015

[PATCH] Fix variable assignments in function invocations

Hello all,

A long-standing problem with dash has been how it deals with variable 
assignments in function invocations, and several packages are affected 
by it, two I've come across recently being autogen and pkg-config (only 
their test suites, luckily).

A short test script:

   f() {
     echo inside f, VAR is $VAR
     sh -c 'echo inside sh called from f, VAR is $VAR'

   VAR=value f
   echo after returning from f, VAR is $VAR

Assuming VAR was not already set, this should print (and does with bash):

   inside f, VAR is value
   inside sh called from f, VAR is value
   after returning from f, VAR is

With dash, this actually prints:

   inside f, VAR is value
   inside sh called from f, VAR is
   after returning from f, VAR is value

The first problem with that is that VAR does not get exported, the 
(Continue reading)

Herbert Xu | 31 Dec 21:56 2014

[EXPAND] Fixed "$ <at> " expansion when EXP_FULL is false

On Wed, Dec 31, 2014 at 07:03:30PM +0100, Juergen Daubert wrote:
> Hi,
> today I tried to use dash from git as /bin/sh and run in a lot of
> problem I don't see with stable version 0.5.8. 
> After some investigations I narrowed it down to commit 
> 3c06acdac0b1ba0e0acdda513a57ee6e31385dce 
> [EXPAND] Split unquoted $ <at> /$* correctly when IFS is set but empty
> and related following to expand.c
> It seems that the changes to dash triggers, among others, some problem 
> with libtool.
> As examples I've attached build logs for libpixman and kbd, there are a
> lot other builds that failed as well. If you need more, please let me 
> know.

Thanks for the report.  This patch should fix the problem.

-- >8 --
The commit 3c06acdac0b1ba0e0acdda513a57ee6e31385dce ([EXPAND]
Split unquoted $ <at> /$* correctly when IFS is set but empty) broke
the case where $ <at>  is in quotes and EXP_FULL is false.

In that case we should still emit IFS as field splitting is not

(Continue reading)