Why does terminal takes input line by line?

Clash Royale CLAN TAG#URR8PPP
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
|
show 1 more comment
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
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 understrace, 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
|
show 1 more comment
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
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
shell devices write
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 understrace, 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
|
show 1 more comment
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 understrace, 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
|
show 1 more comment
1 Answer
1
active
oldest
votes
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?
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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?
add a comment |
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?
add a comment |
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?
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?
edited Feb 20 at 19:16
answered Feb 20 at 19:13
JdeBPJdeBP
37.1k476177
37.1k476177
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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