Draw a Full-Width Horizontal Rule in a Bash Terminal
Draw a rule as wide as the terminal with printf and a star width plus tr, or build it with a parameter expansion. COLUMNS is only set in an interactive Bash.
A script prints sections and you want a divider line that spans the terminal, or any other fixed width.
cols=${COLUMNS:-$(tput cols 2>/dev/null || echo 40)}
printf '%*s\n' "$cols" '' | tr ' ' '-'
printf -v line '%*s' 20 ''
echo "${line// /=}"
printf '%*s%s\n' 5 '' 'indented by five'----------------------------------------
====================
indented by fiveprintf '%*s' N '' prints N spaces, because the star takes its width from the argument list, and tr ' ' '-' turns each space into a dash. The second form keeps the spaces in a variable and replaces them with ${line// /=}, which needs no external command. COLUMNS holds the terminal width in an interactive shell, and tput cols asks the terminal otherwise. The format string is described under the printf builtin.
COLUMNS is not exported and is unset in scripts, and tput cols fails without a terminal, so the example falls back to 40 columns, as it did in this run. A rule made of multibyte characters needs the parameter-expansion form, because GNU tr works on bytes.