Pi PHP and CRON

Boy am I in it over my head (for now). my new Raspberry Pi turned up – very nice – formatted a 32Gig microSD, loaded Raspbian and after a couple of false starts I soon had a working (graphical worktop) operating system.  I added FTP, VNC (so I don’t have to tie up a monitor, keyboard and mouse) and PHP,  I managed to get my PHP MQTT page to run and send messages to the MQTT Broker.

So this works.   127.0.0.1/mqtt/examples/publish.php

No problem.

I THOUGHT I was having trouble getting a CRON job to work (timed running of the page) – but it turns out it’s worse than that..   I’ve been trying “PHP” then the location of the page… and I’ve realise that won’t work – so in a terminal..

php  /var/www/mqtt/examples/publish.php  – the page runs but relative paths in the page are wrong… surely there is a way to run a page like that as if it was running in a browser (clearly without any client side stuff).

So in the CRON page I had

* * * * * php /var/www/mqtt/examples/publish.php

and NOTHING was happening…  and of course now I know at least one reason. I’m assuming the other reason will be something to do with permissions…

So can anyone familiar with the PI point me in the right direction.. how do I get a CRON job to run the page with internal relative links working as if it was being run from a browser.

And if we get that far, am I going to hit permissions issues. I used sudo crontab –e to edit a simple text file with the above line in it and saved it in /etc/cron.d

All of which is probably wrong.

Incidentally don’t try installing THINGBOX on the Pi2 – it won’t work and they don’t have a way around it yet. In my case it would not even start up.

Solution: Although no-one had a single solution I got enough out of all you helpful people to resolve this and more.

So firstly, it’s not /usr/local/bin that PHP resides it’s /usr/bin and you can use any old editor to edit any old file name in /etc/cron.d to do the job.

Given my hatred of command lines I found the command line editor to be ATTROCIOUS but.. LeafEdit in the desktop is great (well ok, it’s not NOTEPAD++ is it) – it’s only failing is it’s not running as root. Now there might be an easier way but I went into the terminal and ran “sudo leafedit” and up popped the graphical editor with all the permissions I needed – I updated my file calld cron to include the path for php, saved it and then ran “crontab cron” – no idea what that does – but next thing I knew, my PHP messages were appearing in Mosquitto (being monitored by mqtt-spy on the PC) no problem.

I rebooted the PI – no problem – it all came up roses and no modifications to the original PHP file at all. That’s what I call A RESULT.

 

