1

I have a script that have "while true" loop. And I want to run that script from cron on every minute, so that when the process is killed (or is failed - no matter why) cron will run the script again.

But when I'm checking the ps -aef --forest there is my process runned by /usr/sbin/CROND -n. This wasn't be bad for cron or system? Or maybe I should do it differently?

1
  • 1
    You would be better of to either a) use cron for starting a script that checks for the status of the infinite script and restarts if need be or b) create a systemd service - there you can even define a restart on failure. See here. Systemd is a bit hard in the beginning but much more powerful than cron.
    – FelixJN
    May 28, 2019 at 11:50

3 Answers 3

5

Maybe a short example for a systemd service will do.

This is our infinite script, location /path/to/infinite_script , executable bit set:

#!/bin/bash
while ((1)) ; do
    date >> /tmp/infinite_date
    sleep 2
done

No we need to define a service file:

[Unit]
#just what it does
Description= infinite date service

[Service]
#not run by root, but by me
User=fiximan
#we assume the full service as active one the script was started
Type=simple
#where to find the executable
ExecStart=/path/to/infinite_script
#what you want: make sure it always is running
Restart=always

[Install]
#which service wants this to run - default.target is just it is loaded by default
WantedBy=default.target

and place it in /etc/systemd/system/infinite_script.service

Now load and start the service (as root):

systemctl enable infinite_script.service
systemctl start infinite_script.service

The service is running now and we can check its status

systemctl status infinite_script.service

● infinite_script.service - infinite date service
   Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-05-28 14:18:52 CEST; 1min 33s ago
 Main PID: 7349 (infinite_script)
    Tasks: 2 (limit: 4915)
   Memory: 1.5M
   CGroup: /system.slice/infinite_script.service
           ├─7349 /bin/bash /path/to/infinite_script
           └─7457 sleep 2

Mai 28 14:18:52 <host> systemd[1]: Started infinite date service.

Now if you kill the script (kill 7349 - main PID) and check the status again:

● infinite_script.service - infinite date service
   Loaded: loaded (/etc/systemd/system/infinite_script.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2019-05-28 14:22:21 CEST; 12s ago
 Main PID: 7583 (infinite_script)
    Tasks: 2 (limit: 4915)
   Memory: 1.5M
   CGroup: /system.slice/infinite_script.service
           ├─7583 /bin/bash /path/to/infinite_script
           └─7606 sleep 2

Mai 28 14:22:21 <host> systemd[1]: Started infinite date service.

So note how it was just restarted instantly with a new PID.

And check the file ownership of the output:

ls /tmp/infinite/date
-rw-r--r-- 1 fiximan fiximan  300 Mai 28 14:31 infinite_date

So the script is run by the correct user as set in the service file.

Of course you can stop and disable the service:

systemctl stop infinite_script.service
systemctl disable infinite_script.service

EDIT:

A few more details: a user's personal services can (by default) be placed in $HOME/.config/systemd/user/ and managed accordingly with systemctl --user <commands>. No root needed just like with a personal crontab.

5

mu.

cron is the wrong tool for this job.

The right tool is a service manager, one moreover that incorporates the idea of auto-restarting services when they terminate. (Not all do.) Such service managers include:

One creates a service definition, appropriate to the service manager, that runs the infinite loop script, and adds it. For several of the service managers, that's simply a small run program (usually itself a script) that execs the infinite loop script. The service managers do the starting, monitoring, and auto-restarting.

Several of the service managers are easily employed to do per-user service management as well as system-wide, and one can set this up as a per-user service definition of a service that runs as one's own account and can be managed without superuser privileges (which managing system-wide services requires).

Further reading

1
  • 1
    Would your point be a little clearer if you disambiguated mu ?
    – Jeff Schaller
    May 28, 2019 at 12:50
0

@FelixJN

A caveat: Switching on selinux may prevent your script to run. To get it working, I

  1. moved it to /usr/local/bin (which is a folder selinux supports)

  2. and edited /etc/systemd/system/infinite_script.service to correct ExecStart accordingly

  3. ran sudo restorecon -rv /usr/local/bin to get this information to selinux and

  4. ran systemctl daemon-reload to finally

  5. restart the service systemctl start infinite_script.service

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .