12

Accidentially, I found out that wc counts differently depending on how it gets the input from bash:

$ s='hello'
$ wc -m <<<"$s"
6
$ wc -c <<<"$s"
6
$ printf '%s' "$s" | wc -m
5
$ printf '%s' "$s" | wc -c
5

Is this - IMHO confusing - behaviour documented somewhere? What does wc count here - is this an assumed newline?

4
  • 3
    You can always pipe to od -c to see exactly what you have. Jan 30, 2018 at 17:19
  • Or, better, xxd -g1.
    – Ruslan
    Jan 30, 2018 at 18:27
  • 1
    I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
    – user541686
    Jan 30, 2018 at 23:23
  • Since there were so many comments about printf, I edited my post to reflect best practice. Jan 31, 2018 at 6:01

2 Answers 2

38

The difference is caused by a newline added to the here string. See the Bash manual:

The result is supplied as a single string, with a newline appended, to the command on its standard input (or file descriptor n if n is specified).

wc is counting in the same way, but its input is different.

2
  • 7
    If should be noted that to print the (arbitrary) content of a variable without an added newline character, it should be printf %s "$var" (or print -rn -- "$var" with ksh-like shells), not printf "$var" which wouldn't work correctly for values of $var that contain % or backslash characters (or start with - with most implementations). Jan 30, 2018 at 16:54
  • Note that the original here-string implementation in the Unix port of rc did not add that newline character. Jan 30, 2018 at 16:56
26

It's a succeeding newline added by the here-string redirector:

$ s="hello"
$ hexdump -C <<<"$s"
00000000  68 65 6c 6c 6f 0a                                 |hello.|
00000006
$ printf "$s" | hexdump -C
00000000  68 65 6c 6c 6f                                    |hello|
00000005

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .