run python telegram bot after reboot and if it's crashes on AWS EC2 - python-3.x

I created a telegram bot using pyrogram and it crashes after few hours. Sometimes I stop the EC2 myself to reduce the cost. I created these cron jobs inside /etc/crontab but it seems they are not working as expected.
Cronjob 1 is to run the python file after EC2 reboot.
Cronjob 2 is to restart the bot if it got crashed.
Here is my crontab content.
#reboot sudo pgrep -f bot.py || sudo nohup /usr/bin/python3 /home/ubuntu/bot.py & > /home/ubuntu/startOnReboot.log
*/2 * * * * sudo pgrep -f bot.py || sudo nohup /usr/bin/python3 /home/ubuntu/bot.py & > /home/ubuntu/restartBotAfterCrash.log
I would like to know whether my cronjob is not correct or any solution better than this approach.

You shouldn't use sudo in the cronjob, use sudo crontab -e instead to have it run as root.
Futhermore, & > is different from &> - did you mean to redirect all output to the specified file or run the cronjob in the background and redirect stdout? If it's the latter, you don't need to tell cron to run it as a background job and the redirection should come before the ampersand (which you should drop anyway).
Last, you probably want to use a systemd service for this instead.

Related

Is there a way to make crontab run a gnu screen session?

I have a discord bot running on a raspberry pi that i need to restart every day, I'm trying to do this through crontab but with no luck.
It manages to kill the active screen processes but never starts an instance, not that I can see with "screen -ls" and I can tell that it doesn't create one that I can't see as the bot itself does not come online.
Here is the script:
#!/bin/bash
sudo pkill screen
sleep 2
screen -dmS discordBot
sleep 2
screen -S "discordBot" -X stuff "node discordBot/NEWNEWNEWN\n"
Here is also the crontab:
0 0 * * * /bin/bash /home/admin/discordBot/script.sh
Is it possible to have crontab run a screen session? And if so how?
Previously I tried putting the screen command stright into cron but now I have it in a bash script instead.
If I run the script in the terminal it works perfectly, it’s just cron where it fails. Also replacing "screen" with the full path "/usr/bin/screen" does not change anything.
So the best way of doing it, without investigating the underlying problem would be to create a systemd service and putting a restart command into cron.
 
/etc/systemd/system/mydiscordbot.service:
[Unit]
Description=A very simple discord bot
[Service]
Type=simple
ExecStart=node /path/to/my/discordBot.js
[Install]
WantedBy=multi-user.target
Now you can run your bot with systemctl start mydiscordbot and can view your logs with journalctl --follow -u mydiscord bot
Now you only need to put
45 2 * * * systemctl restart discordbot
into root's crontab and you should be good to go.
You probably should also write the logs into a logfile, maybe /var/log/mydiscordbot.log, but how and if you do that is up to you.
OLD/WRONG ANSWER:
cron is run with a minimal environment, and depending on your os, /usr/bin/ is probably not in the $PATH var. screen is mostlikely located at /usr/bin/screen, so cron can't run it because it can't find the screen binary. try replacing screen in your script with /usr/bin/screen
But the other question here is: Why does your discord bot need to be restarted every day. I run multiple bots with 100k+ users, and they don't need to be restarted at all. Maybe you should open a new question with the error and some code snippets.
I don't know what os your rpi is running, but I had a similar issue earlier today trying to get vms on a server to launch a terminal and run a python script with crontab. I found a very easily solution to automatically restart it on crashes, and to run something simply in the background. Don't rely on crontab or an init service. If your rpi as an x server running, or anything that can be launched on session start, there is a simple shell solution. Make a bash script like
while :; do
/my/script/to/keep/running/here -foo -bar -baz >> /var/log/myscriptlog 2>&1
done
and then you would start it on .xprofile or some similar startup operation like
/path/to/launcher.sh &
to have it run the background. It will restart automatically everytime it closes if started in something like .xprofile, .xinitrc, or anything ran at startup.
Then maybe make a cronjob to restart the raspberry pi or whatever system is running the script but this script wil restart the service whenever it's closed anyway. Maybe you can put that cronjob on a script but I don't think it would launch the GUI.
Some other things you can do to launch a GUI terminal in my research with cronjob that you can try, though they didn't work for my situation on these custom linux vms, and that I read was a security risk to do this from a cronjob, is you can specify the display.
* * * * * DISPLAY=:0 /your/gui/stuff/here
but you would would need to make sure the user has the right permissions and it's considered an unsafe hack to even do this as far as I have read.
for my issue, I had to launch a terminal that stayed open, and then changed to the directory of a python script and ran the script, so that the local files in directory would be called in the python script. here is a rough example of the "launcher.sh" I called from the startup method this strange linux distro used lol.
#!/bin/sh
while :; do
/usr/bin/urxvt -e /bin/bash -c "cd /path/to/project && python loader.py"
done
Also check this source for process management
https://mywiki.wooledge.org/ProcessManagement

