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?

            Displaying single band from multi-band raster using QGIS

            How many registers does an x86_64 CPU actually have?