Which PID belongs into the systemd PIDFile section when creating a shell script daemon?

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





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
1
down vote

favorite












I've created a shell script daemon, based on the code of this answer. I've written a systemd service file with the following contents:



[Unit]
Description=My Daemon
After=network.target

[Service]
Type=forking
PIDFile=/run/daemon.pid
ExecStart=/root/bin/daemon.sh
ExecReload=/bin/kill -1 -- $MAINPID
ExecStop=/bin/kill -- $MAINPID
TimeoutStopSec=5
KillMode=process

[Install]
WantedBy=multi-user.target


Just before the while loop starts, I'm creating a PID file (it is going to be created by the daemon, not by the child, or the parent, because they don't come to this point): echo $$ > /run/daemon.pid;. It works fine, but each time I call systemctl status daemon.service, I get the following warning:



daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory


If I insert the PID creaton statement echo $$ > /run/daemon.pid; at the very beginning of the script (which will be used by the children and parent, too), I get the following warning:



daemon.service: PID 30631 read from file /run/daemon.pid does not exist or is a zombie.


What would be the best approach for creating the PID file without getting any warning messages by systemd?







share|improve this question

























    up vote
    1
    down vote

    favorite












    I've created a shell script daemon, based on the code of this answer. I've written a systemd service file with the following contents:



    [Unit]
    Description=My Daemon
    After=network.target

    [Service]
    Type=forking
    PIDFile=/run/daemon.pid
    ExecStart=/root/bin/daemon.sh
    ExecReload=/bin/kill -1 -- $MAINPID
    ExecStop=/bin/kill -- $MAINPID
    TimeoutStopSec=5
    KillMode=process

    [Install]
    WantedBy=multi-user.target


    Just before the while loop starts, I'm creating a PID file (it is going to be created by the daemon, not by the child, or the parent, because they don't come to this point): echo $$ > /run/daemon.pid;. It works fine, but each time I call systemctl status daemon.service, I get the following warning:



    daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory


    If I insert the PID creaton statement echo $$ > /run/daemon.pid; at the very beginning of the script (which will be used by the children and parent, too), I get the following warning:



    daemon.service: PID 30631 read from file /run/daemon.pid does not exist or is a zombie.


    What would be the best approach for creating the PID file without getting any warning messages by systemd?







    share|improve this question





















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I've created a shell script daemon, based on the code of this answer. I've written a systemd service file with the following contents:



      [Unit]
      Description=My Daemon
      After=network.target

      [Service]
      Type=forking
      PIDFile=/run/daemon.pid
      ExecStart=/root/bin/daemon.sh
      ExecReload=/bin/kill -1 -- $MAINPID
      ExecStop=/bin/kill -- $MAINPID
      TimeoutStopSec=5
      KillMode=process

      [Install]
      WantedBy=multi-user.target


      Just before the while loop starts, I'm creating a PID file (it is going to be created by the daemon, not by the child, or the parent, because they don't come to this point): echo $$ > /run/daemon.pid;. It works fine, but each time I call systemctl status daemon.service, I get the following warning:



      daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory


      If I insert the PID creaton statement echo $$ > /run/daemon.pid; at the very beginning of the script (which will be used by the children and parent, too), I get the following warning:



      daemon.service: PID 30631 read from file /run/daemon.pid does not exist or is a zombie.


      What would be the best approach for creating the PID file without getting any warning messages by systemd?







      share|improve this question











      I've created a shell script daemon, based on the code of this answer. I've written a systemd service file with the following contents:



      [Unit]
      Description=My Daemon
      After=network.target

      [Service]
      Type=forking
      PIDFile=/run/daemon.pid
      ExecStart=/root/bin/daemon.sh
      ExecReload=/bin/kill -1 -- $MAINPID
      ExecStop=/bin/kill -- $MAINPID
      TimeoutStopSec=5
      KillMode=process

      [Install]
      WantedBy=multi-user.target


      Just before the while loop starts, I'm creating a PID file (it is going to be created by the daemon, not by the child, or the parent, because they don't come to this point): echo $$ > /run/daemon.pid;. It works fine, but each time I call systemctl status daemon.service, I get the following warning:



      daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory


      If I insert the PID creaton statement echo $$ > /run/daemon.pid; at the very beginning of the script (which will be used by the children and parent, too), I get the following warning:



      daemon.service: PID 30631 read from file /run/daemon.pid does not exist or is a zombie.


      What would be the best approach for creating the PID file without getting any warning messages by systemd?









      share|improve this question










      share|improve this question




      share|improve this question









      asked Aug 3 at 12:53









      chevallier

      800116




      800116




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote













          So the problem you're seeing here is because when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.



          If you create the pidfile from the child, then it will race with the exit of the parent and in some (many?) cases will cause the first error you're seeing.



          If you create the pidfile writing $$ to it before you start the child, then it will have the pid of the parent, which will have exited, so you'll see the other error.



          One way to do this correctly is to write the pidfile from the parent, just before exiting. In that case, write $! (and not $$), which returns the pid of the last process spawned in background.



          For example:



          #!/bin/bash

          # Run the following code in background:
          (
          while keep_running; do
          do_something
          done
          ) &

          # Write pid of the child to the pidfile:
          echo "$!" >/run/daemon.pid
          exit


          This should work correctly... HOWEVER, there's a much better way to accomplish this! Read on...




          Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time...



          Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.



          Update your /root/bin/daemon.sh to simply do this:



          #!/bin/bash

          # Run the following code in foreground:
          while keep_running; do
          do_something
          done


          (NOTE: Perhaps daemon.sh is not the best name for it at this point... Since that would imply it runs in background. Maybe name it something more appropriate, related to what it actually does.)



          Then update the .service file to use Type=simple (which would actually be used by default here, so you could even omit it.)



          [Service]
          Type=simple
          ExecStart=/root/bin/daemon.sh
          ExecReload=/bin/kill -1 -- $MAINPID
          ExecStop=/bin/kill -- $MAINPID
          TimeoutStopSec=5
          KillMode=process


          BTW, you can probably drop ExecStop=, since killing the process with a signal is the default behavior as well...



          systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)



          I hope you find this helpful... And I really hope you choose to let systemd do the heavy lifting for you! It's much more efficient that way.






          share|improve this answer




























            up vote
            0
            down vote













            Ok, the error message daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory disappeared after I added the following statement to the service file:



            ExecStartPost=/bin/sleep 2





            share|improve this answer





















              Your Answer







              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "106"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460321%2fwhich-pid-belongs-into-the-systemd-pidfile-section-when-creating-a-shell-script%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              So the problem you're seeing here is because when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.



              If you create the pidfile from the child, then it will race with the exit of the parent and in some (many?) cases will cause the first error you're seeing.



              If you create the pidfile writing $$ to it before you start the child, then it will have the pid of the parent, which will have exited, so you'll see the other error.



              One way to do this correctly is to write the pidfile from the parent, just before exiting. In that case, write $! (and not $$), which returns the pid of the last process spawned in background.



              For example:



              #!/bin/bash

              # Run the following code in background:
              (
              while keep_running; do
              do_something
              done
              ) &

              # Write pid of the child to the pidfile:
              echo "$!" >/run/daemon.pid
              exit


              This should work correctly... HOWEVER, there's a much better way to accomplish this! Read on...




              Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time...



              Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.



              Update your /root/bin/daemon.sh to simply do this:



              #!/bin/bash

              # Run the following code in foreground:
              while keep_running; do
              do_something
              done


              (NOTE: Perhaps daemon.sh is not the best name for it at this point... Since that would imply it runs in background. Maybe name it something more appropriate, related to what it actually does.)



              Then update the .service file to use Type=simple (which would actually be used by default here, so you could even omit it.)



              [Service]
              Type=simple
              ExecStart=/root/bin/daemon.sh
              ExecReload=/bin/kill -1 -- $MAINPID
              ExecStop=/bin/kill -- $MAINPID
              TimeoutStopSec=5
              KillMode=process


              BTW, you can probably drop ExecStop=, since killing the process with a signal is the default behavior as well...



              systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)



              I hope you find this helpful... And I really hope you choose to let systemd do the heavy lifting for you! It's much more efficient that way.






              share|improve this answer

























                up vote
                1
                down vote













                So the problem you're seeing here is because when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.



                If you create the pidfile from the child, then it will race with the exit of the parent and in some (many?) cases will cause the first error you're seeing.



                If you create the pidfile writing $$ to it before you start the child, then it will have the pid of the parent, which will have exited, so you'll see the other error.



                One way to do this correctly is to write the pidfile from the parent, just before exiting. In that case, write $! (and not $$), which returns the pid of the last process spawned in background.



                For example:



                #!/bin/bash

                # Run the following code in background:
                (
                while keep_running; do
                do_something
                done
                ) &

                # Write pid of the child to the pidfile:
                echo "$!" >/run/daemon.pid
                exit


                This should work correctly... HOWEVER, there's a much better way to accomplish this! Read on...




                Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time...



                Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.



                Update your /root/bin/daemon.sh to simply do this:



                #!/bin/bash

                # Run the following code in foreground:
                while keep_running; do
                do_something
                done


                (NOTE: Perhaps daemon.sh is not the best name for it at this point... Since that would imply it runs in background. Maybe name it something more appropriate, related to what it actually does.)



                Then update the .service file to use Type=simple (which would actually be used by default here, so you could even omit it.)



                [Service]
                Type=simple
                ExecStart=/root/bin/daemon.sh
                ExecReload=/bin/kill -1 -- $MAINPID
                ExecStop=/bin/kill -- $MAINPID
                TimeoutStopSec=5
                KillMode=process


                BTW, you can probably drop ExecStop=, since killing the process with a signal is the default behavior as well...



                systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)



                I hope you find this helpful... And I really hope you choose to let systemd do the heavy lifting for you! It's much more efficient that way.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  So the problem you're seeing here is because when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.



                  If you create the pidfile from the child, then it will race with the exit of the parent and in some (many?) cases will cause the first error you're seeing.



                  If you create the pidfile writing $$ to it before you start the child, then it will have the pid of the parent, which will have exited, so you'll see the other error.



                  One way to do this correctly is to write the pidfile from the parent, just before exiting. In that case, write $! (and not $$), which returns the pid of the last process spawned in background.



                  For example:



                  #!/bin/bash

                  # Run the following code in background:
                  (
                  while keep_running; do
                  do_something
                  done
                  ) &

                  # Write pid of the child to the pidfile:
                  echo "$!" >/run/daemon.pid
                  exit


                  This should work correctly... HOWEVER, there's a much better way to accomplish this! Read on...




                  Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time...



                  Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.



                  Update your /root/bin/daemon.sh to simply do this:



                  #!/bin/bash

                  # Run the following code in foreground:
                  while keep_running; do
                  do_something
                  done


                  (NOTE: Perhaps daemon.sh is not the best name for it at this point... Since that would imply it runs in background. Maybe name it something more appropriate, related to what it actually does.)



                  Then update the .service file to use Type=simple (which would actually be used by default here, so you could even omit it.)



                  [Service]
                  Type=simple
                  ExecStart=/root/bin/daemon.sh
                  ExecReload=/bin/kill -1 -- $MAINPID
                  ExecStop=/bin/kill -- $MAINPID
                  TimeoutStopSec=5
                  KillMode=process


                  BTW, you can probably drop ExecStop=, since killing the process with a signal is the default behavior as well...



                  systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)



                  I hope you find this helpful... And I really hope you choose to let systemd do the heavy lifting for you! It's much more efficient that way.






                  share|improve this answer













                  So the problem you're seeing here is because when Type=forking is in use, then the pid file must be created (with the correct pid) before the parent process exits.



                  If you create the pidfile from the child, then it will race with the exit of the parent and in some (many?) cases will cause the first error you're seeing.



                  If you create the pidfile writing $$ to it before you start the child, then it will have the pid of the parent, which will have exited, so you'll see the other error.



                  One way to do this correctly is to write the pidfile from the parent, just before exiting. In that case, write $! (and not $$), which returns the pid of the last process spawned in background.



                  For example:



                  #!/bin/bash

                  # Run the following code in background:
                  (
                  while keep_running; do
                  do_something
                  done
                  ) &

                  # Write pid of the child to the pidfile:
                  echo "$!" >/run/daemon.pid
                  exit


                  This should work correctly... HOWEVER, there's a much better way to accomplish this! Read on...




                  Actually, the whole point of systemd is to daemonize processes and run them in background for you... By trying to do that yourself, you're just preventing systemd from doing it for you. Which is making your life much harder at the same time...



                  Instead of using Type=forking, simply write your shell script to run in foreground and set up the service to use Type=simple. You don't need any pidfiles then.



                  Update your /root/bin/daemon.sh to simply do this:



                  #!/bin/bash

                  # Run the following code in foreground:
                  while keep_running; do
                  do_something
                  done


                  (NOTE: Perhaps daemon.sh is not the best name for it at this point... Since that would imply it runs in background. Maybe name it something more appropriate, related to what it actually does.)



                  Then update the .service file to use Type=simple (which would actually be used by default here, so you could even omit it.)



                  [Service]
                  Type=simple
                  ExecStart=/root/bin/daemon.sh
                  ExecReload=/bin/kill -1 -- $MAINPID
                  ExecStop=/bin/kill -- $MAINPID
                  TimeoutStopSec=5
                  KillMode=process


                  BTW, you can probably drop ExecStop=, since killing the process with a signal is the default behavior as well...



                  systemd's Type=forking is really there only for legacy programs that only work that way and can't be easily fixed to work in foreground... It's hacky and inefficient. The whole point of systemd (and some of its alternatives, predecessors) is to do the forking and daemonizing itself and let services just worry about doing what they need to do! :-)



                  I hope you find this helpful... And I really hope you choose to let systemd do the heavy lifting for you! It's much more efficient that way.







                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Aug 4 at 4:28









                  Filipe Brandenburger

                  2,894417




                  2,894417






















                      up vote
                      0
                      down vote













                      Ok, the error message daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory disappeared after I added the following statement to the service file:



                      ExecStartPost=/bin/sleep 2





                      share|improve this answer

























                        up vote
                        0
                        down vote













                        Ok, the error message daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory disappeared after I added the following statement to the service file:



                        ExecStartPost=/bin/sleep 2





                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          Ok, the error message daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory disappeared after I added the following statement to the service file:



                          ExecStartPost=/bin/sleep 2





                          share|improve this answer













                          Ok, the error message daemon.service: PID file /run/daemon.pid not readable (yet?) after start: No such file or directory disappeared after I added the following statement to the service file:



                          ExecStartPost=/bin/sleep 2






                          share|improve this answer













                          share|improve this answer



                          share|improve this answer











                          answered Aug 3 at 13:23









                          chevallier

                          800116




                          800116






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f460321%2fwhich-pid-belongs-into-the-systemd-pidfile-section-when-creating-a-shell-script%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              How to check contact read email or not when send email to Individual?

                              Bahrain

                              Postfix configuration issue with fips on centos 7; mailgun relay