bug-bash
[Top][All Lists]
Advanced

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

Re: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empt


From: Ilkka Virta
Subject: Re: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empty word if prepended/appended with space
Date: Sat, 21 Jul 2018 13:28:40 +0300
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

On 21.7. 07:44, Bob Proulx wrote:
Denys Vlasenko wrote:
$ f() { for i; do echo "|$i|"; done; }
$ x=x
$ e=
$ f ${x:+ ""}
^^^^^^^^^^^ prints nothing, bug?

$  ${x:+"" }
^^^^^^^^^^^ prints nothing, bug?

Insufficient quoting.  That argument should be quoted to avoid the
whitespace getting stripped.  (Is that during word splitting phase
using the IFS?  I think so.)

Try this:

   f "${x:+ ""}"
   f "${x:+"" }"

That's not the same at all. With outer quotes, the result will always be a single word. Without them, having an empty 'x' would result in no word:


Without outer quotes:

$ for cond in "" "1" ; do for value in "" "*" ; do printf "<%s>\t" "$cond" "$value" ${cond:+"$value"}; echo; done; done
<>      <>
<>      <*>
<1>     <>      <>
<1>     <*>     <*>


With outer quotes:

$ for cond in "" "1" ; do for value in "" "*" ; do printf "<%s>\t" "$cond" "$value" "${cond:+"$value"}"; echo; done; done
<>      <>      <>
<>      <*>     <>
<1>     <>      <>
<1>     <*>     <*>


I suppose that could be used to pass optional arguments to some command.

Though different shells do behave a bit differently here, and I'm not sure which behaviour is the correct one. With the values from the third line in the above test (the other three seem consistent), different shells:


No extra spaces in ${cond:+"$value"}:

$ for shell in bash dash ksh "zsh -y" ; do $shell -c 'cond=1; value=""; printf "<%s> " "$0" ${cond:+"$value"}; echo;' ; done
<bash> <>
<dash> <>
<ksh>
<zsh> <>


Extra spaces in ${cond:+ "$value" }:

$ for shell in bash dash ksh "zsh -y" ; do $shell -c 'cond=1; value=""; printf "<%s> " "$0" ${cond:+ "$value" }; echo;' ; done
<bash>
<dash> <>
<ksh> <>
<zsh> <>


Or with multiple words inside:

$ for shell in bash dash ksh "zsh -y" ; do $shell -c 'cond=1; printf "<%s> " "$0" ${cond:+"" "x" ""}; echo;' ; done
<bash> <x>
<dash> <> <x> <>
<ksh> <> <x>
<zsh> <> <x> <>


It doesn't seem like a very good idea to rely on this, arrays would of course work better.


Bash: GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
ksh:    version         sh (AT&T Research) 93u+ 2012-08-01
zsh:  zsh 5.3.1 (x86_64-debian-linux-gnu)
dash: Debian's 0.5.8-2.4


--
Ilkka Virta / itvirta@iki.fi



reply via email to

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