11

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.