[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-bash] ${var:?message} customization

From: Dan Douglas
Subject: Re: [Help-bash] ${var:?message} customization
Date: Fri, 15 May 2015 09:20:12 -0500

On Fri, May 15, 2015 at 5:55 AM, Stephane Chazelas
<address@hidden> wrote:
> That assumes $IFS doesn't contain f, a, l, s, e or :.

True it's good to look out for unexpected IFS. Often times I want
splitting with ${var+word} so it's easy to miss.

> does look more convoluted to me than
> [ -n "${var+defined}" ]
> or
> [ "${var+defined}" = defined ]
> or
> [ "${var+defined}" ]
> It takes me longer to decipher.

Most people disagree with me, but that hurt my brain when I first saw
it. I suppose it's the same sort of people that find: `if
(boolThing()) { return true; } else { return false; }` to be more
intuitive than `return boolThing();`.

>> Note that there's no shell that I know nowadays where "[" is not
>> builtin so I don't think the performance aspect holds.

I'm arguing over some pretty negligible differences. It's mainly [
being a simple command. It would take some special-case optimization
to avoid having to test var then pass in the argument by value even
for a builtin. Since simple command evaluation tends to be one of the
slower processes, evaluating a null command saves time in a tight loop
in a few shells. It's also why [[ ${var+_} ]] beats the POSIX
solutions even if it means testing an extra value. : / false also just
have simpler implementations than [.

The same applies to testing empty strings. [[ $var ]] should be simple
in comparison to [ "$var" ], and the `${var:+}` expansion should start
to look appealing for a sufficiently long string. If there were a
magic optimization then you would expect these to differ quite
substantially. (Looks like ksh might actually do some magic here. Bash
is about like what I'd expect)

 $ bash -c 'x=$(ksh -c "printf {0..10000000}"); echo "${#x}";
time [ "$x" ]; eval time [ "$x" ]'

real    0m0.120s
user    0m0.119s
sys     0m0.002s

real    0m0.326s
user    0m0.320s
sys     0m0.006s

 $ mksh -c 'x=$(ksh -c "printf {0..10000000}"); echo "${#x}";
time [ "$x" ]; eval time [ "$x" ]'
    0m0.04s real     0m0.03s user     0m0.00s system
    0m0.05s real     0m0.05s user     0m0.00s system

 $ ksh -c 'x=$(ksh -c "printf {0..10000000}"); echo "${#x}"; time
[ "$x" ]; eval time [ "$x" ]'

real    0m0.12s
user    0m0.12s
sys     0m0.00s

real    0m0.00s
user    0m0.00s
sys     0m0.00s

reply via email to

[Prev in Thread] Current Thread [Next in Thread]