Why does terminal takes input line by line?

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












2















If I use:



strace echo 'a
b
c' > file


The bottom lines are:



write(1, "anbncndn", 8) = 8


but in



strace echo 'a
b
c
d' > /dev/pts/0


These lines are:



write(1, "an", 2) = 2
write(1, "bn", 2) = 2
write(1, "cn", 2) = 2
write(1, "dn", 2) = 2


In second case, why does it is writing line by line, whereas in first case it is writing together. May be because terminal is character device, but I got definition of character device as:




A character (char) device is one that can be accessed as a stream of bytes (like a file).The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.




Edit: Shell is bash.










share|improve this question
























  • I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

    – DopeGhoti
    Feb 20 at 18:44











  • This is not terminal input at all.

    – JdeBP
    Feb 20 at 18:47






  • 3





    perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

    – Thomas Dickey
    Feb 20 at 18:47






  • 2





    It's not a shell built-in. The questioner is running it under strace, notice.

    – JdeBP
    Feb 20 at 18:48











  • sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

    – Thomas Dickey
    Feb 20 at 18:49
















2















If I use:



strace echo 'a
b
c' > file


The bottom lines are:



write(1, "anbncndn", 8) = 8


but in



strace echo 'a
b
c
d' > /dev/pts/0


These lines are:



write(1, "an", 2) = 2
write(1, "bn", 2) = 2
write(1, "cn", 2) = 2
write(1, "dn", 2) = 2


In second case, why does it is writing line by line, whereas in first case it is writing together. May be because terminal is character device, but I got definition of character device as:




A character (char) device is one that can be accessed as a stream of bytes (like a file).The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.




Edit: Shell is bash.










share|improve this question
























  • I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

    – DopeGhoti
    Feb 20 at 18:44











  • This is not terminal input at all.

    – JdeBP
    Feb 20 at 18:47






  • 3





    perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

    – Thomas Dickey
    Feb 20 at 18:47






  • 2





    It's not a shell built-in. The questioner is running it under strace, notice.

    – JdeBP
    Feb 20 at 18:48











  • sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

    – Thomas Dickey
    Feb 20 at 18:49














2












2








2


1






If I use:



strace echo 'a
b
c' > file


The bottom lines are:



write(1, "anbncndn", 8) = 8


but in



strace echo 'a
b
c
d' > /dev/pts/0


These lines are:



write(1, "an", 2) = 2
write(1, "bn", 2) = 2
write(1, "cn", 2) = 2
write(1, "dn", 2) = 2


In second case, why does it is writing line by line, whereas in first case it is writing together. May be because terminal is character device, but I got definition of character device as:




A character (char) device is one that can be accessed as a stream of bytes (like a file).The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.




Edit: Shell is bash.










share|improve this question
















If I use:



strace echo 'a
b
c' > file


The bottom lines are:



write(1, "anbncndn", 8) = 8


but in



strace echo 'a
b
c
d' > /dev/pts/0


These lines are:



write(1, "an", 2) = 2
write(1, "bn", 2) = 2
write(1, "cn", 2) = 2
write(1, "dn", 2) = 2


In second case, why does it is writing line by line, whereas in first case it is writing together. May be because terminal is character device, but I got definition of character device as:




A character (char) device is one that can be accessed as a stream of bytes (like a file).The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.




Edit: Shell is bash.







shell devices write






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 21 at 4:37







Prvt_Yadv

















asked Feb 20 at 18:35









Prvt_YadvPrvt_Yadv

2,83031027




2,83031027












  • I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

    – DopeGhoti
    Feb 20 at 18:44











  • This is not terminal input at all.

    – JdeBP
    Feb 20 at 18:47






  • 3





    perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

    – Thomas Dickey
    Feb 20 at 18:47






  • 2





    It's not a shell built-in. The questioner is running it under strace, notice.

    – JdeBP
    Feb 20 at 18:48











  • sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

    – Thomas Dickey
    Feb 20 at 18:49


















  • I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

    – DopeGhoti
    Feb 20 at 18:44











  • This is not terminal input at all.

    – JdeBP
    Feb 20 at 18:47






  • 3





    perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

    – Thomas Dickey
    Feb 20 at 18:47






  • 2





    It's not a shell built-in. The questioner is running it under strace, notice.

    – JdeBP
    Feb 20 at 18:48











  • sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

    – Thomas Dickey
    Feb 20 at 18:49

















