On Sat, Jan 25, 2025 at 15:56:39 +0100, Andreas Kähäri wrote:
> Je Sat, Jan 25, 2025 at 07:16:14AM +0000, Ross skribis:
> > However:
> >     foo=$(printf "%*s\n" 80 " " | tr " " "*")
> >     echo $foo
> > acts very differently; it seems to perform ls or something similar.

> This is no bug in bash but in your shell code.  There is almost never a
> reason *not* to double quote a variable substitution.  Doing so will
> prevent the shell from splitting the value of the variable on the
> characters in $IFS (space, tab, and newline, by default), but also from
> using the split-up value as filename globbing patterns, which is what
> happens in your case.
> 
> Just double quote the variable expansion:
> 
>       echo "$foo"

Andreas is correct.  Just to demonstrate, though:

hobbit:~$ x='burger*.gif'
hobbit:~$ declare -p x
declare -- x="burger*.gif"
hobbit:~$ printf '%s\n' "$x"
burger*.gif
hobbit:~$ echo "$x"
burger*.gif
hobbit:~$ echo $x
burger15.gif burger16.gif burger.gif

The error you're experiencing in your script is not due to the behavior
of printf.  It's due to the unquoted $foo expansion.

The contents of an unquoted expansion undergo two more steps: word
splitting (using the contents of $IFS) and pathname expansion.  In
this case, you're seeing the result of the pathname expansion.

Since this is typically *not* what you want, you should double-quote
your expansions to prevent it from happening.

By the way, you might be interested in this wiki page, which shows
several additional ways to generate a horizontal line of characters:
<https://mywiki.wooledge.org/BashFAQ/122>.

Reply via email to