Quite often, when developing websites or web services, some application logic, like sending letters or re-indexing a search database, must be executed in the background on the server side. In UNIX-like systems, there is a software utility cron
that allows you to run scripts periodically at a certain time. Using this job scheduler, it is possible to execute scripts with a frequency not more than once per minute. But it is not always enough to solve specific tasks.
Therefore, I will show an approach that I use in my projects and that allows scripts to be run periodically every few seconds. We'll look at how to run shell scripts with another rarely used but useful nohup
utility.
First, create a shell script cron.sh
in the project folder /var/www/example.com
with the following content.
#!/bin/bash
while true
do
# Execute another server script.
/usr/bin/php ./backend_logic.php
# Wait for 10 seconds.
sleep 10
done
As you can see, the code is very simple: an infinite loop in which another PHP script is invoked with a delay of 10 seconds after each iteration.
Note that when running PHP script with a cron
, there may be a situation when the same script is run in parallel two or more times. It is possible in cases where the execution time of the script is more than one minute and the job scheduler is configured to run the script every minute. This is because cron
does not wait until the task is completed. With a shell script, it will never happen, because the code is always executed sequentially.
Save this file and set execute permission on it.
sudo chmod a+x cron.sh
In fact, this script can already be used, but let's see how it can be run from the command line in the background.
For a fully working method, we need the nohup
. A command or script launched by the utility will continue to run on the server even after the user's logout. To run our script from the local directory, execute the next command from the console.
sudo nohup ./cron.sh &
The output, which would normally send to the terminal, sends to a file called nohup.out
. If, for some reason, you want to use the nohup
command without getting nohup.out
, here's how to do it.
sudo nohup ./cron.sh </dev/null >/dev/null 2>&1 &
With such parameters, the standard I/O streams (stdin, stdout, and stderr) will be redirected to a device file /dev/null
that discards all data written to it.
In order to stop running the cron.sh
script, we need to find this process in the list of all running processes of the system. For this, use the command:
sudo ps -ef | grep "cron.sh"
OutputUID PID PPID C STIME TTY TIME CMD
root 877 1 0 Jan18 ? 00:12:36 /bin/bash ./cron.sh
As a result, you will see a list of processes matching the keyword in the form of a table. The value in the second column is the process PID, which is needed to stop the execution of the specific process with the kill
command.
sudo kill -9 877
And finally, if you want the cron.sh
script to be executed even after rebooting the server add the following simple configuration in the system's crontab
file.
@reboot nohup /var/www/example.com/cron.sh
Use crontab
with -e
option to open the schedule file in your preferred text editor.
I showed you one approach you can use to perform certain application logic in the background with a frequency greater than the system utility cron
allows. This method, as I mentioned, is convenient to use in conjunction with the poorer software stack. Of course, you can replace nohup
with something else, for example, screen
.