I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

– DopeGhoti
Feb 20 at 18:44





I'm mostly guessing here, but it might have to do with files being more likely to be cached or buffered?

– DopeGhoti
Feb 20 at 18:44













This is not terminal input at all.

– JdeBP
Feb 20 at 18:47





This is not terminal input at all.

– JdeBP
Feb 20 at 18:47




3




3





perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

– Thomas Dickey
Feb 20 at 18:47





perhaps stdout's set for line-buffering. Without knowing which shell, there's no source-code to confirm that.

– Thomas Dickey
Feb 20 at 18:47




2




2





It's not a shell built-in. The questioner is running it under strace, notice.

– JdeBP
Feb 20 at 18:48





It's not a shell built-in. The questioner is running it under strace, notice.

– JdeBP
Feb 20 at 18:48













sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

– Thomas Dickey
Feb 20 at 18:49






sure: but strace won't change the behavior of /bin/echo. And the shell does the redirection anyway. It's probably a duplicate. :-)

– Thomas Dickey
Feb 20 at 18:49











1 Answer
1






active

oldest

votes


















7














This is very simple.



The external echo command that you are running from strace is very probably the one from GNU coreutils. This is written in the C programming language, and uses the C runtime library functions such as putchar() and fputs() to write what it needs to write to the program's standard output.



In the C language, output to standard output can be fully buffered, line buffered, or unbuffered. The rules for what happens are actually part of the C language specification, apply across operating systems, and are written in abstract terms of whether standard output "can be determined not to refer to an interactive device".



On Unix and Linux operating systems, the concrete way that they apply is that standard output is fully buffered if the isatty() function says that the file descriptor is not a terminal. That's what "an interactive device" is in this case. Standard output is otherwise line buffered, on your operating system. The C language standard does not mandate that latter. It is what the GNU C library additionally documents that it does, on top of what the C language standard says.



So when your echo command's standard output is not a terminal but a file, the C library in the program buffers up all of the individual writes to standard output and makes one big write() call, when the buffer is full or when the program finishes. Whereas when standard output is a terminal, the C library only buffers things until a linefeed character is output, at which point it write()s the contents of the buffer.



Hence the observed system calls.



