How bash builtins works with pipeline

The name of the pictureThe name of the pictureThe name of the pictureClash 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?










share|improve this question





















  • 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















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?










share|improve this question





















  • 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













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?










share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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

















  • 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











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





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%2f471221%2fhow-bash-builtins-works-with-pipeline%23new-answer', 'question_page');

    );

    Post as a guest






























    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





    share|improve this answer
























      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





      share|improve this answer






















        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





        share|improve this answer












        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






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Sep 25 at 5:31









        RalfFriedl

        4,2481725




        4,2481725



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            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













































































            Popular posts from this blog

            Peggy Mitchell

            The Forum (Inglewood, California)

            Palaiologos