File manager instances not showing among running processes

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

0

I’ve over 10 windows of a file manager (Thunar, on Xubuntu Core 18.04) open, but ps aux|grep thunar shows nothing (except for the grepped string). Why? ps -e doesn’t not show anything either.

EDIT: I suspect a reason may be that the location (in the address bar) in those windows is an ejected external media. Another one may be that I didn’t open the windows (they opened automatically when I plugged in the media), so the processes might not be mine. However, this still doesn’t explain thunar not showing up. The problem persist after logout

share|improve this question

    0

    I’ve over 10 windows of a file manager (Thunar, on Xubuntu Core 18.04) open, but ps aux|grep thunar shows nothing (except for the grepped string). Why? ps -e doesn’t not show anything either.

    EDIT: I suspect a reason may be that the location (in the address bar) in those windows is an ejected external media. Another one may be that I didn’t open the windows (they opened automatically when I plugged in the media), so the processes might not be mine. However, this still doesn’t explain thunar not showing up. The problem persist after logout

    share|improve this question

      0

      0

      0

      I’ve over 10 windows of a file manager (Thunar, on Xubuntu Core 18.04) open, but ps aux|grep thunar shows nothing (except for the grepped string). Why? ps -e doesn’t not show anything either.

      EDIT: I suspect a reason may be that the location (in the address bar) in those windows is an ejected external media. Another one may be that I didn’t open the windows (they opened automatically when I plugged in the media), so the processes might not be mine. However, this still doesn’t explain thunar not showing up. The problem persist after logout

      share|improve this question

      I’ve over 10 windows of a file manager (Thunar, on Xubuntu Core 18.04) open, but ps aux|grep thunar shows nothing (except for the grepped string). Why? ps -e doesn’t not show anything either.

      EDIT: I suspect a reason may be that the location (in the address bar) in those windows is an ejected external media. Another one may be that I didn’t open the windows (they opened automatically when I plugged in the media), so the processes might not be mine. However, this still doesn’t explain thunar not showing up. The problem persist after logout

      ps process-management thunar

      share|improve this question

      share|improve this question

      share|improve this question

      share|improve this question

      edited Jan 26 at 7:09

      Rui F Ribeiro

      40.1k1479136

      40.1k1479136

      asked Jan 25 at 0:58

      jaamjaam

      1358

      1358

          1 Answer
          1

          active

          oldest

          votes

          2

          Thunar used to use a capital ‘T’ in its name. The package for 18.04 has both Thunar and thunar in it. Try changing your grep command to ignore case:

          ps aux | grep -i thunar

          share|improve this answer

          • You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

            – jaam
            Jan 25 at 12:07

          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%2f496584%2ffile-manager-instances-not-showing-among-running-processes%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

          2

          Thunar used to use a capital ‘T’ in its name. The package for 18.04 has both Thunar and thunar in it. Try changing your grep command to ignore case:

          ps aux | grep -i thunar

          share|improve this answer

          • You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

            – jaam
            Jan 25 at 12:07

          2

          Thunar used to use a capital ‘T’ in its name. The package for 18.04 has both Thunar and thunar in it. Try changing your grep command to ignore case:

          ps aux | grep -i thunar

          share|improve this answer

          • You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

            – jaam
            Jan 25 at 12:07

          2

          2

          2

          Thunar used to use a capital ‘T’ in its name. The package for 18.04 has both Thunar and thunar in it. Try changing your grep command to ignore case:

          ps aux | grep -i thunar

          share|improve this answer

          Thunar used to use a capital ‘T’ in its name. The package for 18.04 has both Thunar and thunar in it. Try changing your grep command to ignore case:

          ps aux | grep -i thunar

          share|improve this answer

          share|improve this answer

          share|improve this answer

          answered Jan 25 at 2:40

          stimutstimut

          362

          362

          • You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

            – jaam
            Jan 25 at 12:07

          • You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

            – jaam
            Jan 25 at 12:07

          You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

          – jaam
          Jan 25 at 12:07

          You were right. I find it very confusing (and a bug: if thunar maps to [Tt]hunar, it should do so system-wide)

          – jaam
          Jan 25 at 12:07

          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%2f496584%2ffile-manager-instances-not-showing-among-running-processes%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

          How to avoid zombie process while working with named pipe?

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

          0

          We normally do the writing job to a FIFO file in background using a control operator &. Something like below.

          if [ ! -p "/tmp/mysqld.init" ]; then
              mkfifo /tmp/mysqld.init
          fi
          
          echo "something" > /tmp/mysqld.init &
          
          exec mysqld --init-file=/tmp/mysqld.init
          

          But when the fifo file is readout the echo process get a zombie process. How can it be avoided ?

          Note This script is a docker entrypoint script and I don’t have a proper zombie handler. Mysqld always takes the pid 1. Something like below.

            PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
              1     0 mysql    S     383m  19%   0   0% mysqld --init-file=/tmp/mysqld.init
             40     0 root     R     1532   0%   1   0% top
              7     1 root     Z        0   0%   0   0% [entrypoint.sh]
          

          Probably I can use tini an init system for docker but without it how can it be achieved ? Double fork ?

          share|improve this question

          • You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

            – ctrl-alt-delor
            Jan 21 at 22:48

          0

          We normally do the writing job to a FIFO file in background using a control operator &. Something like below.

          if [ ! -p "/tmp/mysqld.init" ]; then
              mkfifo /tmp/mysqld.init
          fi
          
          echo "something" > /tmp/mysqld.init &
          
          exec mysqld --init-file=/tmp/mysqld.init
          

          But when the fifo file is readout the echo process get a zombie process. How can it be avoided ?

          Note This script is a docker entrypoint script and I don’t have a proper zombie handler. Mysqld always takes the pid 1. Something like below.

            PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
              1     0 mysql    S     383m  19%   0   0% mysqld --init-file=/tmp/mysqld.init
             40     0 root     R     1532   0%   1   0% top
              7     1 root     Z        0   0%   0   0% [entrypoint.sh]
          

          Probably I can use tini an init system for docker but without it how can it be achieved ? Double fork ?

          share|improve this question

          • You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

            – ctrl-alt-delor
            Jan 21 at 22:48

          0

          0

          0

          We normally do the writing job to a FIFO file in background using a control operator &. Something like below.

          if [ ! -p "/tmp/mysqld.init" ]; then
              mkfifo /tmp/mysqld.init
          fi
          
          echo "something" > /tmp/mysqld.init &
          
          exec mysqld --init-file=/tmp/mysqld.init
          

          But when the fifo file is readout the echo process get a zombie process. How can it be avoided ?

          Note This script is a docker entrypoint script and I don’t have a proper zombie handler. Mysqld always takes the pid 1. Something like below.

            PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
              1     0 mysql    S     383m  19%   0   0% mysqld --init-file=/tmp/mysqld.init
             40     0 root     R     1532   0%   1   0% top
              7     1 root     Z        0   0%   0   0% [entrypoint.sh]
          

          Probably I can use tini an init system for docker but without it how can it be achieved ? Double fork ?

          share|improve this question

          We normally do the writing job to a FIFO file in background using a control operator &. Something like below.

          if [ ! -p "/tmp/mysqld.init" ]; then
              mkfifo /tmp/mysqld.init
          fi
          
          echo "something" > /tmp/mysqld.init &
          
          exec mysqld --init-file=/tmp/mysqld.init
          

          But when the fifo file is readout the echo process get a zombie process. How can it be avoided ?

          Note This script is a docker entrypoint script and I don’t have a proper zombie handler. Mysqld always takes the pid 1. Something like below.

            PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
              1     0 mysql    S     383m  19%   0   0% mysqld --init-file=/tmp/mysqld.init
             40     0 root     R     1532   0%   1   0% top
              7     1 root     Z        0   0%   0   0% [entrypoint.sh]
          

          Probably I can use tini an init system for docker but without it how can it be achieved ? Double fork ?

          docker background-process process-management zombie-process

          share|improve this question

          share|improve this question

          share|improve this question

          share|improve this question

          asked Jan 21 at 21:34

          SkyRarSkyRar

          199

          199

          • You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

            – ctrl-alt-delor
            Jan 21 at 22:48

          • You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

            – ctrl-alt-delor
            Jan 21 at 22:48

          You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

          – ctrl-alt-delor
          Jan 21 at 22:48

          You can not ups exec, but this will use up a process. Alternatively just let it happen. There is little cost in a zombie process. init is usually the reaper of lost children. As mysql is taking the role of init, this will not happen. It will probably be cheapest to just let it be a zombi. And no more than the cost of the un-used fifo that is left lying around.

          – ctrl-alt-delor
          Jan 21 at 22:48

          1 Answer
          1

          active

          oldest

          votes

          0

          The problem is surprisingly more complicated than most people would expect.

          The short answer is that you need to use init, or write a replacement for init that implements reaping and downstream signals propagation, or find a new way to pass data to mysqld, or find a way to live with it (which requires understanding and limiting your zombie creation rate).

          zombie processes arise when their exit status is not collected (reaped) by the parent. exec replaces the current process (a shell) with mysqld, which is not expecting to inherit child processes.

          If you start mysqld in the background, and let the shell script remain to reap children, it also needs to handle propagating received signals to mysqld and waiting for them to respond. Failing to do so will cause mysql to be un-gracefully terminated when the shell script exits. This reaping and propagation is normally the job of init.

          You can make the echo exit immediately by opening a handle for read, like this:

          echo "something" > /tmp/fifo &
          exec 3< /tmp/fifo
          

          … but that creates a new problem: normally echo would close the fifo, and now it can’t: it exits too soon. That means mysql will block when reading it. It’s possible to do non-blocking reads and implement timeouts and all that, but we can assume mysql doesn’t, because it probably expects --init-file to behave like a regular file.

          The last option is to live with it. If we’re talking about 1 process or 100, that’s fine. But the process table is finite and each zombie consumes an entry in it. If you don’t manage the zombie count, and the process table fills, you can’t create any new processes.

          The blog post I linked has a lot of good detail and plugs a small init replacement, created by the author, to solve your exact problem.

          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%2f495859%2fhow-to-avoid-zombie-process-while-working-with-named-pipe%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

            0

            The problem is surprisingly more complicated than most people would expect.

            The short answer is that you need to use init, or write a replacement for init that implements reaping and downstream signals propagation, or find a new way to pass data to mysqld, or find a way to live with it (which requires understanding and limiting your zombie creation rate).

            zombie processes arise when their exit status is not collected (reaped) by the parent. exec replaces the current process (a shell) with mysqld, which is not expecting to inherit child processes.

            If you start mysqld in the background, and let the shell script remain to reap children, it also needs to handle propagating received signals to mysqld and waiting for them to respond. Failing to do so will cause mysql to be un-gracefully terminated when the shell script exits. This reaping and propagation is normally the job of init.

            You can make the echo exit immediately by opening a handle for read, like this:

            echo "something" > /tmp/fifo &
            exec 3< /tmp/fifo
            

            … but that creates a new problem: normally echo would close the fifo, and now it can’t: it exits too soon. That means mysql will block when reading it. It’s possible to do non-blocking reads and implement timeouts and all that, but we can assume mysql doesn’t, because it probably expects --init-file to behave like a regular file.

            The last option is to live with it. If we’re talking about 1 process or 100, that’s fine. But the process table is finite and each zombie consumes an entry in it. If you don’t manage the zombie count, and the process table fills, you can’t create any new processes.

            The blog post I linked has a lot of good detail and plugs a small init replacement, created by the author, to solve your exact problem.

            share|improve this answer

              0

              The problem is surprisingly more complicated than most people would expect.

              The short answer is that you need to use init, or write a replacement for init that implements reaping and downstream signals propagation, or find a new way to pass data to mysqld, or find a way to live with it (which requires understanding and limiting your zombie creation rate).

              zombie processes arise when their exit status is not collected (reaped) by the parent. exec replaces the current process (a shell) with mysqld, which is not expecting to inherit child processes.

              If you start mysqld in the background, and let the shell script remain to reap children, it also needs to handle propagating received signals to mysqld and waiting for them to respond. Failing to do so will cause mysql to be un-gracefully terminated when the shell script exits. This reaping and propagation is normally the job of init.

              You can make the echo exit immediately by opening a handle for read, like this:

              echo "something" > /tmp/fifo &
              exec 3< /tmp/fifo
              

              … but that creates a new problem: normally echo would close the fifo, and now it can’t: it exits too soon. That means mysql will block when reading it. It’s possible to do non-blocking reads and implement timeouts and all that, but we can assume mysql doesn’t, because it probably expects --init-file to behave like a regular file.

              The last option is to live with it. If we’re talking about 1 process or 100, that’s fine. But the process table is finite and each zombie consumes an entry in it. If you don’t manage the zombie count, and the process table fills, you can’t create any new processes.

              The blog post I linked has a lot of good detail and plugs a small init replacement, created by the author, to solve your exact problem.

              share|improve this answer

                0

                0

                0

                The problem is surprisingly more complicated than most people would expect.

                The short answer is that you need to use init, or write a replacement for init that implements reaping and downstream signals propagation, or find a new way to pass data to mysqld, or find a way to live with it (which requires understanding and limiting your zombie creation rate).

                zombie processes arise when their exit status is not collected (reaped) by the parent. exec replaces the current process (a shell) with mysqld, which is not expecting to inherit child processes.

                If you start mysqld in the background, and let the shell script remain to reap children, it also needs to handle propagating received signals to mysqld and waiting for them to respond. Failing to do so will cause mysql to be un-gracefully terminated when the shell script exits. This reaping and propagation is normally the job of init.

                You can make the echo exit immediately by opening a handle for read, like this:

                echo "something" > /tmp/fifo &
                exec 3< /tmp/fifo
                

                … but that creates a new problem: normally echo would close the fifo, and now it can’t: it exits too soon. That means mysql will block when reading it. It’s possible to do non-blocking reads and implement timeouts and all that, but we can assume mysql doesn’t, because it probably expects --init-file to behave like a regular file.

                The last option is to live with it. If we’re talking about 1 process or 100, that’s fine. But the process table is finite and each zombie consumes an entry in it. If you don’t manage the zombie count, and the process table fills, you can’t create any new processes.

                The blog post I linked has a lot of good detail and plugs a small init replacement, created by the author, to solve your exact problem.

                share|improve this answer

                The problem is surprisingly more complicated than most people would expect.

                The short answer is that you need to use init, or write a replacement for init that implements reaping and downstream signals propagation, or find a new way to pass data to mysqld, or find a way to live with it (which requires understanding and limiting your zombie creation rate).

                zombie processes arise when their exit status is not collected (reaped) by the parent. exec replaces the current process (a shell) with mysqld, which is not expecting to inherit child processes.

                If you start mysqld in the background, and let the shell script remain to reap children, it also needs to handle propagating received signals to mysqld and waiting for them to respond. Failing to do so will cause mysql to be un-gracefully terminated when the shell script exits. This reaping and propagation is normally the job of init.

                You can make the echo exit immediately by opening a handle for read, like this:

                echo "something" > /tmp/fifo &
                exec 3< /tmp/fifo
                

                … but that creates a new problem: normally echo would close the fifo, and now it can’t: it exits too soon. That means mysql will block when reading it. It’s possible to do non-blocking reads and implement timeouts and all that, but we can assume mysql doesn’t, because it probably expects --init-file to behave like a regular file.

                The last option is to live with it. If we’re talking about 1 process or 100, that’s fine. But the process table is finite and each zombie consumes an entry in it. If you don’t manage the zombie count, and the process table fills, you can’t create any new processes.

                The blog post I linked has a lot of good detail and plugs a small init replacement, created by the author, to solve your exact problem.

                share|improve this answer

                share|improve this answer

                share|improve this answer

                answered Jan 21 at 22:59

                Oh My GoodnessOh My Goodness

                31516

                31516

                    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%2f495859%2fhow-to-avoid-zombie-process-while-working-with-named-pipe%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

                    How can i get the process with the biggest pid?

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

                    1

                    How can I get the process with the biggest pid using ps?

                    share|improve this question

                    • May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                      – Kusalananda
                      Jan 15 at 16:03

                    1

                    How can I get the process with the biggest pid using ps?

                    share|improve this question

                    • May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                      – Kusalananda
                      Jan 15 at 16:03

                    1

                    1

                    1

                    How can I get the process with the biggest pid using ps?

                    share|improve this question

                    How can I get the process with the biggest pid using ps?

                    process sort ps process-management

                    share|improve this question

                    share|improve this question

                    share|improve this question

                    share|improve this question

                    edited Jul 2 ’14 at 17:51

                    polym

                    6,68143157

                    6,68143157

                    asked Jul 1 ’14 at 16:05

                    NirPesNirPes

                    1064

                    1064

                    • May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                      – Kusalananda
                      Jan 15 at 16:03

                    • May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                      – Kusalananda
                      Jan 15 at 16:03

                    May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                    – Kusalananda
                    Jan 15 at 16:03

                    May I ask what you are using this for? Some systems (OpenBSD) uses random PID allocation, and all Unixes resort to wraparound and PID reuse when the maximum allowed PID has been allocated. If you want to figure out the most recently allocated PID, then your question needs rephrasing.

                    – Kusalananda
                    Jan 15 at 16:03

                    2 Answers
                    2

                    active

                    oldest

                    votes

                    3

                    This doesn’t use ps, but parsing ps is likely to be difficult (not to mention non-portable). This ought to be easier (and at least a bit more portable):

                    ( cd /proc; printf "%sn" *; ) | sort -n | tail -n 1
                    

                    That looks for the highest numbered directory inside /proc, which works because on many Unix systems there’s one /proc/### directory per pid that contains information about that process.

                    share|improve this answer

                      2

                      ps -Ao pid= | sort -rn | head -n 1
                      

                      would be POSIX.

                      On Linux, process ids share the same namespace as the thread ids. There, you can do:

                      ps -LAo tid= | sort -rn | head -n 1
                      

                      To get the highest thread or process id number.

                      share|improve this answer

                      • Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                        – godlygeek
                        Jul 1 ’14 at 16:27

                      • @godlygeek, yes I did add the -e while you were writing your comment.

                        – Stéphane Chazelas
                        Jul 1 ’14 at 16:31

                      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%2f140194%2fhow-can-i-get-the-process-with-the-biggest-pid%23new-answer’, ‘question_page’);
                      }
                      );

                      Post as a guest

                      Required, but never shown

                      2 Answers
                      2

                      active

                      oldest

                      votes

                      2 Answers
                      2

                      active

                      oldest

                      votes

                      active

                      oldest

                      votes

                      active

                      oldest

                      votes

                      3

                      This doesn’t use ps, but parsing ps is likely to be difficult (not to mention non-portable). This ought to be easier (and at least a bit more portable):

                      ( cd /proc; printf "%sn" *; ) | sort -n | tail -n 1
                      

                      That looks for the highest numbered directory inside /proc, which works because on many Unix systems there’s one /proc/### directory per pid that contains information about that process.

                      share|improve this answer

                        3

                        This doesn’t use ps, but parsing ps is likely to be difficult (not to mention non-portable). This ought to be easier (and at least a bit more portable):

                        ( cd /proc; printf "%sn" *; ) | sort -n | tail -n 1
                        

                        That looks for the highest numbered directory inside /proc, which works because on many Unix systems there’s one /proc/### directory per pid that contains information about that process.

                        share|improve this answer

                          3

                          3

                          3

                          This doesn’t use ps, but parsing ps is likely to be difficult (not to mention non-portable). This ought to be easier (and at least a bit more portable):

                          ( cd /proc; printf "%sn" *; ) | sort -n | tail -n 1
                          

                          That looks for the highest numbered directory inside /proc, which works because on many Unix systems there’s one /proc/### directory per pid that contains information about that process.

                          share|improve this answer

                          This doesn’t use ps, but parsing ps is likely to be difficult (not to mention non-portable). This ought to be easier (and at least a bit more portable):

                          ( cd /proc; printf "%sn" *; ) | sort -n | tail -n 1
                          

                          That looks for the highest numbered directory inside /proc, which works because on many Unix systems there’s one /proc/### directory per pid that contains information about that process.

                          share|improve this answer

                          share|improve this answer

                          share|improve this answer

                          answered Jul 1 ’14 at 16:11

                          godlygeekgodlygeek

                          5,95011826

                          5,95011826

                              2

                              ps -Ao pid= | sort -rn | head -n 1
                              

                              would be POSIX.

                              On Linux, process ids share the same namespace as the thread ids. There, you can do:

                              ps -LAo tid= | sort -rn | head -n 1
                              

                              To get the highest thread or process id number.

                              share|improve this answer

                              • Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                                – godlygeek
                                Jul 1 ’14 at 16:27

                              • @godlygeek, yes I did add the -e while you were writing your comment.

                                – Stéphane Chazelas
                                Jul 1 ’14 at 16:31

                              2

                              ps -Ao pid= | sort -rn | head -n 1
                              

                              would be POSIX.

                              On Linux, process ids share the same namespace as the thread ids. There, you can do:

                              ps -LAo tid= | sort -rn | head -n 1
                              

                              To get the highest thread or process id number.

                              share|improve this answer

                              • Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                                – godlygeek
                                Jul 1 ’14 at 16:27

                              • @godlygeek, yes I did add the -e while you were writing your comment.

                                – Stéphane Chazelas
                                Jul 1 ’14 at 16:31

                              2

                              2

                              2

                              ps -Ao pid= | sort -rn | head -n 1
                              

                              would be POSIX.

                              On Linux, process ids share the same namespace as the thread ids. There, you can do:

                              ps -LAo tid= | sort -rn | head -n 1
                              

                              To get the highest thread or process id number.

                              share|improve this answer

                              ps -Ao pid= | sort -rn | head -n 1
                              

                              would be POSIX.

                              On Linux, process ids share the same namespace as the thread ids. There, you can do:

                              ps -LAo tid= | sort -rn | head -n 1
                              

                              To get the highest thread or process id number.

                              share|improve this answer

                              share|improve this answer

                              share|improve this answer

                              edited Jan 15 at 15:42

                              answered Jul 1 ’14 at 16:25

                              Stéphane ChazelasStéphane Chazelas

                              303k57570926

                              303k57570926

                              • Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                                – godlygeek
                                Jul 1 ’14 at 16:27

                              • @godlygeek, yes I did add the -e while you were writing your comment.

                                – Stéphane Chazelas
                                Jul 1 ’14 at 16:31

                              • Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                                – godlygeek
                                Jul 1 ’14 at 16:27

                              • @godlygeek, yes I did add the -e while you were writing your comment.

                                – Stéphane Chazelas
                                Jul 1 ’14 at 16:31

                              Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                              – godlygeek
                              Jul 1 ’14 at 16:27

                              Forgot about -o – that definitely makes it easier to parse ps than I was thinking. But you missed -e, since I’m assuming the OP wants all processes on the machine.

                              – godlygeek
                              Jul 1 ’14 at 16:27

                              @godlygeek, yes I did add the -e while you were writing your comment.

                              – Stéphane Chazelas
                              Jul 1 ’14 at 16:31

                              @godlygeek, yes I did add the -e while you were writing your comment.

                              – Stéphane Chazelas
                              Jul 1 ’14 at 16:31

                              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%2f140194%2fhow-can-i-get-the-process-with-the-biggest-pid%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

                              Get output of server crash from server re-spawning script

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

                              0

                              I currently have Homebridge set up on my raspberry pi. When the pi boots, it starts a script which attempts to keep homebridge alive. I originally took the script from this answer which walks you through the rather trivial process of creating such a script. However, I have slightly adapted the script and it now looks like this:

                              until "homebridge" -s /bin/sh pi; do
                                  echo "Server homebridge crashed with exit code $?.  Respawning.." >&2
                                  echo "Looks like Homebridge just crashed, restarting it now..." | mail -s "Homebridge Crash" pi
                                  rm -r /home/pi/.homebridge/accessories/cachedAccessories
                                  sleep 1
                              done
                              

                              It is virtually the same as the original script with the exception that it deletes a folder and waits a second before re-spawning. Furthermore, it sends some mail to my user (pi) to let me know that the process has died and that it is re-spawning. This has been working perfectly for me with the simple omission of any sort of de-bugging. By that I mean that whilst I do get notified that the process has died, I am not presented with an output of the process when it died. It would be perfect if the mail could include, for example, the last 300 lines before the process exited in order to aid with debugging following a crash

                              What exactly would I need to add to the above script in order to receive a ‘log’ of what the homebridge output was just before it crashed in order to debug it?

                              share|improve this question

                              • 1

                                Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                                – Bodo
                                Jan 15 at 9:39

                              • @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                                – Rocco
                                Jan 15 at 16:36

                              • I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                                – Bodo
                                Jan 15 at 17:00

                              • Wouldn’t it be better to let systemd (re)start homebridge?

                                – Bodo
                                Jan 15 at 17:03

                              0

                              I currently have Homebridge set up on my raspberry pi. When the pi boots, it starts a script which attempts to keep homebridge alive. I originally took the script from this answer which walks you through the rather trivial process of creating such a script. However, I have slightly adapted the script and it now looks like this:

                              until "homebridge" -s /bin/sh pi; do
                                  echo "Server homebridge crashed with exit code $?.  Respawning.." >&2
                                  echo "Looks like Homebridge just crashed, restarting it now..." | mail -s "Homebridge Crash" pi
                                  rm -r /home/pi/.homebridge/accessories/cachedAccessories
                                  sleep 1
                              done
                              

                              It is virtually the same as the original script with the exception that it deletes a folder and waits a second before re-spawning. Furthermore, it sends some mail to my user (pi) to let me know that the process has died and that it is re-spawning. This has been working perfectly for me with the simple omission of any sort of de-bugging. By that I mean that whilst I do get notified that the process has died, I am not presented with an output of the process when it died. It would be perfect if the mail could include, for example, the last 300 lines before the process exited in order to aid with debugging following a crash

                              What exactly would I need to add to the above script in order to receive a ‘log’ of what the homebridge output was just before it crashed in order to debug it?

                              share|improve this question

                              • 1

                                Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                                – Bodo
                                Jan 15 at 9:39

                              • @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                                – Rocco
                                Jan 15 at 16:36

                              • I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                                – Bodo
                                Jan 15 at 17:00

                              • Wouldn’t it be better to let systemd (re)start homebridge?

                                – Bodo
                                Jan 15 at 17:03

                              0

                              0

                              0

                              I currently have Homebridge set up on my raspberry pi. When the pi boots, it starts a script which attempts to keep homebridge alive. I originally took the script from this answer which walks you through the rather trivial process of creating such a script. However, I have slightly adapted the script and it now looks like this:

                              until "homebridge" -s /bin/sh pi; do
                                  echo "Server homebridge crashed with exit code $?.  Respawning.." >&2
                                  echo "Looks like Homebridge just crashed, restarting it now..." | mail -s "Homebridge Crash" pi
                                  rm -r /home/pi/.homebridge/accessories/cachedAccessories
                                  sleep 1
                              done
                              

                              It is virtually the same as the original script with the exception that it deletes a folder and waits a second before re-spawning. Furthermore, it sends some mail to my user (pi) to let me know that the process has died and that it is re-spawning. This has been working perfectly for me with the simple omission of any sort of de-bugging. By that I mean that whilst I do get notified that the process has died, I am not presented with an output of the process when it died. It would be perfect if the mail could include, for example, the last 300 lines before the process exited in order to aid with debugging following a crash

                              What exactly would I need to add to the above script in order to receive a ‘log’ of what the homebridge output was just before it crashed in order to debug it?

                              share|improve this question

                              I currently have Homebridge set up on my raspberry pi. When the pi boots, it starts a script which attempts to keep homebridge alive. I originally took the script from this answer which walks you through the rather trivial process of creating such a script. However, I have slightly adapted the script and it now looks like this:

                              until "homebridge" -s /bin/sh pi; do
                                  echo "Server homebridge crashed with exit code $?.  Respawning.." >&2
                                  echo "Looks like Homebridge just crashed, restarting it now..." | mail -s "Homebridge Crash" pi
                                  rm -r /home/pi/.homebridge/accessories/cachedAccessories
                                  sleep 1
                              done
                              

                              It is virtually the same as the original script with the exception that it deletes a folder and waits a second before re-spawning. Furthermore, it sends some mail to my user (pi) to let me know that the process has died and that it is re-spawning. This has been working perfectly for me with the simple omission of any sort of de-bugging. By that I mean that whilst I do get notified that the process has died, I am not presented with an output of the process when it died. It would be perfect if the mail could include, for example, the last 300 lines before the process exited in order to aid with debugging following a crash

                              What exactly would I need to add to the above script in order to receive a ‘log’ of what the homebridge output was just before it crashed in order to debug it?

                              bash shell-script logs process-management

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              edited Jan 15 at 10:53

                              Rui F Ribeiro

                              39.8k1479132

                              39.8k1479132

                              asked Jan 15 at 9:16

                              RoccoRocco

                              11

                              11

                              • 1

                                Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                                – Bodo
                                Jan 15 at 9:39

                              • @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                                – Rocco
                                Jan 15 at 16:36

                              • I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                                – Bodo
                                Jan 15 at 17:00

                              • Wouldn’t it be better to let systemd (re)start homebridge?

                                – Bodo
                                Jan 15 at 17:03

                              • 1

                                Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                                – Bodo
                                Jan 15 at 9:39

                              • @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                                – Rocco
                                Jan 15 at 16:36

                              • I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                                – Bodo
                                Jan 15 at 17:00

                              • Wouldn’t it be better to let systemd (re)start homebridge?

                                – Bodo
                                Jan 15 at 17:03

                              1

                              1

                              Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                              – Bodo
                              Jan 15 at 9:39

                              Which information exactly do you need? The output on stdout and/or stderr? Does Homebridge write a logfile like /var/log/homebridge.log or does it use syslog? maybe you can configure it to do this. Then it would be easy to filter the log and use tail.

                              – Bodo
                              Jan 15 at 9:39

                              @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                              – Rocco
                              Jan 15 at 16:36

                              @Bodo All output would be great, (both stdout and stderr). I know that homebridge does supposedly write a log either to /var/log/homebridge.log or /var/log/homebridge.err as per here and I understand that tail would be a simple solution. However, neither of these files exist for me and that is why I am wondering whether it would be able to integrate it into the script shown above itself.

                              – Rocco
                              Jan 15 at 16:36

                              I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                              – Bodo
                              Jan 15 at 17:00

                              I suggest to find out how to enable the log output. Of course you can use something like until "homebridge" -s /bin/sh pi > outputfile 2>&1; do and later use something like tail -100 outputfile, but the file may permanently grow limited only by the available space. The regular log mechanism probably already has a mechanism for log file switching and deleting of old log files.

                              – Bodo
                              Jan 15 at 17:00

                              Wouldn’t it be better to let systemd (re)start homebridge?

                              – Bodo
                              Jan 15 at 17:03

                              Wouldn’t it be better to let systemd (re)start homebridge?

                              – Bodo
                              Jan 15 at 17:03

                              0

                              active

                              oldest

                              votes

                              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%2f494559%2fget-output-of-server-crash-from-server-re-spawning-script%23new-answer’, ‘question_page’);
                              }
                              );

                              Post as a guest

                              Required, but never shown

                              0

                              active

                              oldest

                              votes

                              0

                              active

                              oldest

                              votes

                              active

                              oldest

                              votes

                              active

                              oldest

                              votes

                              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%2f494559%2fget-output-of-server-crash-from-server-re-spawning-script%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

                              How to kill and rerun process in one command in Linux

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

                              2

                              Usually, I use the ps command on Linux to find the pid of the process, then I kill the process using this pid and after that I rerun the process with some specific command for this specific process.

                              My question is – how can I kill and rerun the process in single command?

                              Is it possible?

                              share|improve this question

                              • 1

                                Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                                – Johan
                                Jan 8 at 11:15

                              2

                              Usually, I use the ps command on Linux to find the pid of the process, then I kill the process using this pid and after that I rerun the process with some specific command for this specific process.

                              My question is – how can I kill and rerun the process in single command?

                              Is it possible?

                              share|improve this question

                              • 1

                                Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                                – Johan
                                Jan 8 at 11:15

                              2

                              2

                              2

                              Usually, I use the ps command on Linux to find the pid of the process, then I kill the process using this pid and after that I rerun the process with some specific command for this specific process.

                              My question is – how can I kill and rerun the process in single command?

                              Is it possible?

                              share|improve this question

                              Usually, I use the ps command on Linux to find the pid of the process, then I kill the process using this pid and after that I rerun the process with some specific command for this specific process.

                              My question is – how can I kill and rerun the process in single command?

                              Is it possible?

                              ps process-management

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              edited Jan 8 at 12:01

                              terdon

                              129k32253428

                              129k32253428

                              asked Jan 8 at 11:11

                              RefaelJanRefaelJan

                              1112

                              1112

                              • 1

                                Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                                – Johan
                                Jan 8 at 11:15

                              • 1

                                Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                                – Johan
                                Jan 8 at 11:15

                              1

                              1

                              Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                              – Johan
                              Jan 8 at 11:15

                              Some programs listen to a Hangup signal to reload their config files. You can send a SIGHUP by running kill with the -HUP (or -1) argument: kill -HUP 1234 – en.wikipedia.org/wiki/SIGHUP

                              – Johan
                              Jan 8 at 11:15

                              1 Answer
                              1

                              active

                              oldest

                              votes

                              2

                              You could get the PID and then read the /prc/$pid/cmdline file to see the command used to launch it:

                              pid=123
                              com=$(perl -pe 's// /g' /proc/$pid/cmdline)
                              kill 123 && "$com"
                              

                              So you could turn that into a function:

                              restartPid(){
                                  pid=$1
                                  com=$(perl -pe 's// /g' /proc/"$pid"/cmdline)
                                  kill 123 && "$com"
                              }
                              

                              However, this will not work for more complex cases where a command was run with a specific environment. You could start getting more creating and extend this to also include the environment with something like this:

                              restartPid(){
                                pid=$1
                                tempFile=$(mktemp)
                                perl -pe 's//n/g' /proc/"$pid"/environ |
                                  perl -pe 's/^([^=]+)=(.*)/$1="$2"/' > "$tempFile"
                                read -r com args < <(perl -lne '@k=split(//); print "$k[0] ",  join " ", map ""$_"", @k[1..$#k]' /proc/"$pid"/cmdline)
                                  dir=$(readlink -f "/proc/$pid/cwd")    
                                  kill $pid
                                  ( . "$tempFile"; cd "$dir"; eval $com $args )
                              }
                              

                              However this is getting quite complex, as you can see, and I cannot guarantee it will always work. Should be a good start though.

                              share|improve this answer

                              • Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                                – Torin
                                Jan 8 at 13:15

                              • @Torin ah yes, good point thanks.

                                – terdon
                                Jan 8 at 13:19

                              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%2f493203%2fhow-to-kill-and-rerun-process-in-one-command-in-linux%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

                              2

                              You could get the PID and then read the /prc/$pid/cmdline file to see the command used to launch it:

                              pid=123
                              com=$(perl -pe 's// /g' /proc/$pid/cmdline)
                              kill 123 && "$com"
                              

                              So you could turn that into a function:

                              restartPid(){
                                  pid=$1
                                  com=$(perl -pe 's// /g' /proc/"$pid"/cmdline)
                                  kill 123 && "$com"
                              }
                              

                              However, this will not work for more complex cases where a command was run with a specific environment. You could start getting more creating and extend this to also include the environment with something like this:

                              restartPid(){
                                pid=$1
                                tempFile=$(mktemp)
                                perl -pe 's//n/g' /proc/"$pid"/environ |
                                  perl -pe 's/^([^=]+)=(.*)/$1="$2"/' > "$tempFile"
                                read -r com args < <(perl -lne '@k=split(//); print "$k[0] ",  join " ", map ""$_"", @k[1..$#k]' /proc/"$pid"/cmdline)
                                  dir=$(readlink -f "/proc/$pid/cwd")    
                                  kill $pid
                                  ( . "$tempFile"; cd "$dir"; eval $com $args )
                              }
                              

                              However this is getting quite complex, as you can see, and I cannot guarantee it will always work. Should be a good start though.

                              share|improve this answer

                              • Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                                – Torin
                                Jan 8 at 13:15

                              • @Torin ah yes, good point thanks.

                                – terdon
                                Jan 8 at 13:19

                              2

                              You could get the PID and then read the /prc/$pid/cmdline file to see the command used to launch it:

                              pid=123
                              com=$(perl -pe 's// /g' /proc/$pid/cmdline)
                              kill 123 && "$com"
                              

                              So you could turn that into a function:

                              restartPid(){
                                  pid=$1
                                  com=$(perl -pe 's// /g' /proc/"$pid"/cmdline)
                                  kill 123 && "$com"
                              }
                              

                              However, this will not work for more complex cases where a command was run with a specific environment. You could start getting more creating and extend this to also include the environment with something like this:

                              restartPid(){
                                pid=$1
                                tempFile=$(mktemp)
                                perl -pe 's//n/g' /proc/"$pid"/environ |
                                  perl -pe 's/^([^=]+)=(.*)/$1="$2"/' > "$tempFile"
                                read -r com args < <(perl -lne '@k=split(//); print "$k[0] ",  join " ", map ""$_"", @k[1..$#k]' /proc/"$pid"/cmdline)
                                  dir=$(readlink -f "/proc/$pid/cwd")    
                                  kill $pid
                                  ( . "$tempFile"; cd "$dir"; eval $com $args )
                              }
                              

                              However this is getting quite complex, as you can see, and I cannot guarantee it will always work. Should be a good start though.

                              share|improve this answer

                              • Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                                – Torin
                                Jan 8 at 13:15

                              • @Torin ah yes, good point thanks.

                                – terdon
                                Jan 8 at 13:19

                              2

                              2

                              2

                              You could get the PID and then read the /prc/$pid/cmdline file to see the command used to launch it:

                              pid=123
                              com=$(perl -pe 's// /g' /proc/$pid/cmdline)
                              kill 123 && "$com"
                              

                              So you could turn that into a function:

                              restartPid(){
                                  pid=$1
                                  com=$(perl -pe 's// /g' /proc/"$pid"/cmdline)
                                  kill 123 && "$com"
                              }
                              

                              However, this will not work for more complex cases where a command was run with a specific environment. You could start getting more creating and extend this to also include the environment with something like this:

                              restartPid(){
                                pid=$1
                                tempFile=$(mktemp)
                                perl -pe 's//n/g' /proc/"$pid"/environ |
                                  perl -pe 's/^([^=]+)=(.*)/$1="$2"/' > "$tempFile"
                                read -r com args < <(perl -lne '@k=split(//); print "$k[0] ",  join " ", map ""$_"", @k[1..$#k]' /proc/"$pid"/cmdline)
                                  dir=$(readlink -f "/proc/$pid/cwd")    
                                  kill $pid
                                  ( . "$tempFile"; cd "$dir"; eval $com $args )
                              }
                              

                              However this is getting quite complex, as you can see, and I cannot guarantee it will always work. Should be a good start though.

                              share|improve this answer

                              You could get the PID and then read the /prc/$pid/cmdline file to see the command used to launch it:

                              pid=123
                              com=$(perl -pe 's// /g' /proc/$pid/cmdline)
                              kill 123 && "$com"
                              

                              So you could turn that into a function:

                              restartPid(){
                                  pid=$1
                                  com=$(perl -pe 's// /g' /proc/"$pid"/cmdline)
                                  kill 123 && "$com"
                              }
                              

                              However, this will not work for more complex cases where a command was run with a specific environment. You could start getting more creating and extend this to also include the environment with something like this:

                              restartPid(){
                                pid=$1
                                tempFile=$(mktemp)
                                perl -pe 's//n/g' /proc/"$pid"/environ |
                                  perl -pe 's/^([^=]+)=(.*)/$1="$2"/' > "$tempFile"
                                read -r com args < <(perl -lne '@k=split(//); print "$k[0] ",  join " ", map ""$_"", @k[1..$#k]' /proc/"$pid"/cmdline)
                                  dir=$(readlink -f "/proc/$pid/cwd")    
                                  kill $pid
                                  ( . "$tempFile"; cd "$dir"; eval $com $args )
                              }
                              

                              However this is getting quite complex, as you can see, and I cannot guarantee it will always work. Should be a good start though.

                              share|improve this answer

                              share|improve this answer

                              share|improve this answer

                              edited Jan 8 at 22:37

                              answered Jan 8 at 12:50

                              terdonterdon

                              129k32253428

                              129k32253428

                              • Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                                – Torin
                                Jan 8 at 13:15

                              • @Torin ah yes, good point thanks.

                                – terdon
                                Jan 8 at 13:19

                              • Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                                – Torin
                                Jan 8 at 13:15

                              • @Torin ah yes, good point thanks.

                                – terdon
                                Jan 8 at 13:19

                              Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                              – Torin
                              Jan 8 at 13:15

                              Might also be worth a cd /proc/"$pid"/cwd to start in the same working directory

                              – Torin
                              Jan 8 at 13:15

                              @Torin ah yes, good point thanks.

                              – terdon
                              Jan 8 at 13:19

                              @Torin ah yes, good point thanks.

                              – terdon
                              Jan 8 at 13:19

                              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%2f493203%2fhow-to-kill-and-rerun-process-in-one-command-in-linux%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

                              Coreutils timeout(1) plays badly with man/less

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

                              2

                              I want to set a timeout to the less(1) command on our company’s production server. Everyday we produce large log files on it, and despite the nightly batch job to archive/remove them, we sometimes get alerted on high disk usage because a (long-)running process can prevent a file from getting unlink(2)-ed physically due to the reference-counting semantics of POSIX filesystems.

                              To avoid the most common cases of such annoyances, I wrote a wrapper of less which runs it under timeout(1) so that idle less processes get automatically killed after several hours without keeping open files in the filesystem.

                              But it turned out to play badly with man(1): when the wrapper is launched by the man command via the PAGER environment variable, it stopped responding to any keyboard inputs. Here is a minimal reproducible test case:

                              $ PAGER='timeout 12h /bin/less' man man
                              

                              After running this, ps fx output looks like this:

                              19415 pts/1    SNs    0:00  _ -bash
                              19854 pts/1    SN+    0:00      _ man man
                              19867 pts/1    SN     0:00          _ timeout 12h /bin/less
                              19869 pts/1    TN     0:00              _ /bin/less
                              

                              and I could only kill -KILL 19869 to regain an access to the terminal.

                              What did I get wrong here?
                              Why is the less process in the T state, as opposed to S?

                              share|improve this question

                              • Show us the wrapper please

                                – Rui F Ribeiro
                                Jan 7 at 7:24

                              • The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                                – Kusalananda
                                Jan 7 at 7:27

                              • I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                                – Gilles
                                Jan 7 at 8:36

                              • @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                                – nodakai
                                Jan 7 at 8:55

                              2

                              I want to set a timeout to the less(1) command on our company’s production server. Everyday we produce large log files on it, and despite the nightly batch job to archive/remove them, we sometimes get alerted on high disk usage because a (long-)running process can prevent a file from getting unlink(2)-ed physically due to the reference-counting semantics of POSIX filesystems.

                              To avoid the most common cases of such annoyances, I wrote a wrapper of less which runs it under timeout(1) so that idle less processes get automatically killed after several hours without keeping open files in the filesystem.

                              But it turned out to play badly with man(1): when the wrapper is launched by the man command via the PAGER environment variable, it stopped responding to any keyboard inputs. Here is a minimal reproducible test case:

                              $ PAGER='timeout 12h /bin/less' man man
                              

                              After running this, ps fx output looks like this:

                              19415 pts/1    SNs    0:00  _ -bash
                              19854 pts/1    SN+    0:00      _ man man
                              19867 pts/1    SN     0:00          _ timeout 12h /bin/less
                              19869 pts/1    TN     0:00              _ /bin/less
                              

                              and I could only kill -KILL 19869 to regain an access to the terminal.

                              What did I get wrong here?
                              Why is the less process in the T state, as opposed to S?

                              share|improve this question

                              • Show us the wrapper please

                                – Rui F Ribeiro
                                Jan 7 at 7:24

                              • The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                                – Kusalananda
                                Jan 7 at 7:27

                              • I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                                – Gilles
                                Jan 7 at 8:36

                              • @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                                – nodakai
                                Jan 7 at 8:55

                              2

                              2

                              2

                              0

                              I want to set a timeout to the less(1) command on our company’s production server. Everyday we produce large log files on it, and despite the nightly batch job to archive/remove them, we sometimes get alerted on high disk usage because a (long-)running process can prevent a file from getting unlink(2)-ed physically due to the reference-counting semantics of POSIX filesystems.

                              To avoid the most common cases of such annoyances, I wrote a wrapper of less which runs it under timeout(1) so that idle less processes get automatically killed after several hours without keeping open files in the filesystem.

                              But it turned out to play badly with man(1): when the wrapper is launched by the man command via the PAGER environment variable, it stopped responding to any keyboard inputs. Here is a minimal reproducible test case:

                              $ PAGER='timeout 12h /bin/less' man man
                              

                              After running this, ps fx output looks like this:

                              19415 pts/1    SNs    0:00  _ -bash
                              19854 pts/1    SN+    0:00      _ man man
                              19867 pts/1    SN     0:00          _ timeout 12h /bin/less
                              19869 pts/1    TN     0:00              _ /bin/less
                              

                              and I could only kill -KILL 19869 to regain an access to the terminal.

                              What did I get wrong here?
                              Why is the less process in the T state, as opposed to S?

                              share|improve this question

                              I want to set a timeout to the less(1) command on our company’s production server. Everyday we produce large log files on it, and despite the nightly batch job to archive/remove them, we sometimes get alerted on high disk usage because a (long-)running process can prevent a file from getting unlink(2)-ed physically due to the reference-counting semantics of POSIX filesystems.

                              To avoid the most common cases of such annoyances, I wrote a wrapper of less which runs it under timeout(1) so that idle less processes get automatically killed after several hours without keeping open files in the filesystem.

                              But it turned out to play badly with man(1): when the wrapper is launched by the man command via the PAGER environment variable, it stopped responding to any keyboard inputs. Here is a minimal reproducible test case:

                              $ PAGER='timeout 12h /bin/less' man man
                              

                              After running this, ps fx output looks like this:

                              19415 pts/1    SNs    0:00  _ -bash
                              19854 pts/1    SN+    0:00      _ man man
                              19867 pts/1    SN     0:00          _ timeout 12h /bin/less
                              19869 pts/1    TN     0:00              _ /bin/less
                              

                              and I could only kill -KILL 19869 to regain an access to the terminal.

                              What did I get wrong here?
                              Why is the less process in the T state, as opposed to S?

                              terminal process-management timeout

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              asked Jan 7 at 7:19

                              nodakainodakai

                              247110

                              247110

                              • Show us the wrapper please

                                – Rui F Ribeiro
                                Jan 7 at 7:24

                              • The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                                – Kusalananda
                                Jan 7 at 7:27

                              • I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                                – Gilles
                                Jan 7 at 8:36

                              • @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                                – nodakai
                                Jan 7 at 8:55

                              • Show us the wrapper please

                                – Rui F Ribeiro
                                Jan 7 at 7:24

                              • The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                                – Kusalananda
                                Jan 7 at 7:27

                              • I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                                – Gilles
                                Jan 7 at 8:36

                              • @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                                – nodakai
                                Jan 7 at 8:55

                              Show us the wrapper please

                              – Rui F Ribeiro
                              Jan 7 at 7:24

                              Show us the wrapper please

                              – Rui F Ribeiro
                              Jan 7 at 7:24

                              The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                              – Kusalananda
                              Jan 7 at 7:27

                              The only way I can reproduce this is if I temporarily put man/less in the background through Ctrl+Z. Did you do that to run your ps command? That would put less in a T state… Using timeout in PAGER seems to work as expected on my OpenBSD system.

                              – Kusalananda
                              Jan 7 at 7:27

                              I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                              – Gilles
                              Jan 7 at 8:36

                              I suspect that the less process is getting suspended because it isn’ in the foreground (so it receives SIGTTIN when it tries to read from stdin). @Kusalananda

                              – Gilles
                              Jan 7 at 8:36

                              @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                              – nodakai
                              Jan 7 at 8:55

                              @Gilles Had you given a comment a bit earlier… I just posted my findings as a solution to my own question.

                              – nodakai
                              Jan 7 at 8:55

                              1 Answer
                              1

                              active

                              oldest

                              votes

                              2

                              Answering to my own question, as I couldn’t really find any hints on this via my googling.

                              strace(1) could actually reveal that SIGTTOU had been sent to the less process.

                              • https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

                              This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. …snip…

                              And apparently timeout(1) by default puts the process under management into background:

                              • https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

                              --foreground

                              Don’t create a separate background program group, so that the managed command can use the foreground TTY normally. …snip…

                              So the solution to my problem was

                              $ PAGER='/bin/timeout --foreground 12h /bin/less' man man
                              

                              (and something equivalent in my wrapper)

                              share|improve this answer

                              • Hmmm… I wonder it seemed to be working on my system then?

                                – Kusalananda
                                Jan 7 at 9:02

                              • 1

                                @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                                – mosvy
                                Jan 7 at 9:16

                              • 1

                                less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                                – mosvy
                                Jan 7 at 9:23

                              • 1

                                @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                                – roaima
                                Jan 7 at 9:59

                              • Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                                – roaima
                                Jan 7 at 10:04

                              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%2f492941%2fcoreutils-timeout1-plays-badly-with-man-less%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

                              2

                              Answering to my own question, as I couldn’t really find any hints on this via my googling.

                              strace(1) could actually reveal that SIGTTOU had been sent to the less process.

                              • https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

                              This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. …snip…

                              And apparently timeout(1) by default puts the process under management into background:

                              • https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

                              --foreground

                              Don’t create a separate background program group, so that the managed command can use the foreground TTY normally. …snip…

                              So the solution to my problem was

                              $ PAGER='/bin/timeout --foreground 12h /bin/less' man man
                              

                              (and something equivalent in my wrapper)

                              share|improve this answer

                              • Hmmm… I wonder it seemed to be working on my system then?

                                – Kusalananda
                                Jan 7 at 9:02

                              • 1

                                @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                                – mosvy
                                Jan 7 at 9:16

                              • 1

                                less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                                – mosvy
                                Jan 7 at 9:23

                              • 1

                                @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                                – roaima
                                Jan 7 at 9:59

                              • Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                                – roaima
                                Jan 7 at 10:04

                              2

                              Answering to my own question, as I couldn’t really find any hints on this via my googling.

                              strace(1) could actually reveal that SIGTTOU had been sent to the less process.

                              • https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

                              This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. …snip…

                              And apparently timeout(1) by default puts the process under management into background:

                              • https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

                              --foreground

                              Don’t create a separate background program group, so that the managed command can use the foreground TTY normally. …snip…

                              So the solution to my problem was

                              $ PAGER='/bin/timeout --foreground 12h /bin/less' man man
                              

                              (and something equivalent in my wrapper)

                              share|improve this answer

                              • Hmmm… I wonder it seemed to be working on my system then?

                                – Kusalananda
                                Jan 7 at 9:02

                              • 1

                                @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                                – mosvy
                                Jan 7 at 9:16

                              • 1

                                less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                                – mosvy
                                Jan 7 at 9:23

                              • 1

                                @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                                – roaima
                                Jan 7 at 9:59

                              • Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                                – roaima
                                Jan 7 at 10:04

                              2

                              2

                              2

                              Answering to my own question, as I couldn’t really find any hints on this via my googling.

                              strace(1) could actually reveal that SIGTTOU had been sent to the less process.

                              • https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

                              This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. …snip…

                              And apparently timeout(1) by default puts the process under management into background:

                              • https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

                              --foreground

                              Don’t create a separate background program group, so that the managed command can use the foreground TTY normally. …snip…

                              So the solution to my problem was

                              $ PAGER='/bin/timeout --foreground 12h /bin/less' man man
                              

                              (and something equivalent in my wrapper)

                              share|improve this answer

                              Answering to my own question, as I couldn’t really find any hints on this via my googling.

                              strace(1) could actually reveal that SIGTTOU had been sent to the less process.

                              • https://www.gnu.org/software/libc/manual/html_node/Job-Control-Signals.html

                              This is similar to SIGTTIN, but is generated when a process in a background job attempts to write to the terminal or set its modes. …snip…

                              And apparently timeout(1) by default puts the process under management into background:

                              • https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html

                              --foreground

                              Don’t create a separate background program group, so that the managed command can use the foreground TTY normally. …snip…

                              So the solution to my problem was

                              $ PAGER='/bin/timeout --foreground 12h /bin/less' man man
                              

                              (and something equivalent in my wrapper)

                              share|improve this answer

                              share|improve this answer

                              share|improve this answer

                              edited Jan 7 at 8:56

                              answered Jan 7 at 8:51

                              nodakainodakai

                              247110

                              247110

                              • Hmmm… I wonder it seemed to be working on my system then?

                                – Kusalananda
                                Jan 7 at 9:02

                              • 1

                                @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                                – mosvy
                                Jan 7 at 9:16

                              • 1

                                less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                                – mosvy
                                Jan 7 at 9:23

                              • 1

                                @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                                – roaima
                                Jan 7 at 9:59

                              • Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                                – roaima
                                Jan 7 at 10:04

                              • Hmmm… I wonder it seemed to be working on my system then?

                                – Kusalananda
                                Jan 7 at 9:02

                              • 1

                                @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                                – mosvy
                                Jan 7 at 9:16

                              • 1

                                less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                                – mosvy
                                Jan 7 at 9:23

                              • 1

                                @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                                – roaima
                                Jan 7 at 9:59

                              • Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                                – roaima
                                Jan 7 at 10:04

                              Hmmm… I wonder it seemed to be working on my system then?

                              – Kusalananda
                              Jan 7 at 9:02

                              Hmmm… I wonder it seemed to be working on my system then?

                              – Kusalananda
                              Jan 7 at 9:02

                              1

                              1

                              @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                              – mosvy
                              Jan 7 at 9:16

                              @Kusalananda /usr/bin/man is a completely different beast on OpenBSD than on linux, especially since they got rid of groff.

                              – mosvy
                              Jan 7 at 9:16

                              1

                              1

                              less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                              – mosvy
                              Jan 7 at 9:23

                              less still doesn’t work right with timeout; when killed by a signal, less will fail to restore the stty/termios settings, and you will be left with having to do a blind reset or stty sane; try timeout 2s less ~/.bashrc.

                              – mosvy
                              Jan 7 at 9:23

                              1

                              1

                              @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                              – roaima
                              Jan 7 at 9:59

                              @mosvy this (minimal example) wrapper seems to fix it for me g=$(stty -g); timeout 2s less ~/.bashrc || stty "$g"

                              – roaima
                              Jan 7 at 9:59

                              Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                              – roaima
                              Jan 7 at 10:04

                              Nodakai, on my Debian version of timeout the man page and effect appear to contradict the GNU info page you referenced. With timeout 12h less the page works as I would expect – until the timeout gets reached. Specifically, the --foreground option is not required unless timeout itself is not being run directly from a terminal.

                              – roaima
                              Jan 7 at 10:04

                              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%2f492941%2fcoreutils-timeout1-plays-badly-with-man-less%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

                              Why should parent process wait (to terminate) until all of its child process terminates?

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

                              0

                              I know there is no enforcement for the parent process to wait until all its child process terminates. However it’s a convention followed.
                              Furthermore, I know that if parent process terminates before it’s child process terminates, then the child process become orphan and it will be adapted by init process.
                              But what I don’t understand is, what is the problem if the child process becomes orphan and gets adapted by initprocess. Why should it be attached to the parent process itself until it terminates?

                              share|improve this question

                              • What you know is wrong. unix.stackexchange.com/a/177361/5132

                                – JdeBP
                                Dec 30 ’18 at 11:42

                              0

                              I know there is no enforcement for the parent process to wait until all its child process terminates. However it’s a convention followed.
                              Furthermore, I know that if parent process terminates before it’s child process terminates, then the child process become orphan and it will be adapted by init process.
                              But what I don’t understand is, what is the problem if the child process becomes orphan and gets adapted by initprocess. Why should it be attached to the parent process itself until it terminates?

                              share|improve this question

                              • What you know is wrong. unix.stackexchange.com/a/177361/5132

                                – JdeBP
                                Dec 30 ’18 at 11:42

                              0

                              0

                              0

                              I know there is no enforcement for the parent process to wait until all its child process terminates. However it’s a convention followed.
                              Furthermore, I know that if parent process terminates before it’s child process terminates, then the child process become orphan and it will be adapted by init process.
                              But what I don’t understand is, what is the problem if the child process becomes orphan and gets adapted by initprocess. Why should it be attached to the parent process itself until it terminates?

                              share|improve this question

                              I know there is no enforcement for the parent process to wait until all its child process terminates. However it’s a convention followed.
                              Furthermore, I know that if parent process terminates before it’s child process terminates, then the child process become orphan and it will be adapted by init process.
                              But what I don’t understand is, what is the problem if the child process becomes orphan and gets adapted by initprocess. Why should it be attached to the parent process itself until it terminates?

                              process init process-management wait

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              share|improve this question

                              asked Dec 30 ’18 at 6:49

                              Darshan LDarshan L

                              41

                              41

                              • What you know is wrong. unix.stackexchange.com/a/177361/5132

                                – JdeBP
                                Dec 30 ’18 at 11:42

                              • What you know is wrong. unix.stackexchange.com/a/177361/5132

                                – JdeBP
                                Dec 30 ’18 at 11:42

                              What you know is wrong. unix.stackexchange.com/a/177361/5132

                              – JdeBP
                              Dec 30 ’18 at 11:42

                              What you know is wrong. unix.stackexchange.com/a/177361/5132

                              – JdeBP
                              Dec 30 ’18 at 11:42

                              2 Answers
                              2

                              active

                              oldest

                              votes

                              1

                              The main reason for this convention is that if the parent process terminates before the children, the children’s exit code will be lost and the child process may remain a zombie for a while.

                              After a child process terminates, it will stay around (and consume memory) until the exit code is read. This is what is referred to as a zombie process – dead, but not reaped (removed).

                              It is generally the parent process’s responsibility to read the exit code and allow the zombie process to completely go away. Since the parent should keep track of the children, it will hopefully be quick to clean up. If the parent process does not do that, you have a resource leak.

                              If the parent process terminates before the child does, init will indeed take over that responsibility, but it may not be aware of that immediately, so the child may remain a zombie for longer, and thus take up more resources.

                              Edit: for clarification, a process in zombie state does not keep all of its memory around – most of it is freed before the process becomes a zombie. It is the entry in the process table that remains. The more process table entries there are, the more time the kernel will need for process-related activities.

                              share|improve this answer

                                0

                                The main reason for this convention is that, if a process forks children,
                                typically the child processes are doing part of the job
                                that the main process was expected to do.
                                 
                                Did you have any example of a program that forks in mind?

                                Here are some examples:

                                • A program that does intense computation might fork
                                  multiple copies of itself
                                  in order to run on multiple CPUs/cores simultaneously. 
                                  (It might be more conventional to use threads for this,
                                  but it can certainly be done with forked processes.) 
                                  Such a program might be designed so that each process
                                  just writes an independent output. 
                                  But it would also be common for the main process
                                  to wait for all the children to finish and then consolidate their results.
                                • Programs like netcat sometimes
                                  have one process reading from host A and writing to host B,
                                  and one process reading from host B and writing to host A. 
                                  (Yes, this could also be done with threads.)
                                • Trivially, in the cases of find -exec and xargs,
                                  the (main) program’s job is to run the subordinate program
                                  and wait for it to finish. 
                                  Imagine what would happen if a user said

                                  find . -type f -exec cp {} /backup ';'  &&  rm -r .

                                  and the find exited without waiting for all the copies to finish.

                                In these cases (and others), the main program’s job isn’t done
                                until any and all child processes have completed. 
                                Therefore, the program must not exit
                                until it has waited for all the child process(es).

                                Of course this isn’t the only way fork is used. 
                                It is common for network servers (e.g., FTP and mail)
                                to have one main process that listens for incoming connections,
                                and then to fork a child each time it gets a client connection. 
                                Such child processes could terminate at arbitrary times
                                (determined by the clients),
                                and there is no reason for the main process to wait for its children.

                                The bit about what “parent”/reaper process
                                a child process is associated with when it terminates
                                is not really an issue.

                                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%2f491549%2fwhy-should-parent-process-wait-to-terminate-until-all-of-its-child-process-ter%23new-answer’, ‘question_page’);
                                  }
                                  );

                                  Post as a guest

                                  Required, but never shown

                                  2 Answers
                                  2

                                  active

                                  oldest

                                  votes

                                  2 Answers
                                  2

                                  active

                                  oldest

                                  votes

                                  active

                                  oldest

                                  votes

                                  active

                                  oldest

                                  votes

                                  1

                                  The main reason for this convention is that if the parent process terminates before the children, the children’s exit code will be lost and the child process may remain a zombie for a while.

                                  After a child process terminates, it will stay around (and consume memory) until the exit code is read. This is what is referred to as a zombie process – dead, but not reaped (removed).

                                  It is generally the parent process’s responsibility to read the exit code and allow the zombie process to completely go away. Since the parent should keep track of the children, it will hopefully be quick to clean up. If the parent process does not do that, you have a resource leak.

                                  If the parent process terminates before the child does, init will indeed take over that responsibility, but it may not be aware of that immediately, so the child may remain a zombie for longer, and thus take up more resources.

                                  Edit: for clarification, a process in zombie state does not keep all of its memory around – most of it is freed before the process becomes a zombie. It is the entry in the process table that remains. The more process table entries there are, the more time the kernel will need for process-related activities.

                                  share|improve this answer

                                    1

                                    The main reason for this convention is that if the parent process terminates before the children, the children’s exit code will be lost and the child process may remain a zombie for a while.

                                    After a child process terminates, it will stay around (and consume memory) until the exit code is read. This is what is referred to as a zombie process – dead, but not reaped (removed).

                                    It is generally the parent process’s responsibility to read the exit code and allow the zombie process to completely go away. Since the parent should keep track of the children, it will hopefully be quick to clean up. If the parent process does not do that, you have a resource leak.

                                    If the parent process terminates before the child does, init will indeed take over that responsibility, but it may not be aware of that immediately, so the child may remain a zombie for longer, and thus take up more resources.

                                    Edit: for clarification, a process in zombie state does not keep all of its memory around – most of it is freed before the process becomes a zombie. It is the entry in the process table that remains. The more process table entries there are, the more time the kernel will need for process-related activities.

                                    share|improve this answer

                                      1

                                      1

                                      1

                                      The main reason for this convention is that if the parent process terminates before the children, the children’s exit code will be lost and the child process may remain a zombie for a while.

                                      After a child process terminates, it will stay around (and consume memory) until the exit code is read. This is what is referred to as a zombie process – dead, but not reaped (removed).

                                      It is generally the parent process’s responsibility to read the exit code and allow the zombie process to completely go away. Since the parent should keep track of the children, it will hopefully be quick to clean up. If the parent process does not do that, you have a resource leak.

                                      If the parent process terminates before the child does, init will indeed take over that responsibility, but it may not be aware of that immediately, so the child may remain a zombie for longer, and thus take up more resources.

                                      Edit: for clarification, a process in zombie state does not keep all of its memory around – most of it is freed before the process becomes a zombie. It is the entry in the process table that remains. The more process table entries there are, the more time the kernel will need for process-related activities.

                                      share|improve this answer

                                      The main reason for this convention is that if the parent process terminates before the children, the children’s exit code will be lost and the child process may remain a zombie for a while.

                                      After a child process terminates, it will stay around (and consume memory) until the exit code is read. This is what is referred to as a zombie process – dead, but not reaped (removed).

                                      It is generally the parent process’s responsibility to read the exit code and allow the zombie process to completely go away. Since the parent should keep track of the children, it will hopefully be quick to clean up. If the parent process does not do that, you have a resource leak.

                                      If the parent process terminates before the child does, init will indeed take over that responsibility, but it may not be aware of that immediately, so the child may remain a zombie for longer, and thus take up more resources.

                                      Edit: for clarification, a process in zombie state does not keep all of its memory around – most of it is freed before the process becomes a zombie. It is the entry in the process table that remains. The more process table entries there are, the more time the kernel will need for process-related activities.

                                      share|improve this answer

                                      share|improve this answer

                                      share|improve this answer

                                      answered Dec 30 ’18 at 7:11

                                      Kevin KeaneKevin Keane

                                      335111

                                      335111

                                          0

                                          The main reason for this convention is that, if a process forks children,
                                          typically the child processes are doing part of the job
                                          that the main process was expected to do.
                                           
                                          Did you have any example of a program that forks in mind?

                                          Here are some examples:

                                          • A program that does intense computation might fork
                                            multiple copies of itself
                                            in order to run on multiple CPUs/cores simultaneously. 
                                            (It might be more conventional to use threads for this,
                                            but it can certainly be done with forked processes.) 
                                            Such a program might be designed so that each process
                                            just writes an independent output. 
                                            But it would also be common for the main process
                                            to wait for all the children to finish and then consolidate their results.
                                          • Programs like netcat sometimes
                                            have one process reading from host A and writing to host B,
                                            and one process reading from host B and writing to host A. 
                                            (Yes, this could also be done with threads.)
                                          • Trivially, in the cases of find -exec and xargs,
                                            the (main) program’s job is to run the subordinate program
                                            and wait for it to finish. 
                                            Imagine what would happen if a user said

                                            find . -type f -exec cp {} /backup ';'  &&  rm -r .

                                            and the find exited without waiting for all the copies to finish.

                                          In these cases (and others), the main program’s job isn’t done
                                          until any and all child processes have completed. 
                                          Therefore, the program must not exit
                                          until it has waited for all the child process(es).

                                          Of course this isn’t the only way fork is used. 
                                          It is common for network servers (e.g., FTP and mail)
                                          to have one main process that listens for incoming connections,
                                          and then to fork a child each time it gets a client connection. 
                                          Such child processes could terminate at arbitrary times
                                          (determined by the clients),
                                          and there is no reason for the main process to wait for its children.

                                          The bit about what “parent”/reaper process
                                          a child process is associated with when it terminates
                                          is not really an issue.

                                          share|improve this answer

                                            0

                                            The main reason for this convention is that, if a process forks children,
                                            typically the child processes are doing part of the job
                                            that the main process was expected to do.
                                             
                                            Did you have any example of a program that forks in mind?

                                            Here are some examples:

                                            • A program that does intense computation might fork
                                              multiple copies of itself
                                              in order to run on multiple CPUs/cores simultaneously. 
                                              (It might be more conventional to use threads for this,
                                              but it can certainly be done with forked processes.) 
                                              Such a program might be designed so that each process
                                              just writes an independent output. 
                                              But it would also be common for the main process
                                              to wait for all the children to finish and then consolidate their results.
                                            • Programs like netcat sometimes
                                              have one process reading from host A and writing to host B,
                                              and one process reading from host B and writing to host A. 
                                              (Yes, this could also be done with threads.)
                                            • Trivially, in the cases of find -exec and xargs,
                                              the (main) program’s job is to run the subordinate program
                                              and wait for it to finish. 
                                              Imagine what would happen if a user said

                                              find . -type f -exec cp {} /backup ';'  &&  rm -r .

                                              and the find exited without waiting for all the copies to finish.

                                            In these cases (and others), the main program’s job isn’t done
                                            until any and all child processes have completed. 
                                            Therefore, the program must not exit
                                            until it has waited for all the child process(es).

                                            Of course this isn’t the only way fork is used. 
                                            It is common for network servers (e.g., FTP and mail)
                                            to have one main process that listens for incoming connections,
                                            and then to fork a child each time it gets a client connection. 
                                            Such child processes could terminate at arbitrary times
                                            (determined by the clients),
                                            and there is no reason for the main process to wait for its children.

                                            The bit about what “parent”/reaper process
                                            a child process is associated with when it terminates
                                            is not really an issue.

                                            share|improve this answer

                                              0

                                              0

                                              0

                                              The main reason for this convention is that, if a process forks children,
                                              typically the child processes are doing part of the job
                                              that the main process was expected to do.
                                               
                                              Did you have any example of a program that forks in mind?

                                              Here are some examples:

                                              • A program that does intense computation might fork
                                                multiple copies of itself
                                                in order to run on multiple CPUs/cores simultaneously. 
                                                (It might be more conventional to use threads for this,
                                                but it can certainly be done with forked processes.) 
                                                Such a program might be designed so that each process
                                                just writes an independent output. 
                                                But it would also be common for the main process
                                                to wait for all the children to finish and then consolidate their results.
                                              • Programs like netcat sometimes
                                                have one process reading from host A and writing to host B,
                                                and one process reading from host B and writing to host A. 
                                                (Yes, this could also be done with threads.)
                                              • Trivially, in the cases of find -exec and xargs,
                                                the (main) program’s job is to run the subordinate program
                                                and wait for it to finish. 
                                                Imagine what would happen if a user said

                                                find . -type f -exec cp {} /backup ';'  &&  rm -r .

                                                and the find exited without waiting for all the copies to finish.

                                              In these cases (and others), the main program’s job isn’t done
                                              until any and all child processes have completed. 
                                              Therefore, the program must not exit
                                              until it has waited for all the child process(es).

                                              Of course this isn’t the only way fork is used. 
                                              It is common for network servers (e.g., FTP and mail)
                                              to have one main process that listens for incoming connections,
                                              and then to fork a child each time it gets a client connection. 
                                              Such child processes could terminate at arbitrary times
                                              (determined by the clients),
                                              and there is no reason for the main process to wait for its children.

                                              The bit about what “parent”/reaper process
                                              a child process is associated with when it terminates
                                              is not really an issue.

                                              share|improve this answer

                                              The main reason for this convention is that, if a process forks children,
                                              typically the child processes are doing part of the job
                                              that the main process was expected to do.
                                               
                                              Did you have any example of a program that forks in mind?

                                              Here are some examples:

                                              • A program that does intense computation might fork
                                                multiple copies of itself
                                                in order to run on multiple CPUs/cores simultaneously. 
                                                (It might be more conventional to use threads for this,
                                                but it can certainly be done with forked processes.) 
                                                Such a program might be designed so that each process
                                                just writes an independent output. 
                                                But it would also be common for the main process
                                                to wait for all the children to finish and then consolidate their results.
                                              • Programs like netcat sometimes
                                                have one process reading from host A and writing to host B,
                                                and one process reading from host B and writing to host A. 
                                                (Yes, this could also be done with threads.)
                                              • Trivially, in the cases of find -exec and xargs,
                                                the (main) program’s job is to run the subordinate program
                                                and wait for it to finish. 
                                                Imagine what would happen if a user said

                                                find . -type f -exec cp {} /backup ';'  &&  rm -r .

                                                and the find exited without waiting for all the copies to finish.

                                              In these cases (and others), the main program’s job isn’t done
                                              until any and all child processes have completed. 
                                              Therefore, the program must not exit
                                              until it has waited for all the child process(es).

                                              Of course this isn’t the only way fork is used. 
                                              It is common for network servers (e.g., FTP and mail)
                                              to have one main process that listens for incoming connections,
                                              and then to fork a child each time it gets a client connection. 
                                              Such child processes could terminate at arbitrary times
                                              (determined by the clients),
                                              and there is no reason for the main process to wait for its children.

                                              The bit about what “parent”/reaper process
                                              a child process is associated with when it terminates
                                              is not really an issue.

                                              share|improve this answer

                                              share|improve this answer

                                              share|improve this answer

                                              answered Jan 1 at 6:06

                                              G-ManG-Man

                                              13k93365

                                              13k93365

                                                  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%2f491549%2fwhy-should-parent-process-wait-to-terminate-until-all-of-its-child-process-ter%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

                                                  About `page_table_lock` in Linux process address space

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

                                                  1

                                                  I’m reading a tutorial about Linux page table, in the linked page

                                                  Each process has its own page tables (threads share them). The pgd field of the memory descriptor points to the process’s page global directory. Manipulating and traversing page tables requires the page_table_lock, which is located inside the associated memory descriptor.

                                                  So what is a page_table_lock? Is it some kind of reader-writer lock to prevent race condition?

                                                  share|improve this question

                                                  • 1

                                                    read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                    – Murray Jensen
                                                    Dec 28 ’18 at 14:05

                                                  1

                                                  I’m reading a tutorial about Linux page table, in the linked page

                                                  Each process has its own page tables (threads share them). The pgd field of the memory descriptor points to the process’s page global directory. Manipulating and traversing page tables requires the page_table_lock, which is located inside the associated memory descriptor.

                                                  So what is a page_table_lock? Is it some kind of reader-writer lock to prevent race condition?

                                                  share|improve this question

                                                  • 1

                                                    read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                    – Murray Jensen
                                                    Dec 28 ’18 at 14:05

                                                  1

                                                  1

                                                  1

                                                  I’m reading a tutorial about Linux page table, in the linked page

                                                  Each process has its own page tables (threads share them). The pgd field of the memory descriptor points to the process’s page global directory. Manipulating and traversing page tables requires the page_table_lock, which is located inside the associated memory descriptor.

                                                  So what is a page_table_lock? Is it some kind of reader-writer lock to prevent race condition?

                                                  share|improve this question

                                                  I’m reading a tutorial about Linux page table, in the linked page

                                                  Each process has its own page tables (threads share them). The pgd field of the memory descriptor points to the process’s page global directory. Manipulating and traversing page tables requires the page_table_lock, which is located inside the associated memory descriptor.

                                                  So what is a page_table_lock? Is it some kind of reader-writer lock to prevent race condition?

                                                  linux kernel process-management lock

                                                  share|improve this question

                                                  share|improve this question

                                                  share|improve this question

                                                  share|improve this question

                                                  asked Dec 27 ’18 at 13:22

                                                  ptr_user7813604ptr_user7813604

                                                  1508

                                                  1508

                                                  • 1

                                                    read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                    – Murray Jensen
                                                    Dec 28 ’18 at 14:05

                                                  • 1

                                                    read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                    – Murray Jensen
                                                    Dec 28 ’18 at 14:05

                                                  1

                                                  1

                                                  read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                  – Murray Jensen
                                                  Dec 28 ’18 at 14:05

                                                  read this – it used to be a spin lock (simple mutual exclusion – no read-writer), but it is now more complicated.
                                                  – Murray Jensen
                                                  Dec 28 ’18 at 14:05

                                                  0

                                                  active

                                                  oldest

                                                  votes

                                                  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%2f491125%2fabout-page-table-lock-in-linux-process-address-space%23new-answer’, ‘question_page’);
                                                  }
                                                  );

                                                  Post as a guest

                                                  Required, but never shown

                                                  0

                                                  active

                                                  oldest

                                                  votes

                                                  0

                                                  active

                                                  oldest

                                                  votes

                                                  active

                                                  oldest

                                                  votes

                                                  active

                                                  oldest

                                                  votes

                                                  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.

                                                  Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

                                                  Please pay close attention to the following guidance:

                                                  • 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%2f491125%2fabout-page-table-lock-in-linux-process-address-space%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

                                                  kernel event listener

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

                                                  up vote
                                                  2
                                                  down vote

                                                  favorite

                                                  I wonder if there is something similar to an event listener in UNIX that a program can subscribe to? Specifically I want to know:

                                                  Start and end times of a user session
                                                  Start and end of the applications executed by that user
                                                  

                                                  Any Tips?

                                                  share|improve this question

                                                    up vote
                                                    2
                                                    down vote

                                                    favorite

                                                    I wonder if there is something similar to an event listener in UNIX that a program can subscribe to? Specifically I want to know:

                                                    Start and end times of a user session
                                                    Start and end of the applications executed by that user
                                                    

                                                    Any Tips?

                                                    share|improve this question

                                                      up vote
                                                      2
                                                      down vote

                                                      favorite

                                                      up vote
                                                      2
                                                      down vote

                                                      favorite

                                                      I wonder if there is something similar to an event listener in UNIX that a program can subscribe to? Specifically I want to know:

                                                      Start and end times of a user session
                                                      Start and end of the applications executed by that user
                                                      

                                                      Any Tips?

                                                      share|improve this question

                                                      I wonder if there is something similar to an event listener in UNIX that a program can subscribe to? Specifically I want to know:

                                                      Start and end times of a user session
                                                      Start and end of the applications executed by that user
                                                      

                                                      Any Tips?

                                                      ubuntu kernel linux-kernel process-management application

                                                      share|improve this question

                                                      share|improve this question

                                                      share|improve this question

                                                      share|improve this question

                                                      edited Jun 2 ’14 at 14:49

                                                      slm

                                                      245k66505671

                                                      245k66505671

                                                      asked Jun 2 ’14 at 13:31

                                                      Inkognito

                                                      211

                                                      211

                                                          1 Answer
                                                          1

                                                          active

                                                          oldest

                                                          votes

                                                          up vote
                                                          1
                                                          down vote

                                                          Using psacct

                                                          The events that you’re looking for can be found through psacct. Specifically I’d take a look at the tool ac which shows accounting information on users. I touch on this in this U&L Q&A titled: Commands for determining level of usage of server.

                                                          NOTE: This is not a subscribe-able “service”, rather a tracking & reporting infrastructure that you can ask it questions.

                                                          You can also use lastcomm (part of psacct, it has several tools in the suite) to find out when a given application was used by user X.

                                                          Example

                                                          $ lastcomm rm
                                                          rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                          rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                          rm                S     root     pts/0      0.00 secs Tue Nov 14 00:38 
                                                          

                                                          You’ll have to dig a bit into psacct but there’s a lot of resources about it on U&L as well as google which should get you what you want.

                                                          Using auditd

                                                          The other tool, in the same vain as psacct‘s tracking & reporting approach is auditd. With auditd you can query to find out who and for how long program X was run.

                                                          Example

                                                          $ sudo ausearch -x /usr/bin/sudo | head -5
                                                          ----
                                                          time->Sat Dec  7 21:15:15 2013
                                                          type=USER_AUTH msg=audit(1386468915.558:419): pid=2189 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="saml" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
                                                          ----
                                                          time->Sat Dec  7 21:15:15 2013
                                                          

                                                          NOTE: The above is finding all the entries where someone ran the tool /usr/bin/sudo.

                                                          References

                                                          • Chapter 34. Introducing an Audit Rule Set
                                                          • 7.7. Searching the Audit Log Files
                                                          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: 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%2f134107%2fkernel-event-listener%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

                                                            up vote
                                                            1
                                                            down vote

                                                            Using psacct

                                                            The events that you’re looking for can be found through psacct. Specifically I’d take a look at the tool ac which shows accounting information on users. I touch on this in this U&L Q&A titled: Commands for determining level of usage of server.

                                                            NOTE: This is not a subscribe-able “service”, rather a tracking & reporting infrastructure that you can ask it questions.

                                                            You can also use lastcomm (part of psacct, it has several tools in the suite) to find out when a given application was used by user X.

                                                            Example

                                                            $ lastcomm rm
                                                            rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                            rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                            rm                S     root     pts/0      0.00 secs Tue Nov 14 00:38 
                                                            

                                                            You’ll have to dig a bit into psacct but there’s a lot of resources about it on U&L as well as google which should get you what you want.

                                                            Using auditd

                                                            The other tool, in the same vain as psacct‘s tracking & reporting approach is auditd. With auditd you can query to find out who and for how long program X was run.

                                                            Example

                                                            $ sudo ausearch -x /usr/bin/sudo | head -5
                                                            ----
                                                            time->Sat Dec  7 21:15:15 2013
                                                            type=USER_AUTH msg=audit(1386468915.558:419): pid=2189 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="saml" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
                                                            ----
                                                            time->Sat Dec  7 21:15:15 2013
                                                            

                                                            NOTE: The above is finding all the entries where someone ran the tool /usr/bin/sudo.

                                                            References

                                                            • Chapter 34. Introducing an Audit Rule Set
                                                            • 7.7. Searching the Audit Log Files
                                                            share|improve this answer

                                                              up vote
                                                              1
                                                              down vote

                                                              Using psacct

                                                              The events that you’re looking for can be found through psacct. Specifically I’d take a look at the tool ac which shows accounting information on users. I touch on this in this U&L Q&A titled: Commands for determining level of usage of server.

                                                              NOTE: This is not a subscribe-able “service”, rather a tracking & reporting infrastructure that you can ask it questions.

                                                              You can also use lastcomm (part of psacct, it has several tools in the suite) to find out when a given application was used by user X.

                                                              Example

                                                              $ lastcomm rm
                                                              rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                              rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                              rm                S     root     pts/0      0.00 secs Tue Nov 14 00:38 
                                                              

                                                              You’ll have to dig a bit into psacct but there’s a lot of resources about it on U&L as well as google which should get you what you want.

                                                              Using auditd

                                                              The other tool, in the same vain as psacct‘s tracking & reporting approach is auditd. With auditd you can query to find out who and for how long program X was run.

                                                              Example

                                                              $ sudo ausearch -x /usr/bin/sudo | head -5
                                                              ----
                                                              time->Sat Dec  7 21:15:15 2013
                                                              type=USER_AUTH msg=audit(1386468915.558:419): pid=2189 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="saml" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
                                                              ----
                                                              time->Sat Dec  7 21:15:15 2013
                                                              

                                                              NOTE: The above is finding all the entries where someone ran the tool /usr/bin/sudo.

                                                              References

                                                              • Chapter 34. Introducing an Audit Rule Set
                                                              • 7.7. Searching the Audit Log Files
                                                              share|improve this answer

                                                                up vote
                                                                1
                                                                down vote

                                                                up vote
                                                                1
                                                                down vote

                                                                Using psacct

                                                                The events that you’re looking for can be found through psacct. Specifically I’d take a look at the tool ac which shows accounting information on users. I touch on this in this U&L Q&A titled: Commands for determining level of usage of server.

                                                                NOTE: This is not a subscribe-able “service”, rather a tracking & reporting infrastructure that you can ask it questions.

                                                                You can also use lastcomm (part of psacct, it has several tools in the suite) to find out when a given application was used by user X.

                                                                Example

                                                                $ lastcomm rm
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:38 
                                                                

                                                                You’ll have to dig a bit into psacct but there’s a lot of resources about it on U&L as well as google which should get you what you want.

                                                                Using auditd

                                                                The other tool, in the same vain as psacct‘s tracking & reporting approach is auditd. With auditd you can query to find out who and for how long program X was run.

                                                                Example

                                                                $ sudo ausearch -x /usr/bin/sudo | head -5
                                                                ----
                                                                time->Sat Dec  7 21:15:15 2013
                                                                type=USER_AUTH msg=audit(1386468915.558:419): pid=2189 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="saml" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
                                                                ----
                                                                time->Sat Dec  7 21:15:15 2013
                                                                

                                                                NOTE: The above is finding all the entries where someone ran the tool /usr/bin/sudo.

                                                                References

                                                                • Chapter 34. Introducing an Audit Rule Set
                                                                • 7.7. Searching the Audit Log Files
                                                                share|improve this answer

                                                                Using psacct

                                                                The events that you’re looking for can be found through psacct. Specifically I’d take a look at the tool ac which shows accounting information on users. I touch on this in this U&L Q&A titled: Commands for determining level of usage of server.

                                                                NOTE: This is not a subscribe-able “service”, rather a tracking & reporting infrastructure that you can ask it questions.

                                                                You can also use lastcomm (part of psacct, it has several tools in the suite) to find out when a given application was used by user X.

                                                                Example

                                                                $ lastcomm rm
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:39
                                                                rm                S     root     pts/0      0.00 secs Tue Nov 14 00:38 
                                                                

                                                                You’ll have to dig a bit into psacct but there’s a lot of resources about it on U&L as well as google which should get you what you want.

                                                                Using auditd

                                                                The other tool, in the same vain as psacct‘s tracking & reporting approach is auditd. With auditd you can query to find out who and for how long program X was run.

                                                                Example

                                                                $ sudo ausearch -x /usr/bin/sudo | head -5
                                                                ----
                                                                time->Sat Dec  7 21:15:15 2013
                                                                type=USER_AUTH msg=audit(1386468915.558:419): pid=2189 uid=1000 auid=1000 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:authentication acct="saml" exe="/usr/bin/sudo" hostname=? addr=? terminal=/dev/pts/0 res=success'
                                                                ----
                                                                time->Sat Dec  7 21:15:15 2013
                                                                

                                                                NOTE: The above is finding all the entries where someone ran the tool /usr/bin/sudo.

                                                                References

                                                                • Chapter 34. Introducing an Audit Rule Set
                                                                • 7.7. Searching the Audit Log Files
                                                                share|improve this answer

                                                                share|improve this answer

                                                                share|improve this answer

                                                                edited Nov 28 at 22:51

                                                                answered Jun 2 ’14 at 14:56

                                                                slm

                                                                245k66505671

                                                                245k66505671

                                                                    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.

                                                                    Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

                                                                    Please pay close attention to the following guidance:

                                                                    • 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%2f134107%2fkernel-event-listener%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

                                                                    Is there a way to prevent sigkill to reach a process?

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

                                                                    up vote
                                                                    1
                                                                    down vote

                                                                    favorite

                                                                    1

                                                                    I know that a process cannot prevent SIGKILL.

                                                                    But is there an external way to temporarily prevent SIGKILL to reach a (specific) process? (something like dropping packets by firewalls).

                                                                    share|improve this question

                                                                    • Yes, running the process as another user.
                                                                      – mosvy
                                                                      Nov 24 at 19:15

                                                                    • but still any root owned process can kill it
                                                                      – gopy
                                                                      Nov 24 at 19:19

                                                                    • that’s by design. do you want unkillable processes on your machine?
                                                                      – mosvy
                                                                      Nov 24 at 19:25

                                                                    • 2

                                                                      modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                      – thrig
                                                                      Nov 24 at 19:25

                                                                    • 1

                                                                      @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                      – Stéphane Chazelas
                                                                      Nov 26 at 22:31

                                                                    up vote
                                                                    1
                                                                    down vote

                                                                    favorite

                                                                    1

                                                                    I know that a process cannot prevent SIGKILL.

                                                                    But is there an external way to temporarily prevent SIGKILL to reach a (specific) process? (something like dropping packets by firewalls).

                                                                    share|improve this question

                                                                    • Yes, running the process as another user.
                                                                      – mosvy
                                                                      Nov 24 at 19:15

                                                                    • but still any root owned process can kill it
                                                                      – gopy
                                                                      Nov 24 at 19:19

                                                                    • that’s by design. do you want unkillable processes on your machine?
                                                                      – mosvy
                                                                      Nov 24 at 19:25

                                                                    • 2

                                                                      modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                      – thrig
                                                                      Nov 24 at 19:25

                                                                    • 1

                                                                      @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                      – Stéphane Chazelas
                                                                      Nov 26 at 22:31

                                                                    up vote
                                                                    1
                                                                    down vote

                                                                    favorite

                                                                    1

                                                                    up vote
                                                                    1
                                                                    down vote

                                                                    favorite

                                                                    1
                                                                    1

                                                                    I know that a process cannot prevent SIGKILL.

                                                                    But is there an external way to temporarily prevent SIGKILL to reach a (specific) process? (something like dropping packets by firewalls).

                                                                    share|improve this question

                                                                    I know that a process cannot prevent SIGKILL.

                                                                    But is there an external way to temporarily prevent SIGKILL to reach a (specific) process? (something like dropping packets by firewalls).

                                                                    linux process-management syscalls sigkill

                                                                    share|improve this question

                                                                    share|improve this question

                                                                    share|improve this question

                                                                    share|improve this question

                                                                    edited Nov 25 at 7:08

                                                                    asked Nov 24 at 19:08

                                                                    gopy

                                                                    194

                                                                    194

                                                                    • Yes, running the process as another user.
                                                                      – mosvy
                                                                      Nov 24 at 19:15

                                                                    • but still any root owned process can kill it
                                                                      – gopy
                                                                      Nov 24 at 19:19

                                                                    • that’s by design. do you want unkillable processes on your machine?
                                                                      – mosvy
                                                                      Nov 24 at 19:25

                                                                    • 2

                                                                      modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                      – thrig
                                                                      Nov 24 at 19:25

                                                                    • 1

                                                                      @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                      – Stéphane Chazelas
                                                                      Nov 26 at 22:31

                                                                    • Yes, running the process as another user.
                                                                      – mosvy
                                                                      Nov 24 at 19:15

                                                                    • but still any root owned process can kill it
                                                                      – gopy
                                                                      Nov 24 at 19:19

                                                                    • that’s by design. do you want unkillable processes on your machine?
                                                                      – mosvy
                                                                      Nov 24 at 19:25

                                                                    • 2

                                                                      modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                      – thrig
                                                                      Nov 24 at 19:25

                                                                    • 1

                                                                      @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                      – Stéphane Chazelas
                                                                      Nov 26 at 22:31

                                                                    Yes, running the process as another user.
                                                                    – mosvy
                                                                    Nov 24 at 19:15

                                                                    Yes, running the process as another user.
                                                                    – mosvy
                                                                    Nov 24 at 19:15

                                                                    but still any root owned process can kill it
                                                                    – gopy
                                                                    Nov 24 at 19:19

                                                                    but still any root owned process can kill it
                                                                    – gopy
                                                                    Nov 24 at 19:19

                                                                    that’s by design. do you want unkillable processes on your machine?
                                                                    – mosvy
                                                                    Nov 24 at 19:25

                                                                    that’s by design. do you want unkillable processes on your machine?
                                                                    – mosvy
                                                                    Nov 24 at 19:25

                                                                    2

                                                                    2

                                                                    modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                    – thrig
                                                                    Nov 24 at 19:25

                                                                    modify the kernel to implement the behavior you want (this would be a bad idea—why do you want to prevent a KILL signal?)
                                                                    – thrig
                                                                    Nov 24 at 19:25

                                                                    1

                                                                    1

                                                                    @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                    – Stéphane Chazelas
                                                                    Nov 26 at 22:31

                                                                    @mosvy, it should be pretty easy with systemtap. LSMs would be seen as an equivalent of the firewall the OP is mentioning.
                                                                    – Stéphane Chazelas
                                                                    Nov 26 at 22:31

                                                                    1 Answer
                                                                    1

                                                                    active

                                                                    oldest

                                                                    votes

                                                                    up vote
                                                                    4
                                                                    down vote

                                                                    You kill a process by invoking the kill() (or tkill()) system call (the kernel can also kill processes/tasks by itself (like the SIGINT sent upon Ctrl-C or SIGKILL sent by the out-of-memory killer). Some signals may be sent as a result of other system calls like ptrace).

                                                                    When kill() is invoked, it then all happens in the kernel.

                                                                    Only kernel code stands in between the process sending the signal and the process receiving it (and possibly terminate as a consequence).

                                                                    Now there are still a few kernel features that stand in the way and that you may be able to use here:

                                                                    1. the simple Unix permissions. Quoting the kill(2) man page on Linux:

                                                                      For a process to have permission to send a signal, it must either be privileged (under Linux: have the CAP_KILL capability in the user namespace of the target process), or the real or effective user ID of the sending process must equal the real or saved set-user-ID of the target process.

                                                                    2. Linux Security Modules. LSMs can (and do at least for Smack, SELinux and apparmor) filter what may send signals to what.

                                                                    3. Some processes are immune to killing. That’s the case of the process of id 1 (init) on Linux. The root process of other child namespaces is also immune to signals sent by other processes in its namespace. Kernel tasks are also immune to signals.

                                                                    4. And then there are kernel instrumentation mechanisms like that used by SystemTap that allows you to affect the behaviour of the kernel and here could be used to hijack signal delivery.

                                                                    But before getting there, maybe the first thing to try would be to stop whatever is sending that SIGKILL signal from doing it.

                                                                    If it’s to prevent a critical process (for instance one used to support the root file system) to be killed upon shutdown, most init systems will have a way to prevent a given processes to be subject to the killall5 or equivalent that happens then. See the /run/sendsigs.omit.d in some versions of Debian, or the killmode of systemd for instance.

                                                                    The killer process, whatever it it, must have a way to determine which process to kill. If it’s based on the pid of the victim stored in a file (like /run/victim.pid), you can change that file, if it’s based on the process name (/proc/pid/task/tid/comm), that’s also changeable (by attaching a debugger for instance and call prctl(PR_SET_NAME)), same for the arg list (/proc/pid/cmdline shown by ps -f).

                                                                    If the killer process is dynamically linked, you could inject code in it to replace the kill() system call with a wrapper function that refuses to do it for a given pid:

                                                                    #define _GNU_SOURCE
                                                                    #include <dlfcn.h>
                                                                    #include <stdlib.h>
                                                                    #include <sys/types.h>
                                                                    #include <signal.h>
                                                                    #include <errno.h>
                                                                    
                                                                    int kill(pid_t pid, int sig)
                                                                    {
                                                                      static pid_t pid_to_safeguard = 0;
                                                                      static int (*orig_kill)(pid_t, int) = 0;
                                                                    
                                                                      if (!orig_kill)
                                                                        orig_kill = (int (*)(pid_t, int)) dlsym (RTLD_NEXT, "kill");
                                                                    
                                                                      if (!orig_kill) abort();
                                                                    
                                                                      if (!pid_to_safeguard) {
                                                                        char *env = getenv("NOTME");
                                                                        if (env) pid_to_safeguard = atol(env);
                                                                      }
                                                                    
                                                                      if (pid_to_safeguard && pid == pid_to_safeguard) {
                                                                        errno = EPERM;
                                                                        return -1;
                                                                      }
                                                                    
                                                                      return orig_kill(pid, sig);
                                                                    }
                                                                    

                                                                    (you may need to do the same for tkill(), and for the pgid of the victim depending on how the killer actually sends the signal).

                                                                    Compile as:

                                                                    gcc -fPIC -shared -o notme.so notme.c -ldl
                                                                    

                                                                    And run the killer command as:

                                                                    LD_PRELOAD=/path/to/notme.so NOTME=12345 killer args...
                                                                    

                                                                    Or you could hide the process completely by running it in a pid namespace different from (but not a child of) the one for the rest of the system.

                                                                    If none of those are an option, then we can go through our list above to prevent the signal from being delivered:

                                                                    1. Run the victim as a different user from the killer (assuming the killer is not running as root)
                                                                    2. Use a LSM. For instance, when using Smack (boot with security=smack as kernel parameter), setting a different label for the victim process would be enough for other processes not to be able to see it, let alone kill it. For instance:

                                                                      sudo zsh -c 'echo unkillable > /proc/self/attr/current && exec sleep 1000'
                                                                      

                                                                      would have sleep run in that unkillable domain (the name could be anything, the point is there’s no currently defined rule that allows anyway to interfere with that domain) and even processes running as the same uid wouldn’t be able to kill it. root would though.

                                                                    3. If you start your victim process as the leader of a new pid namespace, then it would be immune from its descendants.

                                                                      ~$ sudo unshare -p --fork --mount-proc zsh
                                                                      ~# kill -s KILL "$$"
                                                                      ~#
                                                                      

                                                                      (still there).

                                                                    4. SystemTap could be used here. Note however that you need kernel symbols (linux-image-<version>-dbgsym on Debian) to be able to use it, and the SystemTap or the internal kernel functions that your stap script will hook into are potentially subject to change. So maybe not the most stable of options. The Guru mode should also be used with care (don’t try doing anything too fancy).

                                                                      With stap, you can inject code at different points in the running kernel. For instance, you could hook into the kernel function that handles the kill() or tkill() system call and tell it change the signal to 0 (harmless) when the pid is that of your victim.

                                                                      stap -ge 'probe kernel.function("sys_kill") { if ($pid == 12345) $sig = 0; }'
                                                                      

                                                                      (here for any signal, you can also check for $sig == 9 if you only want to cover SIGKILL). Now, that doesn’t work when tkill() is used or when kill() is called with the process group id of the victim, so we’d need to extend that. That doesn’t cover the cases where the signal is sent by the kernel itself.

                                                                      But we can also look at the kernel code and see if we can hook ourself in the place where the kernel checks for permission to send the signal.

                                                                      stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                                 if (@entry($t->pid) == 12345) $return = -1; }'
                                                                      

                                                                      We return -1 (-EPERM) which has also the benefit of letting the killer know its kill() failed, when the requested pid is that of our target (here 12345 as an example).

                                                                      ~$ sleep 1000 &
                                                                      [1] 8508
                                                                      ~$ sudo stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                        if (@entry($t->pid) == '"$!"') $return = -1; }' &
                                                                      [2] 8510
                                                                      ~$ kill -s KILL 8508
                                                                      kill: kill 8508 failed: operation not permitted
                                                                      

                                                                      it also works for some of the cases where the kernel sends a signal by itself, but not all. For that, we’d need to go down to the bottom-most function that does the signal delivery in the kernel code: __send_signal() (at least in current versions of the Linux kernel).

                                                                      One way would be to hook into the prepare_signal() function that that __send_signal() calls at the beginning (and bails out if it returns 0);

                                                                      stap -ge 'probe kernel.function("prepare_signal").return {
                                                                        if (@entry($p->pid) == 12345) $return = 0; }'
                                                                      

                                                                      Then that pid 12345 would be unkillable as long as that stap process lives.

                                                                      Note that the kernel generally assumes SIGKILL would work, so it’s not impossible that the above would have unexpected side effects in some corner cases (like the oom-killer being rendered ineffective if it keeps picking your unkillable victim).

                                                                    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: 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%2f483913%2fis-there-a-way-to-prevent-sigkill-to-reach-a-process%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

                                                                      up vote
                                                                      4
                                                                      down vote

                                                                      You kill a process by invoking the kill() (or tkill()) system call (the kernel can also kill processes/tasks by itself (like the SIGINT sent upon Ctrl-C or SIGKILL sent by the out-of-memory killer). Some signals may be sent as a result of other system calls like ptrace).

                                                                      When kill() is invoked, it then all happens in the kernel.

                                                                      Only kernel code stands in between the process sending the signal and the process receiving it (and possibly terminate as a consequence).

                                                                      Now there are still a few kernel features that stand in the way and that you may be able to use here:

                                                                      1. the simple Unix permissions. Quoting the kill(2) man page on Linux:

                                                                        For a process to have permission to send a signal, it must either be privileged (under Linux: have the CAP_KILL capability in the user namespace of the target process), or the real or effective user ID of the sending process must equal the real or saved set-user-ID of the target process.

                                                                      2. Linux Security Modules. LSMs can (and do at least for Smack, SELinux and apparmor) filter what may send signals to what.

                                                                      3. Some processes are immune to killing. That’s the case of the process of id 1 (init) on Linux. The root process of other child namespaces is also immune to signals sent by other processes in its namespace. Kernel tasks are also immune to signals.

                                                                      4. And then there are kernel instrumentation mechanisms like that used by SystemTap that allows you to affect the behaviour of the kernel and here could be used to hijack signal delivery.

                                                                      But before getting there, maybe the first thing to try would be to stop whatever is sending that SIGKILL signal from doing it.

                                                                      If it’s to prevent a critical process (for instance one used to support the root file system) to be killed upon shutdown, most init systems will have a way to prevent a given processes to be subject to the killall5 or equivalent that happens then. See the /run/sendsigs.omit.d in some versions of Debian, or the killmode of systemd for instance.

                                                                      The killer process, whatever it it, must have a way to determine which process to kill. If it’s based on the pid of the victim stored in a file (like /run/victim.pid), you can change that file, if it’s based on the process name (/proc/pid/task/tid/comm), that’s also changeable (by attaching a debugger for instance and call prctl(PR_SET_NAME)), same for the arg list (/proc/pid/cmdline shown by ps -f).

                                                                      If the killer process is dynamically linked, you could inject code in it to replace the kill() system call with a wrapper function that refuses to do it for a given pid:

                                                                      #define _GNU_SOURCE
                                                                      #include <dlfcn.h>
                                                                      #include <stdlib.h>
                                                                      #include <sys/types.h>
                                                                      #include <signal.h>
                                                                      #include <errno.h>
                                                                      
                                                                      int kill(pid_t pid, int sig)
                                                                      {
                                                                        static pid_t pid_to_safeguard = 0;
                                                                        static int (*orig_kill)(pid_t, int) = 0;
                                                                      
                                                                        if (!orig_kill)
                                                                          orig_kill = (int (*)(pid_t, int)) dlsym (RTLD_NEXT, "kill");
                                                                      
                                                                        if (!orig_kill) abort();
                                                                      
                                                                        if (!pid_to_safeguard) {
                                                                          char *env = getenv("NOTME");
                                                                          if (env) pid_to_safeguard = atol(env);
                                                                        }
                                                                      
                                                                        if (pid_to_safeguard && pid == pid_to_safeguard) {
                                                                          errno = EPERM;
                                                                          return -1;
                                                                        }
                                                                      
                                                                        return orig_kill(pid, sig);
                                                                      }
                                                                      

                                                                      (you may need to do the same for tkill(), and for the pgid of the victim depending on how the killer actually sends the signal).

                                                                      Compile as:

                                                                      gcc -fPIC -shared -o notme.so notme.c -ldl
                                                                      

                                                                      And run the killer command as:

                                                                      LD_PRELOAD=/path/to/notme.so NOTME=12345 killer args...
                                                                      

                                                                      Or you could hide the process completely by running it in a pid namespace different from (but not a child of) the one for the rest of the system.

                                                                      If none of those are an option, then we can go through our list above to prevent the signal from being delivered:

                                                                      1. Run the victim as a different user from the killer (assuming the killer is not running as root)
                                                                      2. Use a LSM. For instance, when using Smack (boot with security=smack as kernel parameter), setting a different label for the victim process would be enough for other processes not to be able to see it, let alone kill it. For instance:

                                                                        sudo zsh -c 'echo unkillable > /proc/self/attr/current && exec sleep 1000'
                                                                        

                                                                        would have sleep run in that unkillable domain (the name could be anything, the point is there’s no currently defined rule that allows anyway to interfere with that domain) and even processes running as the same uid wouldn’t be able to kill it. root would though.

                                                                      3. If you start your victim process as the leader of a new pid namespace, then it would be immune from its descendants.

                                                                        ~$ sudo unshare -p --fork --mount-proc zsh
                                                                        ~# kill -s KILL "$$"
                                                                        ~#
                                                                        

                                                                        (still there).

                                                                      4. SystemTap could be used here. Note however that you need kernel symbols (linux-image-<version>-dbgsym on Debian) to be able to use it, and the SystemTap or the internal kernel functions that your stap script will hook into are potentially subject to change. So maybe not the most stable of options. The Guru mode should also be used with care (don’t try doing anything too fancy).

                                                                        With stap, you can inject code at different points in the running kernel. For instance, you could hook into the kernel function that handles the kill() or tkill() system call and tell it change the signal to 0 (harmless) when the pid is that of your victim.

                                                                        stap -ge 'probe kernel.function("sys_kill") { if ($pid == 12345) $sig = 0; }'
                                                                        

                                                                        (here for any signal, you can also check for $sig == 9 if you only want to cover SIGKILL). Now, that doesn’t work when tkill() is used or when kill() is called with the process group id of the victim, so we’d need to extend that. That doesn’t cover the cases where the signal is sent by the kernel itself.

                                                                        But we can also look at the kernel code and see if we can hook ourself in the place where the kernel checks for permission to send the signal.

                                                                        stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                                   if (@entry($t->pid) == 12345) $return = -1; }'
                                                                        

                                                                        We return -1 (-EPERM) which has also the benefit of letting the killer know its kill() failed, when the requested pid is that of our target (here 12345 as an example).

                                                                        ~$ sleep 1000 &
                                                                        [1] 8508
                                                                        ~$ sudo stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                          if (@entry($t->pid) == '"$!"') $return = -1; }' &
                                                                        [2] 8510
                                                                        ~$ kill -s KILL 8508
                                                                        kill: kill 8508 failed: operation not permitted
                                                                        

                                                                        it also works for some of the cases where the kernel sends a signal by itself, but not all. For that, we’d need to go down to the bottom-most function that does the signal delivery in the kernel code: __send_signal() (at least in current versions of the Linux kernel).

                                                                        One way would be to hook into the prepare_signal() function that that __send_signal() calls at the beginning (and bails out if it returns 0);

                                                                        stap -ge 'probe kernel.function("prepare_signal").return {
                                                                          if (@entry($p->pid) == 12345) $return = 0; }'
                                                                        

                                                                        Then that pid 12345 would be unkillable as long as that stap process lives.

                                                                        Note that the kernel generally assumes SIGKILL would work, so it’s not impossible that the above would have unexpected side effects in some corner cases (like the oom-killer being rendered ineffective if it keeps picking your unkillable victim).

                                                                      share|improve this answer

                                                                        up vote
                                                                        4
                                                                        down vote

                                                                        You kill a process by invoking the kill() (or tkill()) system call (the kernel can also kill processes/tasks by itself (like the SIGINT sent upon Ctrl-C or SIGKILL sent by the out-of-memory killer). Some signals may be sent as a result of other system calls like ptrace).

                                                                        When kill() is invoked, it then all happens in the kernel.

                                                                        Only kernel code stands in between the process sending the signal and the process receiving it (and possibly terminate as a consequence).

                                                                        Now there are still a few kernel features that stand in the way and that you may be able to use here:

                                                                        1. the simple Unix permissions. Quoting the kill(2) man page on Linux:

                                                                          For a process to have permission to send a signal, it must either be privileged (under Linux: have the CAP_KILL capability in the user namespace of the target process), or the real or effective user ID of the sending process must equal the real or saved set-user-ID of the target process.

                                                                        2. Linux Security Modules. LSMs can (and do at least for Smack, SELinux and apparmor) filter what may send signals to what.

                                                                        3. Some processes are immune to killing. That’s the case of the process of id 1 (init) on Linux. The root process of other child namespaces is also immune to signals sent by other processes in its namespace. Kernel tasks are also immune to signals.

                                                                        4. And then there are kernel instrumentation mechanisms like that used by SystemTap that allows you to affect the behaviour of the kernel and here could be used to hijack signal delivery.

                                                                        But before getting there, maybe the first thing to try would be to stop whatever is sending that SIGKILL signal from doing it.

                                                                        If it’s to prevent a critical process (for instance one used to support the root file system) to be killed upon shutdown, most init systems will have a way to prevent a given processes to be subject to the killall5 or equivalent that happens then. See the /run/sendsigs.omit.d in some versions of Debian, or the killmode of systemd for instance.

                                                                        The killer process, whatever it it, must have a way to determine which process to kill. If it’s based on the pid of the victim stored in a file (like /run/victim.pid), you can change that file, if it’s based on the process name (/proc/pid/task/tid/comm), that’s also changeable (by attaching a debugger for instance and call prctl(PR_SET_NAME)), same for the arg list (/proc/pid/cmdline shown by ps -f).

                                                                        If the killer process is dynamically linked, you could inject code in it to replace the kill() system call with a wrapper function that refuses to do it for a given pid:

                                                                        #define _GNU_SOURCE
                                                                        #include <dlfcn.h>
                                                                        #include <stdlib.h>
                                                                        #include <sys/types.h>
                                                                        #include <signal.h>
                                                                        #include <errno.h>
                                                                        
                                                                        int kill(pid_t pid, int sig)
                                                                        {
                                                                          static pid_t pid_to_safeguard = 0;
                                                                          static int (*orig_kill)(pid_t, int) = 0;
                                                                        
                                                                          if (!orig_kill)
                                                                            orig_kill = (int (*)(pid_t, int)) dlsym (RTLD_NEXT, "kill");
                                                                        
                                                                          if (!orig_kill) abort();
                                                                        
                                                                          if (!pid_to_safeguard) {
                                                                            char *env = getenv("NOTME");
                                                                            if (env) pid_to_safeguard = atol(env);
                                                                          }
                                                                        
                                                                          if (pid_to_safeguard && pid == pid_to_safeguard) {
                                                                            errno = EPERM;
                                                                            return -1;
                                                                          }
                                                                        
                                                                          return orig_kill(pid, sig);
                                                                        }
                                                                        

                                                                        (you may need to do the same for tkill(), and for the pgid of the victim depending on how the killer actually sends the signal).

                                                                        Compile as:

                                                                        gcc -fPIC -shared -o notme.so notme.c -ldl
                                                                        

                                                                        And run the killer command as:

                                                                        LD_PRELOAD=/path/to/notme.so NOTME=12345 killer args...
                                                                        

                                                                        Or you could hide the process completely by running it in a pid namespace different from (but not a child of) the one for the rest of the system.

                                                                        If none of those are an option, then we can go through our list above to prevent the signal from being delivered:

                                                                        1. Run the victim as a different user from the killer (assuming the killer is not running as root)
                                                                        2. Use a LSM. For instance, when using Smack (boot with security=smack as kernel parameter), setting a different label for the victim process would be enough for other processes not to be able to see it, let alone kill it. For instance:

                                                                          sudo zsh -c 'echo unkillable > /proc/self/attr/current && exec sleep 1000'
                                                                          

                                                                          would have sleep run in that unkillable domain (the name could be anything, the point is there’s no currently defined rule that allows anyway to interfere with that domain) and even processes running as the same uid wouldn’t be able to kill it. root would though.

                                                                        3. If you start your victim process as the leader of a new pid namespace, then it would be immune from its descendants.

                                                                          ~$ sudo unshare -p --fork --mount-proc zsh
                                                                          ~# kill -s KILL "$$"
                                                                          ~#
                                                                          

                                                                          (still there).

                                                                        4. SystemTap could be used here. Note however that you need kernel symbols (linux-image-<version>-dbgsym on Debian) to be able to use it, and the SystemTap or the internal kernel functions that your stap script will hook into are potentially subject to change. So maybe not the most stable of options. The Guru mode should also be used with care (don’t try doing anything too fancy).

                                                                          With stap, you can inject code at different points in the running kernel. For instance, you could hook into the kernel function that handles the kill() or tkill() system call and tell it change the signal to 0 (harmless) when the pid is that of your victim.

                                                                          stap -ge 'probe kernel.function("sys_kill") { if ($pid == 12345) $sig = 0; }'
                                                                          

                                                                          (here for any signal, you can also check for $sig == 9 if you only want to cover SIGKILL). Now, that doesn’t work when tkill() is used or when kill() is called with the process group id of the victim, so we’d need to extend that. That doesn’t cover the cases where the signal is sent by the kernel itself.

                                                                          But we can also look at the kernel code and see if we can hook ourself in the place where the kernel checks for permission to send the signal.

                                                                          stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                                     if (@entry($t->pid) == 12345) $return = -1; }'
                                                                          

                                                                          We return -1 (-EPERM) which has also the benefit of letting the killer know its kill() failed, when the requested pid is that of our target (here 12345 as an example).

                                                                          ~$ sleep 1000 &
                                                                          [1] 8508
                                                                          ~$ sudo stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                            if (@entry($t->pid) == '"$!"') $return = -1; }' &
                                                                          [2] 8510
                                                                          ~$ kill -s KILL 8508
                                                                          kill: kill 8508 failed: operation not permitted
                                                                          

                                                                          it also works for some of the cases where the kernel sends a signal by itself, but not all. For that, we’d need to go down to the bottom-most function that does the signal delivery in the kernel code: __send_signal() (at least in current versions of the Linux kernel).

                                                                          One way would be to hook into the prepare_signal() function that that __send_signal() calls at the beginning (and bails out if it returns 0);

                                                                          stap -ge 'probe kernel.function("prepare_signal").return {
                                                                            if (@entry($p->pid) == 12345) $return = 0; }'
                                                                          

                                                                          Then that pid 12345 would be unkillable as long as that stap process lives.

                                                                          Note that the kernel generally assumes SIGKILL would work, so it’s not impossible that the above would have unexpected side effects in some corner cases (like the oom-killer being rendered ineffective if it keeps picking your unkillable victim).

                                                                        share|improve this answer

                                                                          up vote
                                                                          4
                                                                          down vote

                                                                          up vote
                                                                          4
                                                                          down vote

                                                                          You kill a process by invoking the kill() (or tkill()) system call (the kernel can also kill processes/tasks by itself (like the SIGINT sent upon Ctrl-C or SIGKILL sent by the out-of-memory killer). Some signals may be sent as a result of other system calls like ptrace).

                                                                          When kill() is invoked, it then all happens in the kernel.

                                                                          Only kernel code stands in between the process sending the signal and the process receiving it (and possibly terminate as a consequence).

                                                                          Now there are still a few kernel features that stand in the way and that you may be able to use here:

                                                                          1. the simple Unix permissions. Quoting the kill(2) man page on Linux:

                                                                            For a process to have permission to send a signal, it must either be privileged (under Linux: have the CAP_KILL capability in the user namespace of the target process), or the real or effective user ID of the sending process must equal the real or saved set-user-ID of the target process.

                                                                          2. Linux Security Modules. LSMs can (and do at least for Smack, SELinux and apparmor) filter what may send signals to what.

                                                                          3. Some processes are immune to killing. That’s the case of the process of id 1 (init) on Linux. The root process of other child namespaces is also immune to signals sent by other processes in its namespace. Kernel tasks are also immune to signals.

                                                                          4. And then there are kernel instrumentation mechanisms like that used by SystemTap that allows you to affect the behaviour of the kernel and here could be used to hijack signal delivery.

                                                                          But before getting there, maybe the first thing to try would be to stop whatever is sending that SIGKILL signal from doing it.

                                                                          If it’s to prevent a critical process (for instance one used to support the root file system) to be killed upon shutdown, most init systems will have a way to prevent a given processes to be subject to the killall5 or equivalent that happens then. See the /run/sendsigs.omit.d in some versions of Debian, or the killmode of systemd for instance.

                                                                          The killer process, whatever it it, must have a way to determine which process to kill. If it’s based on the pid of the victim stored in a file (like /run/victim.pid), you can change that file, if it’s based on the process name (/proc/pid/task/tid/comm), that’s also changeable (by attaching a debugger for instance and call prctl(PR_SET_NAME)), same for the arg list (/proc/pid/cmdline shown by ps -f).

                                                                          If the killer process is dynamically linked, you could inject code in it to replace the kill() system call with a wrapper function that refuses to do it for a given pid:

                                                                          #define _GNU_SOURCE
                                                                          #include <dlfcn.h>
                                                                          #include <stdlib.h>
                                                                          #include <sys/types.h>
                                                                          #include <signal.h>
                                                                          #include <errno.h>
                                                                          
                                                                          int kill(pid_t pid, int sig)
                                                                          {
                                                                            static pid_t pid_to_safeguard = 0;
                                                                            static int (*orig_kill)(pid_t, int) = 0;
                                                                          
                                                                            if (!orig_kill)
                                                                              orig_kill = (int (*)(pid_t, int)) dlsym (RTLD_NEXT, "kill");
                                                                          
                                                                            if (!orig_kill) abort();
                                                                          
                                                                            if (!pid_to_safeguard) {
                                                                              char *env = getenv("NOTME");
                                                                              if (env) pid_to_safeguard = atol(env);
                                                                            }
                                                                          
                                                                            if (pid_to_safeguard && pid == pid_to_safeguard) {
                                                                              errno = EPERM;
                                                                              return -1;
                                                                            }
                                                                          
                                                                            return orig_kill(pid, sig);
                                                                          }
                                                                          

                                                                          (you may need to do the same for tkill(), and for the pgid of the victim depending on how the killer actually sends the signal).

                                                                          Compile as:

                                                                          gcc -fPIC -shared -o notme.so notme.c -ldl
                                                                          

                                                                          And run the killer command as:

                                                                          LD_PRELOAD=/path/to/notme.so NOTME=12345 killer args...
                                                                          

                                                                          Or you could hide the process completely by running it in a pid namespace different from (but not a child of) the one for the rest of the system.

                                                                          If none of those are an option, then we can go through our list above to prevent the signal from being delivered:

                                                                          1. Run the victim as a different user from the killer (assuming the killer is not running as root)
                                                                          2. Use a LSM. For instance, when using Smack (boot with security=smack as kernel parameter), setting a different label for the victim process would be enough for other processes not to be able to see it, let alone kill it. For instance:

                                                                            sudo zsh -c 'echo unkillable > /proc/self/attr/current && exec sleep 1000'
                                                                            

                                                                            would have sleep run in that unkillable domain (the name could be anything, the point is there’s no currently defined rule that allows anyway to interfere with that domain) and even processes running as the same uid wouldn’t be able to kill it. root would though.

                                                                          3. If you start your victim process as the leader of a new pid namespace, then it would be immune from its descendants.

                                                                            ~$ sudo unshare -p --fork --mount-proc zsh
                                                                            ~# kill -s KILL "$$"
                                                                            ~#
                                                                            

                                                                            (still there).

                                                                          4. SystemTap could be used here. Note however that you need kernel symbols (linux-image-<version>-dbgsym on Debian) to be able to use it, and the SystemTap or the internal kernel functions that your stap script will hook into are potentially subject to change. So maybe not the most stable of options. The Guru mode should also be used with care (don’t try doing anything too fancy).

                                                                            With stap, you can inject code at different points in the running kernel. For instance, you could hook into the kernel function that handles the kill() or tkill() system call and tell it change the signal to 0 (harmless) when the pid is that of your victim.

                                                                            stap -ge 'probe kernel.function("sys_kill") { if ($pid == 12345) $sig = 0; }'
                                                                            

                                                                            (here for any signal, you can also check for $sig == 9 if you only want to cover SIGKILL). Now, that doesn’t work when tkill() is used or when kill() is called with the process group id of the victim, so we’d need to extend that. That doesn’t cover the cases where the signal is sent by the kernel itself.

                                                                            But we can also look at the kernel code and see if we can hook ourself in the place where the kernel checks for permission to send the signal.

                                                                            stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                                       if (@entry($t->pid) == 12345) $return = -1; }'
                                                                            

                                                                            We return -1 (-EPERM) which has also the benefit of letting the killer know its kill() failed, when the requested pid is that of our target (here 12345 as an example).

                                                                            ~$ sleep 1000 &
                                                                            [1] 8508
                                                                            ~$ sudo stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                              if (@entry($t->pid) == '"$!"') $return = -1; }' &
                                                                            [2] 8510
                                                                            ~$ kill -s KILL 8508
                                                                            kill: kill 8508 failed: operation not permitted
                                                                            

                                                                            it also works for some of the cases where the kernel sends a signal by itself, but not all. For that, we’d need to go down to the bottom-most function that does the signal delivery in the kernel code: __send_signal() (at least in current versions of the Linux kernel).

                                                                            One way would be to hook into the prepare_signal() function that that __send_signal() calls at the beginning (and bails out if it returns 0);

                                                                            stap -ge 'probe kernel.function("prepare_signal").return {
                                                                              if (@entry($p->pid) == 12345) $return = 0; }'
                                                                            

                                                                            Then that pid 12345 would be unkillable as long as that stap process lives.

                                                                            Note that the kernel generally assumes SIGKILL would work, so it’s not impossible that the above would have unexpected side effects in some corner cases (like the oom-killer being rendered ineffective if it keeps picking your unkillable victim).

                                                                          share|improve this answer

                                                                          You kill a process by invoking the kill() (or tkill()) system call (the kernel can also kill processes/tasks by itself (like the SIGINT sent upon Ctrl-C or SIGKILL sent by the out-of-memory killer). Some signals may be sent as a result of other system calls like ptrace).

                                                                          When kill() is invoked, it then all happens in the kernel.

                                                                          Only kernel code stands in between the process sending the signal and the process receiving it (and possibly terminate as a consequence).

                                                                          Now there are still a few kernel features that stand in the way and that you may be able to use here:

                                                                          1. the simple Unix permissions. Quoting the kill(2) man page on Linux:

                                                                            For a process to have permission to send a signal, it must either be privileged (under Linux: have the CAP_KILL capability in the user namespace of the target process), or the real or effective user ID of the sending process must equal the real or saved set-user-ID of the target process.

                                                                          2. Linux Security Modules. LSMs can (and do at least for Smack, SELinux and apparmor) filter what may send signals to what.

                                                                          3. Some processes are immune to killing. That’s the case of the process of id 1 (init) on Linux. The root process of other child namespaces is also immune to signals sent by other processes in its namespace. Kernel tasks are also immune to signals.

                                                                          4. And then there are kernel instrumentation mechanisms like that used by SystemTap that allows you to affect the behaviour of the kernel and here could be used to hijack signal delivery.

                                                                          But before getting there, maybe the first thing to try would be to stop whatever is sending that SIGKILL signal from doing it.

                                                                          If it’s to prevent a critical process (for instance one used to support the root file system) to be killed upon shutdown, most init systems will have a way to prevent a given processes to be subject to the killall5 or equivalent that happens then. See the /run/sendsigs.omit.d in some versions of Debian, or the killmode of systemd for instance.

                                                                          The killer process, whatever it it, must have a way to determine which process to kill. If it’s based on the pid of the victim stored in a file (like /run/victim.pid), you can change that file, if it’s based on the process name (/proc/pid/task/tid/comm), that’s also changeable (by attaching a debugger for instance and call prctl(PR_SET_NAME)), same for the arg list (/proc/pid/cmdline shown by ps -f).

                                                                          If the killer process is dynamically linked, you could inject code in it to replace the kill() system call with a wrapper function that refuses to do it for a given pid:

                                                                          #define _GNU_SOURCE
                                                                          #include <dlfcn.h>
                                                                          #include <stdlib.h>
                                                                          #include <sys/types.h>
                                                                          #include <signal.h>
                                                                          #include <errno.h>
                                                                          
                                                                          int kill(pid_t pid, int sig)
                                                                          {
                                                                            static pid_t pid_to_safeguard = 0;
                                                                            static int (*orig_kill)(pid_t, int) = 0;
                                                                          
                                                                            if (!orig_kill)
                                                                              orig_kill = (int (*)(pid_t, int)) dlsym (RTLD_NEXT, "kill");
                                                                          
                                                                            if (!orig_kill) abort();
                                                                          
                                                                            if (!pid_to_safeguard) {
                                                                              char *env = getenv("NOTME");
                                                                              if (env) pid_to_safeguard = atol(env);
                                                                            }
                                                                          
                                                                            if (pid_to_safeguard && pid == pid_to_safeguard) {
                                                                              errno = EPERM;
                                                                              return -1;
                                                                            }
                                                                          
                                                                            return orig_kill(pid, sig);
                                                                          }
                                                                          

                                                                          (you may need to do the same for tkill(), and for the pgid of the victim depending on how the killer actually sends the signal).

                                                                          Compile as:

                                                                          gcc -fPIC -shared -o notme.so notme.c -ldl
                                                                          

                                                                          And run the killer command as:

                                                                          LD_PRELOAD=/path/to/notme.so NOTME=12345 killer args...
                                                                          

                                                                          Or you could hide the process completely by running it in a pid namespace different from (but not a child of) the one for the rest of the system.

                                                                          If none of those are an option, then we can go through our list above to prevent the signal from being delivered:

                                                                          1. Run the victim as a different user from the killer (assuming the killer is not running as root)
                                                                          2. Use a LSM. For instance, when using Smack (boot with security=smack as kernel parameter), setting a different label for the victim process would be enough for other processes not to be able to see it, let alone kill it. For instance:

                                                                            sudo zsh -c 'echo unkillable > /proc/self/attr/current && exec sleep 1000'
                                                                            

                                                                            would have sleep run in that unkillable domain (the name could be anything, the point is there’s no currently defined rule that allows anyway to interfere with that domain) and even processes running as the same uid wouldn’t be able to kill it. root would though.

                                                                          3. If you start your victim process as the leader of a new pid namespace, then it would be immune from its descendants.

                                                                            ~$ sudo unshare -p --fork --mount-proc zsh
                                                                            ~# kill -s KILL "$$"
                                                                            ~#
                                                                            

                                                                            (still there).

                                                                          4. SystemTap could be used here. Note however that you need kernel symbols (linux-image-<version>-dbgsym on Debian) to be able to use it, and the SystemTap or the internal kernel functions that your stap script will hook into are potentially subject to change. So maybe not the most stable of options. The Guru mode should also be used with care (don’t try doing anything too fancy).

                                                                            With stap, you can inject code at different points in the running kernel. For instance, you could hook into the kernel function that handles the kill() or tkill() system call and tell it change the signal to 0 (harmless) when the pid is that of your victim.

                                                                            stap -ge 'probe kernel.function("sys_kill") { if ($pid == 12345) $sig = 0; }'
                                                                            

                                                                            (here for any signal, you can also check for $sig == 9 if you only want to cover SIGKILL). Now, that doesn’t work when tkill() is used or when kill() is called with the process group id of the victim, so we’d need to extend that. That doesn’t cover the cases where the signal is sent by the kernel itself.

                                                                            But we can also look at the kernel code and see if we can hook ourself in the place where the kernel checks for permission to send the signal.

                                                                            stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                                       if (@entry($t->pid) == 12345) $return = -1; }'
                                                                            

                                                                            We return -1 (-EPERM) which has also the benefit of letting the killer know its kill() failed, when the requested pid is that of our target (here 12345 as an example).

                                                                            ~$ sleep 1000 &
                                                                            [1] 8508
                                                                            ~$ sudo stap -ge 'probe kernel.function("check_kill_permission").return {
                                                                              if (@entry($t->pid) == '"$!"') $return = -1; }' &
                                                                            [2] 8510
                                                                            ~$ kill -s KILL 8508
                                                                            kill: kill 8508 failed: operation not permitted
                                                                            

                                                                            it also works for some of the cases where the kernel sends a signal by itself, but not all. For that, we’d need to go down to the bottom-most function that does the signal delivery in the kernel code: __send_signal() (at least in current versions of the Linux kernel).

                                                                            One way would be to hook into the prepare_signal() function that that __send_signal() calls at the beginning (and bails out if it returns 0);

                                                                            stap -ge 'probe kernel.function("prepare_signal").return {
                                                                              if (@entry($p->pid) == 12345) $return = 0; }'
                                                                            

                                                                            Then that pid 12345 would be unkillable as long as that stap process lives.

                                                                            Note that the kernel generally assumes SIGKILL would work, so it’s not impossible that the above would have unexpected side effects in some corner cases (like the oom-killer being rendered ineffective if it keeps picking your unkillable victim).

                                                                          share|improve this answer

                                                                          share|improve this answer

                                                                          share|improve this answer

                                                                          edited Nov 27 at 14:12

                                                                          answered Nov 27 at 14:00

                                                                          Stéphane Chazelas

                                                                          295k54559902

                                                                          295k54559902

                                                                              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.

                                                                              Some of your past answers have not been well-received, and you’re in danger of being blocked from answering.

                                                                              Please pay close attention to the following guidance:

                                                                              • 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%2f483913%2fis-there-a-way-to-prevent-sigkill-to-reach-a-process%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