crontab not being executed into a container after setting up permissions - linux

I'm running a docker container with an image:
ubi8/ubi-minimal
The cronjob has correct path and go packet is already installed:
crontab -l
*/2 * * * * go run /usr/local/src/script.go
The file has correct permissions:
-rw-r-xr-x 1 root root 6329 Jun 16 15:10 script.go
However the crontab -e is like this:
/bin/sh: /usr/bin/vi: No such file or directory
crontab: "/usr/bin/vi" exited with status 127
and
cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
The crontab was added in the dockerfile like this:
RUN crontab -l | { cat; echo "*/2 * * * * go run /usr/local/src/script.go"; } | crontab -
I think is correctly setup isn't it?
the crontab should execute the script every 2 minuts but it's not. Also the image is minimal and I cannot edit any file I just included some permissions to the files from the dockerfile.
If needed to change any Path from crontab I have to do this trough the dockerfile.

As it sounds like a lot of trouble, consider skipping the cron daemon entirely and just sleep in a loop
#!/bin/sh
while true; do
TIME_LOOP_START=$(date +%s) # integer time in seconds
script.go
# calculate offset for 2 minutes in seconds
sleep $(($TIME_LOOP_START + 120 - $(date +%s)))
done
adapted from
https://askubuntu.com/questions/852070/automatically-run-a-command-every-5-minutes
Get current time in seconds since the Epoch on Linux, Bash
You may find this is even better extended by making the time and target executable arguments $1 $2

You need to start the cron daemon. Here's a Dockerfile I made to illustrate
FROM registry.access.redhat.com/ubi8/ubi-minimal
RUN microdnf update && microdnf install cronie
RUN crontab -l | { cat; echo "*/2 * * * * /usr/local/src/script.sh"; } | crontab -
COPY script.sh /usr/local/src/
CMD crond -n
Note that the CMD runs crond with the -n option which keeps crond in the foreground. If we let it daemonize, docker would see that the process had ended and would terminate the container.
Instead of using go, I made a small shell script like this, called script.sh
#/bin/sh
echo Hello from script >> ~/log.txt
It writes to /root/log.txt every 2 minutes.

Related

crontab doesnt work in linux but manually works

I made a shell script to connect using ssh with password to another linux server, get the details of a specific file and save it in a log file in the origin server. Manually works without problem but with the /etc/crontab doesnt update the file. (I think it may be the connection because if I try to write a test text in the file it works fine).
I tried with tee -a command and the >> command to update the file and both fails.
This is my code
#! /bin/bash
sshpass -p "password" ssh "username"#"ipserver" ls -l /filepath/file.txt | tee /home/user/test/details.log
I omitted the password, username and ip for discretion.
This is the /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
* * * * * user-name command to be executed
*/1 * * * * root /home/test/script.sh
Hope you can help me.
Thanks
My first question is, why do you run your script as root? This opens up security holes if the script itself or the directory /home/test is not owned by root.
If you are running the script as root from crontab, have you tested it as root from the command line?
I see directories /home/test and /home/user/test in your post. Do they really both exist and why?
Imho, what you should do:
Setup public key authentication between your user test and the remote user on the system. Use ssh-keygen to generate a public/private key pair, then copy the public key onto the target system and save it to ~/.ssh/authorized_keys. This will eliminate you having to use sshpass and have the password in cleartext in your crontab file.
Test the script as user test and then install it in the user test's crontab file. Simply type crontab -e as user test and you can add the same entry there.

Why my crontab can not work with /etc/crontab file

In my project, I want to make a scheduled task with cron.
So I added a line into /etc/crontab
*/10 * * * * root /home/JobidUserJobname/JobidUserJobname.sh
and the content of /etc/crontab is like:
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
*/10 * * * * root /home/JobidUserJobname/JobidUserJobname.sh
*/1 * * * * root date
and I restart the crontab service:
#service crond restart
#service crond reload
and they executed successfully.
But when I executed:
#crontab -l
It shows:
no crontab for root
It seems nothing wrong. My linux OS is:
CentOS release 6.5 (Final)
Who can help me?
The crontab -l gives the output "no crontab for root". This is expected since it will show only crontabs added using the command crontab -e. The crons added in "/etc/crontab" will not be listed in crontab -l command.
Things to check.
1. Check if the file "/home/JobidUserJobname/JobidUserJobname.sh" has execute permission. If no then execute the below command.
chmod +x /home/JobidUserJobname/JobidUserJobname.sh
If its still not working append a "/bin/sh" before the script.
*/10 * * * * root /bin/sh /home/JobidUserJobname/JobidUserJobname.sh
Check the cron logs to see if there are any errors.

crontab: which one is the right job definition?

