Why does wc <<<“$string” show a one-byte-longer length than printf “$string” | wc?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
11
down vote

favorite
1












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?







share|improve this question


















  • 3




    You can always pipe to od -c to see exactly what you have.
    – Thorbjørn Ravn Andersen
    Jan 30 at 17:19










  • Or, better, xxd -g1.
    – Ruslan
    Jan 30 at 18:27






  • 1




    I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
    – Mehrdad
    Jan 30 at 23:23










  • Since there were so many comments about printf, I edited my post to reflect best practice.
    – rexkogitans
    Jan 31 at 6:01















up vote
11
down vote

favorite
1












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?







share|improve this question


















  • 3




    You can always pipe to od -c to see exactly what you have.
    – Thorbjørn Ravn Andersen
    Jan 30 at 17:19










  • Or, better, xxd -g1.
    – Ruslan
    Jan 30 at 18:27






  • 1




    I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
    – Mehrdad
    Jan 30 at 23:23










  • Since there were so many comments about printf, I edited my post to reflect best practice.
    – rexkogitans
    Jan 31 at 6:01













up vote
11
down vote

favorite
1









up vote
11
down vote

favorite
1






1





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?







share|improve this question














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?









share|improve this question













share|improve this question




share|improve this question








edited Jan 31 at 5:59

























asked Jan 30 at 12:26









rexkogitans

308110




308110







  • 3




    You can always pipe to od -c to see exactly what you have.
    – Thorbjørn Ravn Andersen
    Jan 30 at 17:19










  • Or, better, xxd -g1.
    – Ruslan
    Jan 30 at 18:27






  • 1




    I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
    – Mehrdad
    Jan 30 at 23:23










  • Since there were so many comments about printf, I edited my post to reflect best practice.
    – rexkogitans
    Jan 31 at 6:01













  • 3




    You can always pipe to od -c to see exactly what you have.
    – Thorbjørn Ravn Andersen
    Jan 30 at 17:19










  • Or, better, xxd -g1.
    – Ruslan
    Jan 30 at 18:27






  • 1




    I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
    – Mehrdad
    Jan 30 at 23:23










  • Since there were so many comments about printf, I edited my post to reflect best practice.
    – rexkogitans
    Jan 31 at 6:01








3




3




You can always pipe to od -c to see exactly what you have.
– Thorbjørn Ravn Andersen
Jan 30 at 17:19




You can always pipe to od -c to see exactly what you have.
– Thorbjørn Ravn Andersen
Jan 30 at 17:19












Or, better, xxd -g1.
– Ruslan
Jan 30 at 18:27




Or, better, xxd -g1.
– Ruslan
Jan 30 at 18:27




1




1




I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
– Mehrdad
Jan 30 at 23:23




I hope printf "$s" isn't your actual script... hopefully you meant printf "%s" "$s"
– Mehrdad
Jan 30 at 23:23












Since there were so many comments about printf, I edited my post to reflect best practice.
– rexkogitans
Jan 31 at 6:01





Since there were so many comments about printf, I edited my post to reflect best practice.
– rexkogitans
Jan 31 at 6:01











2 Answers
2






active

oldest

votes

















up vote
38
down vote



accepted










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.






share|improve this answer


















  • 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).
    – Stéphane Chazelas
    Jan 30 at 16:54











  • Note that the original here-string implementation in the Unix port of rc did not add that newline character.
    – Stéphane Chazelas
    Jan 30 at 16:56

















up vote
26
down vote













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





share|improve this answer






















    Your Answer







    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "106"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: false,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );








     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f420655%2fwhy-does-wc-string-show-a-one-byte-longer-length-than-printf-string-w%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    38
    down vote



    accepted










    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.






    share|improve this answer


















    • 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).
      – Stéphane Chazelas
      Jan 30 at 16:54











    • Note that the original here-string implementation in the Unix port of rc did not add that newline character.
      – Stéphane Chazelas
      Jan 30 at 16:56














    up vote
    38
    down vote



    accepted










    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.






    share|improve this answer


















    • 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).
      – Stéphane Chazelas
      Jan 30 at 16:54











    • Note that the original here-string implementation in the Unix port of rc did not add that newline character.
      – Stéphane Chazelas
      Jan 30 at 16:56












    up vote
    38
    down vote



    accepted







    up vote
    38
    down vote



    accepted






    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.






    share|improve this answer














    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.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 30 at 16:36

























    answered Jan 30 at 12:30









    Stephen Kitt

    142k22308370




    142k22308370







    • 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).
      – Stéphane Chazelas
      Jan 30 at 16:54











    • Note that the original here-string implementation in the Unix port of rc did not add that newline character.
      – Stéphane Chazelas
      Jan 30 at 16:56












    • 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).
      – Stéphane Chazelas
      Jan 30 at 16:54











    • Note that the original here-string implementation in the Unix port of rc did not add that newline character.
      – Stéphane Chazelas
      Jan 30 at 16:56







    7




    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).
    – Stéphane Chazelas
    Jan 30 at 16:54





    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).
    – Stéphane Chazelas
    Jan 30 at 16:54













    Note that the original here-string implementation in the Unix port of rc did not add that newline character.
    – Stéphane Chazelas
    Jan 30 at 16:56




    Note that the original here-string implementation in the Unix port of rc did not add that newline character.
    – Stéphane Chazelas
    Jan 30 at 16:56












    up vote
    26
    down vote













    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





    share|improve this answer


























      up vote
      26
      down vote













      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





      share|improve this answer
























        up vote
        26
        down vote










        up vote
        26
        down vote









        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





        share|improve this answer














        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






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 30 at 12:41









        ilkkachu

        49.8k674137




        49.8k674137










        answered Jan 30 at 12:31









        Murphy

        1,7471517




        1,7471517






















             

            draft saved


            draft discarded


























             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f420655%2fwhy-does-wc-string-show-a-one-byte-longer-length-than-printf-string-w%23new-answer', 'question_page');

            );

            Post as a guest













































































            Popular posts from this blog

            How to check contact read email or not when send email to Individual?

            Christian Cage

            How to properly install USB display driver for Fresco Logic FL2000DX on Ubuntu?