Ampersand is your friend
Please, do not run with scissors. You are asking a very valid questions for all the wrong reasons.
at
uses cron
to schedule jobs in the future. They are great tools for that purpose. But when you are using scheduling tools to get things done now you are crossing the water to fill the bucket. MelBurslan points this out to you and gives you the proper answer. You then try to clarify your need - but unfortunately miss his point. You insist on using at
- when you should simply use ampersand &
.
For other readers - the question is more along the lines of "How do I get php to run (spawn) another script and continue without waiting for the script to finish?".
This will then lead you to some great fundamental unix knowledge as MelBurslan shows you:
nohup /path/to/myprogram & 2>&1
nohup
ensures that the command will keep running in the background even if the current user logs out.
&
is what you probably is missing: Ampersand disconnects the process and send it to the background.
2>&1
joins stderr
(2) with stdout
(1) and nohup
then implicitly sends the output to nohup.out
If you do not add the ampersand - then the caller (here php) will wait until the job has finished.
If you then go down the rabbit hole as cas points out - you can then see how people are using this technique with shell_exec
and exec
(see here)
Additional important information to understand from this:
If you are not interested in any output you can send it to /dev/null
like this:
> /dev/null
This will redirect stdout
. If you do not want any error messages as well you can redirect stderr
like this:
2> /dev/null
You can combine them into one line:
> /dev/null 2> /dev/null
And there is a short form of this - send stderr to stdout - and send stdout to "nothing":
> /dev/null 2>&1
So let us put this knowledge into usage:
Your example misuses at
:
shell_exec("echo /usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} | at now");
But if you simply want it to continue your script - simply add the ampersand &
shell_exec("/usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} &");
If you do not use any output - then you should redirect it.
shell_exec("/usr/local/bin/php -q scripts/myfile.php {$var1} {$var2} > /dev/null 2>&1 &");
And the most elegant version as suggested by Brent Braisley would be:
exec("nohup /usr/bin/php -q scripts/myfile.php {$var1} {$var2} > /dev/null 2>&1 &");
Excessive use of at
The at
command schedules commands to be run by the atrun
script.
If you read the man page for at
you will find:
Note that at is implemented through the cron(8) daemon by calling
atrun(8) every five minutes. This implies that the granularity of at
might not be optimal for every deployment. If a finer granularity is
needed, the system crontab at /etc/crontab needs to be changed.
You have already adjusted the crontab. I would advise against it in your case. But if you insist you should look at man crontab (5):
string meaning
------ -------
@reboot Run once, at startup of cron.
@yearly Run once a year, "0 0 1 1 *".
@annually (same as @yearly)
@monthly Run once a month, "0 0 1 * *".
@weekly Run once a week, "0 0 * * 0".
@daily Run once a day, "0 0 * * *".
@midnight (same as @daily)
@hourly Run once an hour, "0 * * * *".
@every_minute Run once a minute, "*/1 * * * *".
@every_second Run once a second.
This means that you can change */1
(for once a minute) to @every_second
.
But - please - don't :-)
Running atrun manually
You should not misuse atrun
as you suggest. "All" it does (in your context) is adding the ampersand &
to execute you job in the background.
The most likely reason it fails is that you (as you should be!) are logged in as a regular user. Only root have permission to use at
per default. If you need to change this - have a look at the man page for at and:
/var/at/at.allow allow permission control
/var/at/at.deny deny permission control
But - again - please - don't :-)
If all fails...
If all fails then please restate your question. Getting the scheduling tool to run now is not the root cause of your problem. If the above is not enough - then we need to dig deeper.
cron
orat
? Why not just run it from the command line ? If you want it to run when you are not logged in anymore you can run it usingnohup
and in the background, such asnohup /path/to/myprogram & 2>&1
this will send thestdin
andstderr
, both tonohup.out
file located in the directory you run the program from.nohup
doesn't work for my usage. I am running the command in PHP. When usingat
, I get a return immediately. When usingnohup
, PHP sits and waits for the command to finish executing which leaves the page hanging. I'll edit the OP to show my usage.