Which one is the right definition for a crontab job?
With or without the user before the execution path?
.---------------- minute (0 - 59)
| .------------- hour (0 - 23)
| | .---------- day of month (1 - 31)
| | | .------- month (1 - 12) OR jan,feb,mar,apr ...
| | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
| | | | |
* * * * * <user> <command>
On Debian, crontab -l show a backup example as:
....
For example, you can run a backup of all your user accounts
at 5 a.m every week with:
0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
...
There is no user here!!
The /etc/crontab content (on the same box), gives a different clue:
....
and files in /etc/cron.d. These files also have username fields,
that none of the other crontabs do.
...
crontab does not * allow for specifying a user to run as...
... unless you're in the root crontab.
If you check my favorite linux admin reference, you'll not near the bottom that there are some tricks to running certain chrontab entries as a particular user. However, the best practice, if you wish to do so, would be to edit the crontab of the user:
crontab -u <username> -e
If you must...
0 0 * * * sudo -u [user] [command]
But this can only be done in the crontab of a user with sudo permissions, and as fcm pointed out, such a user could just edit the root crontab.
Most flavors of 'NIX require a user in the root crontab /etc/crontab
0 0 * * * [user] [command]
Conclusion
If you want to specify which user is running a specific cron job, the best practice is to do one of the following, depending on the use-case:
root crontab
/etc/crontab
sudo crontab
<time> <user> <command>
user crontab
crontab -u <username> -e
<time> <command>

Running a cron job at 2:30 AM everyday

How to configure a cron job to run every night at 2:30? I know how to make it run at 2, but not 2:30.
crontab -e
add:
30 2 * * * /your/command
To edit:
crontab -e
Add this command line:
30 2 * * * /your/command
Crontab Format:
MIN HOUR DOM MON DOW CMD
Format Meanings and Allowed Value:
MIN Minute field 0 to 59
HOUR Hour field 0 to 23
DOM Day of Month 1-31
MON Month field 1-12
DOW Day Of Week 0-6
CMD Command Any command to be executed.
Restart cron with latest data:
service crond restart
As seen in the other answers, the syntax to use is:
30 2 * * * /your/command
# ^ ^
# | hour
# minute
Following the crontab standard format:
+---------------- minute (0 - 59)
| +------------- hour (0 - 23)
| | +---------- day of month (1 - 31)
| | | +------- month (1 - 12)
| | | | +---- day of week (0 - 6) (Sunday=0 or 7)
| | | | |
* * * * * command to be executed
It is also useful to use crontab.guru to check crontab expressions.
The expressions are added into crontab using crontab -e. Once you are done, save and exit (if you are using vi, typing :x does it). The good think of using this tool is that if you write an invalid command you are likely to get a message prompt on the form:
$ crontab -e
crontab: installing new crontab
"/tmp/crontab.tNt1NL/crontab":7: bad minute
errors in crontab file, can't install.
Do you want to retry the same edit? (y/n)
If you have further problems with crontab not running you can check Debugging crontab or Why is crontab not executing my PHP script?.
An easy way to write cron is to use the online cron generator
It will generate the line for you. One thing to note is that if you wish to run it each day (not just weekdays) you need to highlight all the days.
As an addition to the all above mentioned great answers, check the https://crontab.guru/ - a useful online resource for checking your crontab syntax.
What you get is human readable representation of what you have specified.
See the examples below:
30 2 * * * (answer of this question)
#daily
59 23 31 12 *
30 2 * * * wget https://www.yoursite.com/your_function_name
The first part is for setting cron job and the next part to call your function.
30 2 * * * Every Day at 2:30 Am
30-31 2 * * * Every Day at 2:30 -31 am
Along with he answers its important to understand the cron expressions , i face a lot of difficulty in understanding .
But an intuitive way to understand is given here .

Crontab is not working on Amazon EC2 server

Crontab is not working on Amazon EC2 Linux Server.
I have saved below codes in /etc/crontab file
crontab
# For details see man 4 crontabs
# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
* 10 * * * tar cvfpz /home/backup/web_$(date +%Y%m%d).tar.gz /home/web
I have started crontab command already, but this one didn't work.
I also have saved this line in "crontab -e" too, but cron won't work.
* 10 * * * tar cvfpz /home/backup/web_$(date +%Y%m%d).tar.gz /home/web
Is there anyone who had same experience like me?
Thank you.
I recently began using Amazon's linux distro on ec2 instances and after trying all kinds of things for cron all I needed was:
sudo service crond start
crontab -e
This allowed me to set a cron job as "ec2-user" without specifying the user. For example:
0 12 * * * python3 example.py
In fact, specifying a user here prevented it from running.
Solved the problem.
I used this code and it works!
* 2 * * * root tar cvfpz /home/backup/web_`date +\%Y\%m\%d`.tar.gz /home/web
You should use crontab -e to create cron for the logged user, so that you don't need to inform the username.
See here: https://stackoverflow.com/a/16986464/1777152
For people who are dealing with AWS machines and EBS you need to specify the root keyword before the command since ec2-user isn't allowed to run crontabs. Of course there's a way to fix that.
you can edit the crontab by typing sudo nano /etc/cron.d/mycrontabs or crontab -e
* * * * * root bla bla
Also make sure e that the file is ended with a new line
Don't use nano, use the native sudo crontab -e command.

Resources