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>.