I'm trying to run a script via crontab on my Raspberry Pi.
I have created the script: ScreenShot.sh
The content of the file is:
#!/bin/sh
export DISPLAY=:0 && \
import -window root -resize 20% /pathtofolder/screenshot.jpg
This works fine when I run it via SSH
/home/pi/ScreenShot.sh
I have made the script executable.
I then added it to cron via sudo crontab -e
*/1 * * * * /home/pi/ScreenShot.sh
I want the script to run ever 1 minute (I'll extend this later, but for testing purposes I have it at 1 minute).
For some reason the script does not run in crontab and does not take a screenshot.
I have noticed that if I run the script via sudo:
sudo /home/pi/ScreenShot.sh
I get the following error:
No protocol specified
import.im6: unable to open X server `:0' # error/import.c/ImportImageCommand/368.
I'm assuming when Crontab runs, it runs the script as Root, which might be causing the failure.
I enabled logging on crontab and if I view the log I see the following:
Nov 6 06:26:01 IRDigitalDisplay /USR/SBIN/CRON[12634]: (root) CMD (/home/pi/ScreenShot.sh)
Nov 6 06:26:02 IRDigitalDisplay /USR/SBIN/CRON[12633]: (CRON) info (No MTA installed, discarding output
So I'm assuming something goes wrong. However it's not writing the error to the log, but rather trying to email it to me.....
My question is:
How do I get my ImageMagick script to run in crontab, take a screen shot every X minutes, and save this into a predetermined folder?
You need to add the script to the "pi" users crontab, not root's. Start the crontab edior with this command as user "pi":
crontab -e
No sudo needed.
The crontab entry has to be:
*/5 * * * * /home/pi/ScreenShot.sh
Related
So I have a mariadb in a container in /home/admin/containers/mariadb.
This directory also contains an .env-file with MARIADB_ROOT_PASSWORD specified.
I want to backup the database using the following command:
* * * * * root docker exec --env-file /home/admin/containers/mariadb/.env mariadb sh -c 'exec mysqldump --databases dbname -uroot -p"$MARIADB_ROOT_PASSWORD"' > /home/admin/containers/mariadb/backups/dbname.sql
The command works when running from the terminal but crontab only creates an empty sql file.
I assume there are some issues with cron ready the .env file.
Bash command line is nice.
Cron is "different".
Let me count the ways.
Here are things to pay attention to.
To simplify the description,
let's assume you put the above instructions
into backup.sh, so the crontab line is simply
* * * * * root sh backup.sh
Cron is running under UID zero here. Test interactively with: $ sudo backup.sh
Cron uses a restricted $PATH. Test with: $ env PATH=/usr/bin:/bin backup.sh
Cron's $CWD won't be your home directory.
More generally, env will report different results from interactive. Your login dot files have not all been sourced.
Cron doesn't necessarily set umask to 0022. Likely not an issue here.
Output of ulimit -a might differ from what you see interactively.
Cron does not provide a pty, which can affect e.g. password prompts. Likely not an issue here.
Likely there are other details that differ.
If you find that some aspect of the
environment is crucial to a successful
run, then arrange for that near the
top of backup.sh. You might want
to adjust PATH, source a file,
or cd somewhere.
Now let's examine what diagnostic clues
you're gathering from each cron run.
The most important detail is that
while you're logging stdout,
you are regrettably discarding messages sent to
FD 2, stderr.
You can accomplish your logging
on the crontab command line,
or within the backup.sh script.
Use 2>&1 to merge stderr with stdout.
Or capture each stream separately:
docker ... 2> errors.txt > dbname.sql
With no errors, you will see a zero-byte
text file.
Also, remember the default behavior of crond.
If you just run a command, with no
redirect, cron assumes it should
complete silently with zero exit status,
such as /usr/bin/true does.
If there's a non-zero status, cron will
report the error.
If there's any stdout text,
such as /usr/bin/date produces,
cron wants to email you that text.
If there's any stderr text,
again it should be emailed to you.
Test your email setup.
Set the cron MAILTO=me#some.where
variable if the default of root
wasn't suitable.
Interactively verify that email sending on
that server actually works.
Repair your setup for postfix or
whatever if you find that emails are
not reliably being delivered.
I've been searching online for days on how to set up my server to automatically rotate the logs for a Rails app my team recently released. I've gotten myself as far as being able to run sudo logrotate -f /etc/logrotate.conf but of course, who wants to do that all the time?
The contents of the config file for the app's log (I want to add more, but don't see a need to when I can't rotate one file yet):
/path/to/app/production.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
copytruncate
}
I've verified the /etc/logrotate.conf file contains this line:
include /etc/logrotate.d
But this is the part where I'm not too sure where to go. I've found many different approaches at actually automating the process, but none seem to work. For the record, I've verified the server has the anacron command installed, but I don't know how to configure it for any process of my own. Also, root does not have a crontab on the server yet (we haven't needed it), and I'm unsure if that's better to use than /etc/crontab. In the /etc/crontab file, I've added:
15 0 * * * root cd / && run-parts --report /etc/cron.daily
but I've seen other people use
15 0 * * * root test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
Is the latter a better option? Why? If so, how do I ensure it works? Again, I don't know how to set up anacron for the task at hand.
Finally, here are the previous contents of the /etc/cron.daily/logrotate file:
/usr/sbin/logrotate /etc/logrotate.conf >/dev/null 2>&1
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
/usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0
and after some research, I replaced that with this (which I understand a bit better):
test -x /usr/sbin/logrotate || exit 0
/usr/sbin/logrotate /etc/logrotate.conf
Can someone explain to me what the first config was doing, and which of these two options is better? I'm unsure why I have to force this process just to get it to run. Maybe /etc/crontab doesn't work like I think it does?
Is the latter a better option? Why?
With your cron command, /etc/cron.daily/* will only ever run if the computer is on at midnight (00:15). If you turn it off at night, as some people do, it would never run.
The work around this, and instead run the command when the computer starts later in the day, one can use anacron. This is obviously less useful for servers than desktops.
Of course, you don't want to use both at once, since that would run the jobs twice a day. Therefore, cron, the most brittle mechanism, will yield to anacron by only running the job if anacron is not installed.
This is what Debian and Ubuntu does by default with their test -x /usr/sbin/anacron || crontab job prefixes.
All server distros will come with logrotate correctly set up, so you shouldn't be modifying the crontab, anacrontab, or /etc/cron.daily/logrotate. The only thing you should do is add a file to /etc/logrotate.d.
Try putting this in /etc/crontab file :
-*/15 * * * * root test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1
It works for me.
I am trying to run a RAKE file from a bash script fired by a crontab:
my crontab looks like this:
* * * * * /bin/bash ~/sites/www/tweeet/get_tweeet.sh
my bash script (get_tweeet.sh) looks like this:
1 #!/bin/bash
2 set -x
3 cd /var/www/tweeet/
4 export RAILS_ENV=development
5 rake get_tweeet >> /var/www/tweeet/test.log
6 echo "$(date): cron job run " >> /var/www/tweeet/test.log
What happens is that line 6 outputs into the test.log but line 5 does now - the rake does not run.
BUT if i call the script using the exact line from the crontab
/bin/bash /var/www/tweeet/get_tweeet.sh
then it works - i'm baffled by this!
Your direct execution of the script runs because it has your full environment available. A cronjob does not, even if it belongs to the same user. So one solution is to launch it from within a full login shell. In your crontab:
bash --login -c '/var/www/tweeet/get_tweeet.sh'
I remember seeing some post about this potentially having some subtle side effects that I don't recall, but it's been working for me.
I'm having a rough time executing script/runner with a cron and RVM. I believe the issues lie with the rvm environment not being set before the runner is executed.
currently im throwing the error
/bin/sh: 1.sql: command not found
which is more than i've gotten earlier, so i guess that's good.
I've read this thread Need to set up rvm environment prior to every cron job but im still not really getting it. Part of the problem i think is the error reporting.
this is my runner thus far.
*/1 * * * * * /bin/bash -l -c 'rvm use 1.8.7-p352#2310; cd development/app/my_app2310 && script/runner -e development "Mailer.find_customer"'
as per the above link, i tried making a rvm_cron_runner.
i created a file and placed this in it:
#!/bin/sh
source "/Users/dude/.rvm/scripts/rvm"
exec $1
then i updated my crontab to this.
*/1 * * * * * /bin/bash -l -c '/Users/dude/development/app/my_app2310/rvm_cron_runner; rvm use 1.8.7-p352#2310; cd development/app/my_app2310 && script/runner -e development "Mailer.find_customer"'
This also has made no difference. i get no error. nothing.
Can anyone see what i'm doing incorrectly?
P.S i hope my code formatting worked.
Could you try to place the code you want to run in a separate script, and then use the rvm_cron_runner ?
So place your actions in a file called /path/cron_job
rvm use 1.8.7-p352#2310
cd development/app/my_app2310 && script/runner -e development "Mailer.find_customer"
and then in your crontab write
1 2 * * * /path/rvm_cron_runner /path/cron_job
The differences:
this does not start a separate shell
use the parameter of the rvm_cron_runner
If you would use an .rvmrc file, you could even drop the rvm use ... line, I think.
You don't need to write a second cron runner (following that logic, you might as well write a third cron runner runner). Please keep things simple. All you need to do is configure your cron job to launch a bash shell, and make that bash shell load your environment.
The shebang line in your script should not refer directly to a ruby executable, but to rvm's ruby:
#!/usr/bin/env ruby
This instructs the script to load the environment and run ruby as we would on the command line with rvm loaded.
On many UNIX derived systems, crontabs can have a configuration section before the actual lines that define the jobs to be run. If this is the case, you would then specify:
SHELL=/path/to/bash
This will ensure that the cron job will be spawned from bash. Still, your environment is missing, so to instruct bash to load your environment, you will want to add to the configuration section the following:
BASH_ENV=/path/to/environment (typically .bash_profile or .bashrc)
HOME is automatically derived from the /etc/passwd line of the crontab owner, but you can override it.
HOME=/path/to/home
After this, a cron job might look like this:
15 14 1 * * $HOME/rvm_script.rb
What if your crontab doesn't support the configuration section. Well, you will have to give all the environment directives in one line, with the job itself. For example,
15 14 1 * * export BASH_ENV=/path/to/environment && /full/path/to/bash -c '/full/path/to/rvm_script.rb'
Full blog post on the subject
You can use rvm wrappers:
/home/deploy/.rvm/wrappers/ruby-2.2.4/ruby
Source: https://rvm.io/deployment/cron#direct
I'm trying to get a rails job running with CRON. All the examples I find direct me to other rails tools, plugins, gems, etc, which is good, but I really just want to use CRON, regardless. I can run my job ok with the following, but when I've tried cron I haven't had any luck (just doesn't seem to do anything). I want to run it every 3 minutes (for testing).
/usr/bin/env ruby ~/Dropbox/98_2011/webs/apps238/swapper/script/runner /home/durrantm/Dropbox/98_2011/webs/apps238/swapper/app/controllers/scheduled_emails_controller.rb
I'm on Linux Ubuntu.
My PATH has:
/var/lib/gems/1.8/bin:/home/durrantm/.rvm/gems/ruby-1.8.7-p302/bin:/home/durrantm/.rvm/gems/ruby-1.8.7-p302#global/bin:/home/durrantm/.rvm/rubies/ruby-1.8.7-p302/bin:/home/durrantm/.rvm/bin:/home/durrantm/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/pgsql/bin
Cron jobs don't load the user's environment. Try adding RAILS_ENV=production before your command within crontab, or whichever environment you need.
Example:
RAILS_ENV=production
*/3 * * * * /your/command/here
OR, if you want to make sure you have your user's full environment, execute the command within a login shell:
*/3 * * * * bash --login -c '/your/command/here'
Get rid of the home dir expansion character (replace ~ with /home/user/etc/etc) and you should be in good shape (quite likely cron's expansion of ~ doesn't match your users).
If the other parts of the syntax are bothersome there's an easy gui.
http://gnome-schedule.sourceforge.net/
sudo apt-get install gnome-schedule
You'll still have to have the path to your rb file fixed up though.
1- you might not have permissions. try running crontab -e as root
2- why don't you write to a log file to debug the issue:
*/3 * * * * /your/command/here >> /path/to/logfile