Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #14376 > unrolled thread

Re: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empty word if prepended/appended with space

Started byIlkka Virta <itvirta@iki.fi>
First post2018-07-21 13:28 +0300
Last post2018-07-21 13:28 +0300
Articles 1 — 1 participant

Back to article view | Back to gnu.bash.bug

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empty word if prepended/appended with space Ilkka Virta <itvirta@iki.fi> - 2018-07-21 13:28 +0300

#14376 — Re: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empty word if prepended/appended with space

FromIlkka Virta <itvirta@iki.fi>
Date2018-07-21 13:28 +0300
SubjectRe: Empty ""s in ARG in ${x:+ARG} expand to no words instead of the empty word if prepended/appended with space
Message-ID<mailman.3956.1532168951.1292.bug-bash@gnu.org>
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

[toc] | [standalone]


Back to top | Article view | gnu.bash.bug


csiph-web