Ubuntu – Crontab and C program that should be executed into a terminal window

ccrongnome-terminal

I want to create Cron job to run a compiled .c file. Let's say I have a file, called program.c, on my desktop. I compile it using gcc program.c,
which creates a.out executable file.

I want to open a terminal at certain time via Cron and run a.out inside to show its output into the terminal. I've opened Crontab for editing – crontab -e – and I've tried:

30 *  * * * /home/username/Desktop/a.out /Desktop/a.out 

and

30 *  * * * cd /home/username/Desktop/a.out && ./a.out 

and

30 *  * * * /bin/sh /home/username/Desktop/a.out

and

30 *  * * * bash -c "exec /home/username/Desktop/a.out"

And nothing works!

Best Answer

If the executable file generates an output file, or just modifies some things, the Cron job should be:

* * * * * /home/<user>/Desktop/a.out

If the paths inside the program are relative, their origin point should be properly defined, otherwise the output file will be placed, for an example, into the $HOME directory instead of $HOME/Desktop, where you suppose to be. This is a common mistake.


If the program doesn't write any output file and just generates some data within the stdout, you should redirect it to a file to see it into an appropriate place (this part 2>&1 redirects and the error messages to stdout):

* * * * * /home/<user>/Desktop/a.out >> /home/<user>/Desktop/a.out.log 2>&1

While the stdout isn't redirected, Cron will sending local mails to the user, unless this is overridden by setting the variable MAILTO in crontab:

MAILTO="my@custom.mail"
* * * * * /home/<user>/Desktop/a.out

To execute a GUI application via Cron is more difficult task, because Cron is not designed to work with GUI. Few environment variables should be exported and the best way to do that is to create an additional startup script. Here is an example how to do that within Ubuntu Unity/Gnome:

  • Crate the script. Let's assume it is also located into the ~/Desktop directory and is called a-cron.sh. Do nоt forget to make it executable - chmod +x a-cron.sh. The script should look as this:

    #!/bin/sh
    
    # Set the necessary environment variables - UBUNTU/UNITY/GNOME:
    export DISPLAY=$(w $(id -un) | awk 'NF > 7 && $2 ~ /tty[0-9]+/ {print $3; exit}')
    export GNOME_DESKTOP_SESSION_ID=true
    export DBUS_SESSION_BUS_ADDRESS=$(sed -zne 's/^DBUS_SESSION_BUS_ADDRESS=//p' /proc/`pgrep gnome-session -U $(id -u)`/environ)
    
    #Open new terminal and execute the script:
    /usr/bin/gnome-terminal -x sh -c '/home/<user>/Desktop/a.out; exec bash'
    

    The part exec bash intends to keep the terminal window open after the execution of a.out - there are also other available approaches, that are described here.

  • Now create user's Cron job - crontab -e - as this:

    * * * * * /home/<user>/Desktop/a-cron.sh > /home/<user>/Desktop/a-cron.log 2>&1</pre>
    

    Unlike as the above section, the log file plays different role here. The error messages from the execution of a-cron.sh shall be written inside a-cron.log - so if everything is okay it must be empty.

  • Save and close crontab to apply the job. Wait about a minute to see the result.

References:

Demo - I just created a simple C program (this is my first attempt) to check how all this works:

enter image description here

Related Question