Setting up a cronjob on Google Compute Engine

I am new to setting up cronjobs and I'm trying to do it on a virtual machine in google compute engine. After a bit of research, I found this StackOverflow question: Running Python script at Regular intervals using Cron in Virtual Machine (Google Cloud Platform)
As per the answer, I managed to enter the crontab -e edit mode and set up a test cronjob like 10 8 * * * /usr/bin/python /scripts/kite-data-pull/dataPull.py. I also checked the system time, which was in UTC, and entered the time according to that.
The step I'm supposed to take, as per the answer, is to run sudo systemctl restart cron which is throwing an error for me:
sudo systemctl restart cron
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Any suggestions on what I can do to set up this cronjob correctly?
Edit a cron jobs with crontab -e and inset a line:
* * * * * echo test123 > /your_homedir_path/file.log
That will write test123 every minute into file.log file.
Then do tail if and wait a couple minutes. You should see test123 lines appearing in the file (and screen).
If it runs try running your python file but first make your .py file executable with "chmod +x script.py"
Here you can find my reply to similar question.

Crontab does not run on CentOS 7

I'm using CentOS 7, and installed "cronie"
yum install cronie
I have a shell to backup my home folder, shell's content (of course, backup.sh is 775)
#!/bin/bash
#START
TIME=`date +%Y-%m-%d_%Hh%M`
FILENAME=backupHome_123.30.150.29_$TIME.tar.gz
SRCDIR=/home
DESDIR=/backup
tar -cpvzf $DESDIR/$FILENAME $SRCDIR
#END
And add to crontab -e
00 2 * * * /bin/bash /backup/backup.sh
But crontab does nothing. When I check log at /var/log/cron only, something like that and no more error or processing log
May 1 00:26:08 app crontab[12041]: (root) END EDIT (root)
May 1 00:33:21 app crontab[12086]: (root) BEGIN EDIT (root)
May 1 00:34:25 app crontab[12086]: (root) END EDIT (root)
Anyone can give me some advises to make crontab work?
Thank you.
I found that the most useful information was actually given by
systemctl status crond
Which revealed that it failed to load correctly due to an "Unauthorized SELinux context" error.
This can happen if cron daemon isn't running.
Check it with:
pgrep cron
If command returns nothing, run:
systemctl restart crond
This should help.
You want to make sure cron is started & that it is started if your server reboots so you need two commands on CentOS 7 to make sure of this:
systemctl enable crond && systemctl restart crond
If you are used to using sudo, you can add sudo in front of above command. like this:
sudo systemctl enable crond && systemctl restart crond
YOU WILL get confirmation from system, something like:
Created symlink from /etc/systemd/system/multi-user.target.wants/crond.service to /usr/lib/systemd/system/crond.service.
Then lastly check cron is running
pgrep cron
I know that I'm late to answer you, but maybe someone will have this kind of problem. It is possible that CRON can't run the script because the path is not correct.
Your path is
00 2 * * * /bin/bash /backup/backup.sh
I guess that path should be:
00 2 * * * sh /bin/bash/backup/backup.sh
Only difference is space after bash directory and sh command at the start of CRON job.
You have to add username before your command like this for example :
1 * * * * root or username /usr/bin/php /var/www/html/yourwebsite/yourscript.php