Further reading



  • https://unix.stackexchange.com/a/407472/5132

  • What prevents stdout/stderr from interleaving?

  • https://unix.stackexchange.com/a/467061/5132

  • SSH output isn't line buffered?





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',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    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%2f501930%2fwhy-does-terminal-takes-input-line-by-line%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    7














    This is very simple.



    The external echo command that you are running from strace is very probably the one from GNU coreutils. This is written in the C programming language, and uses the C runtime library functions such as putchar() and fputs() to write what it needs to write to the program's standard output.



    In the C language, output to standard output can be fully buffered, line buffered, or unbuffered. The rules for what happens are actually part of the C language specification, apply across operating systems, and are written in abstract terms of whether standard output "can be determined not to refer to an interactive device".



    On Unix and Linux operating systems, the concrete way that they apply is that standard output is fully buffered if the isatty() function says that the file descriptor is not a terminal. That's what "an interactive device" is in this case. Standard output is otherwise line buffered, on your operating system. The C language standard does not mandate that latter. It is what the GNU C library additionally documents that it does, on top of what the C language standard says.



    So when your echo command's standard output is not a terminal but a file, the C library in the program buffers up all of the individual writes to standard output and makes one big write() call, when the buffer is full or when the program finishes. Whereas when standard output is a terminal, the C library only buffers things until a linefeed character is output, at which point it write()s the contents of the buffer.



    Hence the observed system calls.



    Further reading



    • https://unix.stackexchange.com/a/407472/5132

    • What prevents stdout/stderr from interleaving?

    • https://unix.stackexchange.com/a/467061/5132

    • SSH output isn't line buffered?





    share|improve this answer





























      7














      This is very simple.



      The external echo command that you are running from strace is very probably the one from GNU coreutils. This is written in the C programming language, and uses the C runtime library functions such as putchar() and fputs() to write what it needs to write to the program's standard output.



      In the C language, output to standard output can be fully buffered, line buffered, or unbuffered. The rules for what happens are actually part of the C language specification, apply across operating systems, and are written in abstract terms of whether standard output "can be determined not to refer to an interactive device".



      On Unix and Linux operating systems, the concrete way that they apply is that standard output is fully buffered if the isatty() function says that the file descriptor is not a terminal. That's what "an interactive device" is in this case. Standard output is otherwise line buffered, on your operating system. The C language standard does not mandate that latter. It is what the GNU C library additionally documents that it does, on top of what the C language standard says.



      So when your echo command's standard output is not a terminal but a file, the C library in the program buffers up all of the individual writes to standard output and makes one big write() call, when the buffer is full or when the program finishes. Whereas when standard output is a terminal, the C library only buffers things until a linefeed character is output, at which point it write()s the contents of the buffer.



      Hence the observed system calls.



      Further reading



      • https://unix.stackexchange.com/a/407472/5132

      • What prevents stdout/stderr from interleaving?

      • https://unix.stackexchange.com/a/467061/5132

      • SSH output isn't line buffered?





      share|improve this answer



























        7












        7








        7







        This is very simple.



        The external echo command that you are running from strace is very probably the one from GNU coreutils. This is written in the C programming language, and uses the C runtime library functions such as putchar() and fputs() to write what it needs to write to the program's standard output.



        In the C language, output to standard output can be fully buffered, line buffered, or unbuffered. The rules for what happens are actually part of the C language specification, apply across operating systems, and are written in abstract terms of whether standard output "can be determined not to refer to an interactive device".



        On Unix and Linux operating systems, the concrete way that they apply is that standard output is fully buffered if the isatty() function says that the file descriptor is not a terminal. That's what "an interactive device" is in this case. Standard output is otherwise line buffered, on your operating system. The C language standard does not mandate that latter. It is what the GNU C library additionally documents that it does, on top of what the C language standard says.



        So when your echo command's standard output is not a terminal but a file, the C library in the program buffers up all of the individual writes to standard output and makes one big write() call, when the buffer is full or when the program finishes. Whereas when standard output is a terminal, the C library only buffers things until a linefeed character is output, at which point it write()s the contents of the buffer.



        Hence the observed system calls.



        Further reading



        • https://unix.stackexchange.com/a/407472/5132

        • What prevents stdout/stderr from interleaving?

        • https://unix.stackexchange.com/a/467061/5132

        • SSH output isn't line buffered?





        share|improve this answer















        This is very simple.



        The external echo command that you are running from strace is very probably the one from GNU coreutils. This is written in the C programming language, and uses the C runtime library functions such as putchar() and fputs() to write what it needs to write to the program's standard output.



        In the C language, output to standard output can be fully buffered, line buffered, or unbuffered. The rules for what happens are actually part of the C language specification, apply across operating systems, and are written in abstract terms of whether standard output "can be determined not to refer to an interactive device".



        On Unix and Linux operating systems, the concrete way that they apply is that standard output is fully buffered if the isatty() function says that the file descriptor is not a terminal. That's what "an interactive device" is in this case. Standard output is otherwise line buffered, on your operating system. The C language standard does not mandate that latter. It is what the GNU C library additionally documents that it does, on top of what the C language standard says.



        So when your echo command's standard output is not a terminal but a file, the C library in the program buffers up all of the individual writes to standard output and makes one big write() call, when the buffer is full or when the program finishes. Whereas when standard output is a terminal, the C library only buffers things until a linefeed character is output, at which point it write()s the contents of the buffer.



        Hence the observed system calls.



        Further reading



        • https://unix.stackexchange.com/a/407472/5132

        • What prevents stdout/stderr from interleaving?

        • https://unix.stackexchange.com/a/467061/5132

        • SSH output isn't line buffered?






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 20 at 19:16

























        answered Feb 20 at 19:13









        JdeBPJdeBP

        37.1k476177




        37.1k476177



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Unix & Linux Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f501930%2fwhy-does-terminal-takes-input-line-by-line%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown






            Popular posts from this blog

            Peggy Mitchell

            Palaiologos

            The Forum (Inglewood, California)