printf %n
Bash’s printf builtin implements C’s %n:
printf '%nthen we went%n for a ride\n%n' o m g
echo $o $m $g # 0 12 24Instead of consuming an argument to print, %n writes the count of bytes emitted so far into the shell variable named by the corresponding argument. One format string yields the rendered output and measured byte offsets into it: o gets 0, m gets 12 (the end of “then we went”), g gets 24 (everything, newline included).
In C, %n writes through a pointer, which made it the classic format-string attack primitive—the one directive that turns “print” into “write to memory.” In bash the pointer-writing half is gone: the target is a shell variable, named by an ordinary argument, created if it doesn’t exist. The useful half survives—measuring layout while producing it.
That’s the actual use under a narrow contract: byte-offset math where each emitted byte occupies one display column. Print a label, capture the count, and compute padding or alignment instead of re-deriving it with ${#...} arithmetic over every piece of the format. Under the same contract, the number can feed cursor-movement escapes.
Gotchas, in order of likelihood. This is Bash’s builtin interface; another shell or an external printf has its own format rules. Do not assume that the same spelling sets a variable there. The count is bytes, not display columns: multibyte UTF-8, tabs and other control characters, and terminal escape sequences all break the equivalence. Only printable, single-column ASCII makes the byte count a column count.