Cron job not auto runs inside a Docker container

I have a LAMP container with supervisor.
I add a simple cron
* * * * * root /bin/date >> /var/log/cron.log
from my Dockerfile
ADD ./crons/test /etc/cron.d/test
RUN chmod 0777 /etc/cron.d/test
I start cron via supervisor with a supervisor-cron.conf like this:
[program:cron]
command=/bin/bash -c "cron -f"
numprocs=1
autostart=true
autorestart=true
startretries=2
Cron starts fine and stays up and running. The strange thing is that no cronjob is running automatically [as it should] but when I execute docker exec lamp crontab /etc/cron.d/test the cron job starts and works as expected.
Am I missing something? Everywhere I have read that cron jobs are executed automatically by cron.
I solved it.
I tried both setting them up in /etc/crontab and /etc/cron.d/ .
Cron didn’t auto-start the cron jobs .
However, when I run docker exec lamp crontab /etc/cron.d/my_cronjob_file all played nice. This made me suspicious , and then I read this . So, after adding my_cronjob_file in the container [in the dockerfile] I added RUN crontab /etc/cron.d/my_cronjob_file . This essentially ‘installs’ the cronjob to the crontab table. [I don’t know the internals of cron/tab but that’s the gist I understood.] .
After that , the cron service comes up by supervisor and the cronjob runs like a charm.
This can be solved with the bash file, due to the layered architecture of the Docker, cron service doesn't get initiated with RUN/CMD/ENTRYPOINT commands.
Simply add a bash file which will initiate the cron and other services (if required)
DockerFile
FROM gradle:6.5.1-jdk11 AS build
# apt
RUN apt-get update
RUN apt-get -y install cron
# Setup cron to run every minute to print (you can add/update your cron here)
RUN touch /var/log/cron-1.log
RUN (crontab -l ; echo "* * * * * echo testing cron.... >> /var/log/cron-1.log 2>&1") | crontab
# entrypoint.sh
RUN chmod +x entrypoint.sh
CMD ["bash","entrypoint.sh"]
entrypoint.sh
#!/bin/sh
service cron start & tail -f /var/log/cron-2.log
If any other service is also required to run along with cron then add that service with & in the same command, for example: /opt/wildfly/bin/standalone.sh & service cron start & tail -f /var/log/cron-2.log
Once you will get into the docker container there you can see that testing cron.... will be getting printed every minute in file: /var/log/cron-1.log

How to setup cron job on Amazon Linux AMI

I am hosting Tiny Tiny RSS site hosted on
Amazon Linux AMI
To update the feed automatically I have to run the following Cron job.
Reference
http://tt-rss.org/redmine/projects/tt-rss/wiki/UpdatingFeeds
*/30 * * * * /usr/bin/php /var/www/html/tt-rss/update.php --feeds --quiet
Here is the step I did:
sudo su
cd /etc
crontab -e
# add this line
*/30 * * * * /usr/bin/php /var/www/html/tt-rss/update.php --feeds --quiet
But I still got the message "Update Daemon is not running".
May I know, is this correct step for Cron job?
You should enter these commands on Amazon Linux 2:
sudo systemctl start crond
sudo systemctl enable crond
This sounds like crond is not running. In which case:
service crond start
chkconfig crond on
You should first inspect the cron log file /var/log/cron and look for any errors. This will probably give you the answer. Also make sure you can run the command successfully on the command line (/usr/bin/php /var/www/html/tt-rss/update.php --feeds --quiet).
Please check the spaces, it could be because of spaces are not placed correctly
Simply do : * * * * * wget -o - -q -t 1 "your url with cron file"
Please remove the "--quiet" part from your cron command and check the log and feed again

Resources