crontab doesnt work in linux but manually works - linux

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.

Related

crontab not being executed into a container after setting up permissions

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.

schedule pihole blacklist from text file of domains with crontab on raspberry pi

I'm trying to edit my crontab to make a scheduled block of specific domains for my pi hole configuration.
my setup is that I've got a file: 'blocklist.txt' which contains a list of domains like:
instagram.com
facebook.com
newssite.com
and I'm using the following to get that to work with xargs. I've taken the normal version and converted it to absolute paths here so that it will work in cron. I'm also attempting to write out to a file at /home/pi/cron.log which I made just to capture the output and see what's going on. nothing updates there either.
46 17 * * * /usr/bin/xargs -a /home/pi/blocklist.txt /usr/local/bin/pihole --wild &>/home/pi/cron.log
this works totally fine when running in my normal shell and updates the log, etc... but does not work when I try to schedule a cron job for it a few minutes out.
Maybe I'm missing something with my paths or with scheduling?
I already converted my timezone in raspi-config to my timezone.
My solution does not currently read from a file, but it's very close to what you are looking for. Here's a blog post with lots of details, but here are the core snippets:
block.sh:
#!/bin/bash
blockDomains=(facebook.com www.facebook.com pinterest.com www.pinterest.com)
for domain in ${blockDomains[#]}; do
pihole -b $domain
done
allow.sh:
#!/bin/bash
blockDomains=(facebook.com www.facebook.com pinterest.com www.pinterest.com)
for domain in ${blockDomains[#]}; do
pihole -b -d $domain
done
Allow execution on these scripts:
chmod +x /home/pi/Documents/block.sh
chmod +x /home/pi/Documents/allow.sh
Block after 9pm, allow after 6am. crontab -e:
0 21 * * * bash -l -c '/home/pi/Documents/block.sh' | logger -p cron.info
0 6 * * * bash -l -c '/home/pi/Documents/allow.sh' | logger -p cron.info

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>

date function in file which starts on system startup - bash

I am trying to run a bash script on start up. The aim of the script is to play an mp3 file with the music player mplayer, at a set time (say at 15 past every hour).
My bash script is the following:
#!/bin/sh
while :
do
S=$(date)
T=${S:14:2} #this gives me the minute column of the current time
if [ $T -eq 15 ]
then
mplayer path_to_mp3_file
fi
done
When I run this bash file from the terminal it works absolutely fine.
However, when I restart my Linux computer with exactly the same script, it fails to work(this is also the case with other music players such as vlc). The script also works when it only contains the mplayer file_path command.
I have tried setting a standard program to open the script, the gnome-terminal.wrapper.
The way in which I was able to set the program as a start up application is in menu>Preferences>Startup applications and add the file to the already existing applications.
There are 2 parts to your problem. 1. play the mp3, 2. (presumably only when the user is logged in). For part 1, use a crontab and have the cron daemon run the script at 15 past the hour. You create your crontab file with crontab -e (to edit your crontab). The format of a crontab entry is:
* * * * * command_to_execute
| | | | |
| | | | +- day of week (0-6) (Sunday = 0)
| | | +--- month (1-12)
| | +----- day of month (1-31)
| +------- hour (0-23)
+--------- minute (0-59)
In your case you would want:
15 * * * * playmymp3.sh
Part 2 In your script you will want to check whether the user is logged in. To only play the music when you are logged in, test that you are logged in with users. Something like this in playmymp3.sh should work:
if grep -q "yourlogin" < <( users ); then
#play mp3 file
fi
Give it a try and let me know.
Try with:
T=$(date +%M)
instead of:
S=$(date)
T=${S:14:2} #this gives me the minute column of the current time
(note: your script enters in a very fast loop when no sound must be played, I suggest you include a sleep command).
Apologies on my part.
When setting the script as a startup file, I had not noticed that I had to provide an actual command, bash script_path, instead of solely the file path.
With this, my problem seems to be solved.

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