%c takes a string and prints the first character of that string. If the string is
65, as in your example, then it would print
This is specified by the POSIX specification for the
The argument to the
c conversion specifier can be a string containing zero or more bytes. If it contains one or more bytes, the first byte shall be written and any additional bytes shall be ignored. If the argument is an empty string, it is unspecified whether nothing is written or a null byte is written.
The argument operands shall be treated as strings if the corresponding conversion specifier is
This means that the argument of the
%c format is interpreted different in C (where a small positive integer will be converted to a
char) and in the shell (where the same integer remains a string containing several digit characters). The format itself does the same thing though; it outputs a single byte as a character.
$ printf '%d %b\n' 65 '\0101'
101 is 65 in octal. And
%b is specified in POSIX as
An additional conversion specifier character,
b, shall be supported as follows. The argument shall be taken to be a string that can contain
<backslash>-escape sequences. [...]
ddd is a zero, one, two, or three-digit octal number that shall be converted to a byte with the numeric value specified by the octal number.
It's an additional conversion specifier, since it's not available in standard C. It is however needed in the shell as we don't have typed variables (in the POSIX shell).
$ printf '%d %b\n' 65 "$( printf '\\0%o\n' 65 )"
Here we first convert 65 to an octal number in the
\0ddd format using
%o, before using the result of that in another
printf that uses