15 thoughts on “Pi PHP and CRON

  1. Pete,

    On the ongoing discussion with crontab (not all of which is here ..my fault!), you are
    absolutely on the right track and have made the correct deduction about crontab
    doing something with the file after your edit is complete. Your main stumbling block
    at the moment is /etc/cron.d. I have no idea where you got that from to begin with, but
    other than removing any file you’ve put there, you should just forget about it for the time
    being (it’s part of the system start-up initialization and not what you want for your
    script).

    Once you create your scheduling file with the crontab command
    (crontab -e, say), it will be automatically saved to the
    /var/spool/cron/crontabs directory, the cron daemon will read it and then start
    executing it on your scheduled times.

    The temporary file you mention is actually a function of your editor (sounds like
    you’re using “nano”) and you can go ahead and confirm with “y” when it asks
    that confusing question about creating it when you are exiting.

    As mentioned above, you really do need to remove any file you’ve put
    into the /etc/cron.d directory, otherwise you might find that the system
    won’t reboot correctly (unlikely, but possible).

    -John-

  2. Ack, the second code insert should have been

    file_get_contents([full or relative path to second script, or a url]);

    (no php in front.)

  3. I’m pretty sure that anything you can do in PHP in a served webpage can also be done with PHP as a script from a console or cron, it just requires the right references.

    If your main PHP script (the one called as a cron job) needs to execute another PHP script, one option is to include it

    include "[full or relative path to second php script]";

    … and that file will execute as if that code was part of the calling page

    If it’s just a matter of picking up content from a file, or from a url, then it’s as simple as

    php file_get_contents([full or relative path to second script, or a url]);

    Files can also be opened and parsed line-by-line if that’s more convenient.

    If you’re still having problems with your PHP cron script, just post the errors and I’m sure someone can help resolve it.

    1. Done it without any changes to the PHP page – which I think is important… see comments.. thanks for the feedback.

  4. Perhaps, you better forget about php and using python, I run my broker on the pi b +, the same use as a media center, and in turn have a python script running in the background as a service, subscribed a 2 topics that encanrgan turn on and off, another machine, which I use as a file server, web and backups, shortly thanks to his work and that of the community have planned to start adding sensors (temperature, flow meters etc, etc …) and relays for enceder and off things.
    I’ll leave the script in python running on pi, ordered to hear messages and perform the actions, whether they receive proper mensanje.

    ——————————————————————
    #!/usr/bin/env python
    #wakeup nas4free Mqtt mensaje
    import paho.mqtt.client as mqtt
    from wakeonlan import wol
    import os
    nas4free=’00:00:44:5B:00:8D’ #mac del servidor nas4free
    # The callback for when the client receives a CONNACK response from the server.
    def on_connect(client, userdata, flags, rc):
    #print(“Connected with result code “+str(rc))

    # Subscribing in on_connect() means that if we lose the connection and
    # reconnect then subscriptions will be renewed.
    # client.subscribe(“$SYS/#”)
    # client.subscribe(“croms”)
    client.subscribe(“croms/nas4free”)

    # The callback for when a PUBLISH message is received from the server.
    def on_message(client, userdata, msg):
    #print(msg.topic+” “+str(msg.payload))
    if msg.topic==”croms/nas4free”:
    if str(msg.payload)==”ON”:
    #print “Despierta Nas4free”
    wol.send_magic_packet(nas4free)
    if str(msg.payload)==”OFF”:
    os.system(‘ssh root@10.0.0.105 “shutdown -p now” >/dev/null’)

    client = mqtt.Client()
    client.username_pw_set(‘user’,’password’)

    client.on_connect = on_connect
    client.on_message = on_message

    client.connect(“localhost”, 1883, 60)

    # Blocking call that processes network traffic, dispatches callbacks and
    # handles reconnecting.
    # Other loop*() functions are available that give a threaded interface and a
    # manual interface.
    client.loop_forever()

    ————————————————————
    Saludos Leo

    1. This is Raspberry Pi 2 – different processor apparently (I never had the Raspberry Pi B – considered it a little slow – this one is not slow). THanks for feedback. Thingbox of course gives you the graphical interface on a browser at least for NODE_RED – however as it does not seem to work (they say that on their website) I guess I’ll leave that until it does. I guess the magical thing is that I can build this code up and use another SD card to try out Thingbox as a completely separate install. Will check out your links thanks.

  5. Pete,

    The “other reason” is probably because cron (for security reasons) usually runs with a very restricted idea of ${PATH} as default, so it very probably just isn’t finding “php”. Do which php on the command line to find out what executable you’re actually running and then type that whole path into the crontab file. For example:-

    * * * * * php /var/www/mqtt/examples/publish.php

    …might become…

    * * * * * /usr/local/bin/php /var/www/mqtt/examples/publish.php

    Once that’s done, you can just grep for cron in the syslog file to find out what cron thinks is wrong:-
    grep -i cron /var/log/syslog

    Your environmental stuff should be set inside the script, rather than in the crontab entry, but you should, at a push, be able to do something like this:-

    * * * * * ( export PHP_HOME=/var/www/mqtt && /usr/local/bin/php /var/www/mqtt/examples/publish.php ) >> /var/tmp/mqtt-php.log 2>&1

    …where the incantation at the end “>> /var/tmp/mqtt-php.log 2>&1” will append all of the output into the log file you specify (mqtt-php.log in this example), which should make it a bit easier to troubleshoot while you’re developing. Apologies if you already know how to blow those particular eggs.

    1. I don’t know how to blow any of them Pucebabboon – never used grep in my life. I’m now thinking the local version of the php file is never going to work as the links inside the php page assume the website (ie 127.0.0.1) as the base.

      Someone suggested I do this..

      * * * * * wget http://127.0.0.1/mqtt/examples/publish.php

      That looked promising (in a browser that address produces the desired results).

      So to be clear, I’ve used crontab as (using sudo) to write a simple file called cron into the /etc/cron.d with that one line in it..

      How many things did I get wrong..

    2. Right PuceBaboon – I’m seeing part of what you are on about… I’m half convinced that even if the PHP path sorted it – that local reference to the php file won’t work because of relative file references (includes) in the php file – so the idea of using WGET appeals (but my current version doesn’t work).

      I managed to “grep cron” as you suggest… lots of references to INSECURE MODE with no apparent consequences.. then one line with loots of gook – and THAT’s when I discovered that tightvnc on the PI and ultravnc on the PC won’t let me copy and paste info back and forth between the PI and the PC – doohhhhhhhh.

      1. Hi,

        I would recommend creating a shell-script that you run from cron, this allows you to change directory and test everything without having to wait for cron to run. You still probably need a full path to php but it should make your php-includes work ok provided they don’t depend on any other path.

        Create a file called /root/scripts/runcron.sh (or similar).


        #!/bin/sh
        cd /var/www/
        /usr/local/bin/php /var/www/script.php

        Then in cron add:


        * * * * * /root/scripts/runcron.sh >/dev/null 2>/dev/null

        (The ” >/dev/null 2>/dev/null” is to stop warnings and junk from filling up logs.)

        Dont forget “chmod 755 /root/scripts/runcron.sh”.

        Finally, if you would like to really make sure how thing work when you run stuff from cron you can assume the role as cron by typing:


        sudo -u cron /bin/sh

        Then you can run the script and se what kind of errors you get.

        Good luck.

        1. Thanks for that comprehensive response Rickard. Not yet used an .SH file and so will save that joy for my trip next week to Spain where there will be no distractions and I can get to grips with it. Thank you so much – for me and for others reading the comments.

          1. No problem. I’m reading your blog with interest as I’m attempting something similar and you are a few steps ahead of me.

Comments are closed.