How bash builtins works with pipeline

Clash Royale CLAN TAG#URR8PPP
up vote
0
down vote
favorite
Bash builtins defines as:
The shell executes the command directly, without invoking another program.
And a pipeline like foo | bar works roughly like: bar waits inputs from foo, and foo exits first, and then bar exit.
In bash a pipeline like this works as expected:
$ history | grep curl
But how can grep manage to know history is done its work, and exits itself? Since history, which is a builtin, was not spawning new process. Does history generate an EOF signal or something?
bash shell-builtin
add a comment |Â
up vote
0
down vote
favorite
Bash builtins defines as:
The shell executes the command directly, without invoking another program.
And a pipeline like foo | bar works roughly like: bar waits inputs from foo, and foo exits first, and then bar exit.
In bash a pipeline like this works as expected:
$ history | grep curl
But how can grep manage to know history is done its work, and exits itself? Since history, which is a builtin, was not spawning new process. Does history generate an EOF signal or something?
bash shell-builtin
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,history | ...is spawning a new process, even if it's just another instance of bash.
â mosvy
Sep 25 at 4:17
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Bash builtins defines as:
The shell executes the command directly, without invoking another program.
And a pipeline like foo | bar works roughly like: bar waits inputs from foo, and foo exits first, and then bar exit.
In bash a pipeline like this works as expected:
$ history | grep curl
But how can grep manage to know history is done its work, and exits itself? Since history, which is a builtin, was not spawning new process. Does history generate an EOF signal or something?
bash shell-builtin
Bash builtins defines as:
The shell executes the command directly, without invoking another program.
And a pipeline like foo | bar works roughly like: bar waits inputs from foo, and foo exits first, and then bar exit.
In bash a pipeline like this works as expected:
$ history | grep curl
But how can grep manage to know history is done its work, and exits itself? Since history, which is a builtin, was not spawning new process. Does history generate an EOF signal or something?
bash shell-builtin
bash shell-builtin
asked Sep 25 at 3:47
mitnk
261311
261311
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,history | ...is spawning a new process, even if it's just another instance of bash.
â mosvy
Sep 25 at 4:17
add a comment |Â
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,history | ...is spawning a new process, even if it's just another instance of bash.
â mosvy
Sep 25 at 4:17
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,
history | ... is spawning a new process, even if it's just another instance of bash.â mosvy
Sep 25 at 4:17
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,
history | ... is spawning a new process, even if it's just another instance of bash.â mosvy
Sep 25 at 4:17
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
When the manual says "without invoking another program", it means that the shell doesn't use execve to execute another programs. When a command uses redirection, the simple implementation is to fork another process and do the redirection for that process only, leaving the file descriptors of the parent shell unmodified. This is also what bash does with this command, as can be verified with strace.
It is possible to do some trickery and avoid the forks for internal commands, but it seems they are not used in this case.
The second program can't detect that the first program exits, it can only detect that the output side of the pipe has been closed (which may happen because the program exited, or because of a regular close). The reading side of the pipe will receive an EOF.
It is common but not necessary for the first program in a pipe to exit first. Consider:
sleep 10 | echo done
If the second program of the pipe exits before the first and the first tries to write to the pipe it will get the signal SIGPIPE, which will terminate the process, unless it is caught.
(sleep 10; echo test ) | echo done
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
When the manual says "without invoking another program", it means that the shell doesn't use execve to execute another programs. When a command uses redirection, the simple implementation is to fork another process and do the redirection for that process only, leaving the file descriptors of the parent shell unmodified. This is also what bash does with this command, as can be verified with strace.
It is possible to do some trickery and avoid the forks for internal commands, but it seems they are not used in this case.
The second program can't detect that the first program exits, it can only detect that the output side of the pipe has been closed (which may happen because the program exited, or because of a regular close). The reading side of the pipe will receive an EOF.
It is common but not necessary for the first program in a pipe to exit first. Consider:
sleep 10 | echo done
If the second program of the pipe exits before the first and the first tries to write to the pipe it will get the signal SIGPIPE, which will terminate the process, unless it is caught.
(sleep 10; echo test ) | echo done
add a comment |Â
up vote
1
down vote
accepted
When the manual says "without invoking another program", it means that the shell doesn't use execve to execute another programs. When a command uses redirection, the simple implementation is to fork another process and do the redirection for that process only, leaving the file descriptors of the parent shell unmodified. This is also what bash does with this command, as can be verified with strace.
It is possible to do some trickery and avoid the forks for internal commands, but it seems they are not used in this case.
The second program can't detect that the first program exits, it can only detect that the output side of the pipe has been closed (which may happen because the program exited, or because of a regular close). The reading side of the pipe will receive an EOF.
It is common but not necessary for the first program in a pipe to exit first. Consider:
sleep 10 | echo done
If the second program of the pipe exits before the first and the first tries to write to the pipe it will get the signal SIGPIPE, which will terminate the process, unless it is caught.
(sleep 10; echo test ) | echo done
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
When the manual says "without invoking another program", it means that the shell doesn't use execve to execute another programs. When a command uses redirection, the simple implementation is to fork another process and do the redirection for that process only, leaving the file descriptors of the parent shell unmodified. This is also what bash does with this command, as can be verified with strace.
It is possible to do some trickery and avoid the forks for internal commands, but it seems they are not used in this case.
The second program can't detect that the first program exits, it can only detect that the output side of the pipe has been closed (which may happen because the program exited, or because of a regular close). The reading side of the pipe will receive an EOF.
It is common but not necessary for the first program in a pipe to exit first. Consider:
sleep 10 | echo done
If the second program of the pipe exits before the first and the first tries to write to the pipe it will get the signal SIGPIPE, which will terminate the process, unless it is caught.
(sleep 10; echo test ) | echo done
When the manual says "without invoking another program", it means that the shell doesn't use execve to execute another programs. When a command uses redirection, the simple implementation is to fork another process and do the redirection for that process only, leaving the file descriptors of the parent shell unmodified. This is also what bash does with this command, as can be verified with strace.
It is possible to do some trickery and avoid the forks for internal commands, but it seems they are not used in this case.
The second program can't detect that the first program exits, it can only detect that the output side of the pipe has been closed (which may happen because the program exited, or because of a regular close). The reading side of the pipe will receive an EOF.
It is common but not necessary for the first program in a pipe to exit first. Consider:
sleep 10 | echo done
If the second program of the pipe exits before the first and the first tries to write to the pipe it will get the signal SIGPIPE, which will terminate the process, unless it is caught.
(sleep 10; echo test ) | echo done
answered Sep 25 at 5:31
RalfFriedl
4,2481725
4,2481725
add a comment |Â
add a comment |Â
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
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f471221%2fhow-bash-builtins-works-with-pipeline%23new-answer', 'question_page');
);
Post as a guest
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
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
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
the shell runs each command from a pipeline in a separate process, no matter if it's an external command or a built-in. So yes,
history | ...is spawning a new process, even if it's just another instance of bash.â mosvy
Sep 25 at 4:17