Kill process via sh script called by crontab - bash

i wrote a sh file which kills a tomcat process, suppose my shell scrip is in /usr/temp, script looks likethat:
#!/bin/bash
ps -Af | grep "tomcat_something" | grep -v grep | awk '{print$2}' | xargs sudo kill -9
then i created a cron via crontab -e My cron looks likethat (dont pay attention to the time):
10 10 * * * /usr/temp/myshellscript.sh
If i run the sh without cron it works fine, but via cron is not working at all.
I even tryied to run the same shell script with a touch file command and in this case cron works fine, so my doubt is that the problem is the kill command. Can someone help ?

Problem:
sudo in cron job does not work as it expects a password to be entered.
Possible Solutions
Not Recommended as require to give password in plaintext.
Use expect (Quick google or SO search will help you) in your script
and provide sudo's password there.
Run your script as sudo instead of running sudo inside script
In your own crontab, write your command like so:
10 10 * * * echo "your password" | sudo -S /usr/temp/myshellscript.sh
Again, it is not recommended
Best Possible Way: Use roots crontab (only if you have access)
Run the following command:
sudo crontab -e
This opens up root's crontab. sudo is not necessary to run your command in this context since it'll be invoked as root anyway.

Related

Some commands not working in the script running from the crontab -e

I'm running a script from crontab in which I want to set the symbolic link for npx. It does some other things which are dependent on the npx command itself. Its running the script as expected on the giving time interval, but its giving me no result for command which npx or whereis npx. When I try to run the script from terminal directly these commands does generate the correct path.
Note that, crontab I'm using is under the root user privilege, i.e set with sudo crontab -e and verified with echoing whoami inside the script which generate 'root')
By default, crontab will run your cron jobs using sh which might be the reason you are getting no results.
Try to explicitly change the shell to your default shell by adjusting the crontab entry:
*/30 * * * * /bin/bash -c "/my_script.sh"
In this case I changed it to bash, you can change it to your desired shell.

`notify-send` works when invoking script manually, but not from a crontab

I wanted my cron job to report to me on desktop when it executes, through notify-send command on Ubuntu. I've read through the common problems that stated a shell script didn't have access to a display, which is solved by adding this before calling notify-send:
export DISPLAY=:0.0
So i am okay in that regard.
The place where i am right now, is that my script works and notifies me on desktop if i invoke it from terminal manually, but not from the crontab.
The situation is as follows:
The script that executes is a PHP file. The PHP command to invoke the shell command, is:
<?php
`export DISPLAY=:0.0 && command -v notify-send && notify-send "Hello world"`;
(backticks in PHP mean execute in shell)
In both cases i am running it as root
When testing from terminal, i run:
sudo -u root /usr/bin/php -q /var/www/html/cron.php &> /dev/null
This works, and i get a desktop notification
To edit my crontab for the root user, i use:
sudo -u root crontab -e
In my crontab file, my line is this:
* * * * * /usr/bin/php -q /var/www/html/cron.php &> /dev/null
This one does not produce a desktop notification, even though the script 100% executes (i have the successful result in log files).
What goes wrong here, and why wouldn't i get the desktop notification?
you must set the PATH within the script or export it from crontab!
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

docker exec is not working in cron

I have pretty simple command which is working fine standalone as a command or bash script but not when I put it in crontab
40 05 * * * bash /root/scripts/direct.sh >> /root/cron.log
which has following line
PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
SHELL=/bin/sh PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root/
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/
I tried to change the url of script to /usr/bin/scirpts/ no luck
I even tried to run script directly in cron
26 08 * * * docker exec -it mongodb mongodump -d meteor -o /dump/ >> /root/cron.log
with no luck, any help appreciated.
EDIT
I don't see any errors in /root/cron.log file either
Your docker exec command says it needs "pseudo terminal and runs in interactive mode" (-it flags) while cron doesn't attach to any TTYs.
Try changing your docker exec command to this and see if that works?
docker exec mongodb mongodump -d meteor -o /dump/
for what it's worth I had this exact same problem. Fixing your PATH, changing permissions, and making sure you are running as the appropriate docker user are all good things, but that's not enough. It's going to continue failing because you are using "docker exec -it", which tells docker to use an interactive shell. Change it to "docker exec -t" and it'll work fine. There will be no log output anywhere telling you this, however. Enjoy!
cron debugging
1. /var/log or sendmail
As crond work as a daemon, without ability of failing, execution is more important than logging. Then by default, if something goes wrong, cron will send a mail to $USER#localhost reporting script output and errors.
Have a look at /var/mail or /var/spool/mail for some mails, maybe
and at /etc/aliases to see where root's mail are sents.
2. crond and $PATH
When you run a command by cron, have care that $PATH is user's default path and not root default path (ie no */sbin and other reserved path to super user tools).
For this, the simplier way is to print your default path in the environment where everything run fine:
echo $PATH
or patch your script from command line:
sed -e "2aPATH='$PATH'" -i /root/scripts/direct.sh
This will add current $PATH initializer at line 2 in your script.
Or this, will whipe from your script all other PATH=:
sed -e "s/PATH=[^ ]*\( \|$\)/\1/;2aPATH='$PATH'" -i /root/scripts/direct.sh
3. Force logging
Add at top of your script:
exec 1>/tmp/cronlog-$$.log
exec 2>/tmp/cronlog-$$.err
Try this:
sed -e '1a\\nexec 1>/tmp/cronlog-$$.log\nexec 2>/tmp/cronlog-$$.err' -i ~/scripts/direct.sh
Finalized script could look like:
#!/bin/bash
# uncomment two following lines to force log to /tmp
# exec 1>/tmp/cronlog-$$.log
# exec 2>/tmp/cronlog-$$.err
PATH='....' # copied from terminal console!
docker exec -it mongodb mongodump -d meteor -o /dump/
Executable flag
If you run your script by
40 05 * * * bash /root/scripts/direct.sh
no executable flag are required, but you must add them:
chmod +x ~/scripts/direct.sh
if you want to run:
40 05 * * * /root/scripts/direct.sh
1) Make sure this task is in the root user's crontab - it's probably the case but you didn't write it explicitly
2) cron may be unable to find bash. I would remove it and call directly your script after making it executable:
chmod 755 /root/scripts/direct.sh
and then set your crontab entry as 40 05 * * * /root/scripts/direct.sh 2>&1 >> /root/cron.log
If it's still not working, then you should have some useful output in /root/cron.log
Are you sure your script is running? Add an other command like touch /tmp/cronok before the docker exec call.
Don't forget that the crontab needs a newline at the end. Use crontab -e to edit it.
Restart the cron service and check the logs (grep -i cron /var/log/syslog).
If your OS is redhat/centos/fedora, you should try with the username (root) between the frequency and the command.
Check your mails with the mail command.
Check the crontab permissions. chmod 644 /etc/crontab.
Maybe you just don't want to reinvent the wheel.
Here's a few things I'd change-- first, capture STDERR along with STDOUT and remove the shell specification in cron-- use #! in your script instead.
40 05 * * * /root/scripts/direct.sh &>> /root/cron.log
Next, you are setting your PATH in the reverse order, and you are missing your shbang. I have no idea why you are defining SHELL as /bin/sh, when you are running bash, instead of dash. Change your script to this.
#!/usr/bin/env bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/root
PATH=$PATH:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
# Mongo Backup
docker exec -it mongodb mongodump -d meteor -o /dump/
See if that yields something better to work with.

Crontab not really running as root when it should be?

I have Ubuntu and am running under the user "alex". I've got the following bash script running as root with crontab however it sends me an email and it looks like it hasn't run correctly as the result is not present:
/dev/sda - Reallocated_Sector_Ct is
However if I run the crontab job manually from webmin, it works without issues. But when it's scheduled to run, that's when it fails. Maybe it's not really running as root?
Here's my code:
#!/bin/bash
SMARTCHECK=`smartctl -a /dev/sda | grep "Reallocated_Sector_Ct" | awk 'NR==1 {print $10}'`
echo "/dev/sda - Reallocated_Sector_Ct is $SMARTCHECK"
if [ "$SMARTCHECK" != "0" ]; then
mail -s "Failing: /dev/sda" alex <<< "/dev/sda - Reallocated_Sector_Ct is $SMARTCHECK"
fi
Thanks!
There are two possibilities to run scripts using cron:
You use system crontab /etc/crontab. In this case they run as root.
You use users' crontabs, which are accessible using crontab -e. In this case they run with privileges of the user, that has added the command to his crontab.
more possible issues in cronjob scripting.
change all commands in script with full path, especially the command smartctl
check your system has /bin/bash, not /usr/bin/bash, or set the cronjob as:
0 * * * * ~/.profile;/usr/bin/bash YOUR_SCRIPT
check the mail in alex account, if there are any error messages can be found.

How do you run a crontab in Cygwin on Windows?

Some cygwin commands are .exe files, so you can run them with the standard Windows Scheduler, but others don't have an .exe extension so can't be run from DOS (it seems like).
For example I want updatedb to run nightly.
How do I make cron work?
You need to also install cygrunsrv so you can set cron up as a windows service, then run cron-config.
If you want the cron jobs to send email of any output you'll also need to install either exim or ssmtp (before running cron-config.)
See /usr/share/doc/Cygwin/cron-*.README for more details.
Regarding programs without a .exe extension, they are probably shell scripts of some type. If you look at the first line of the file you could see what program you need to use to run them (e.g., "#!/bin/sh"), so you could perhaps execute them from the windows scheduler by calling the shell program (e.g., "C:\cygwin\bin\sh.exe -l /my/cygwin/path/to/prog".)
You have two options:
Install cron as a windows service, using cygrunsrv:
cygrunsrv -I cron -p /usr/sbin/cron -a -n
net start cron
Note, in (very) old versions of cron you need to use -D instead of -n
The 'non .exe' files are probably bash scripts, so you can run them via the windows scheduler by invoking bash to run the script, e.g.:
C:\cygwin\bin\bash.exe -l -c "./full-path/to/script.sh"
hat tip http://linux.subogero.com/894/cron-on-cygwin/
Start the cygwin-setup and add the “cron” package from the “Admin” category.
We’ll run cron as a service by user SYSTEM. Poor SYSTEM therefore needs a home directory and a shell. The “/etc/passwd” file will define them.
$ mkdir /root
$ chown SYSTEM:root /root
$ mcedit /etc/passwd
SYSTEM:*:......:/root:/bin/bash
The start the service:
$ cron-config
Do you want to remove or reinstall it (yes/no) yes
Do you want to install the cron daemon as a service? (yes/no) yes
Enter the value of CYGWIN for the daemon: [ ] ntsec
Do you want the cron daemon to run as yourself? (yes/no) no
Do you want to start the cron daemon as a service now? (yes/no) yes
Local users can now define their scheduled tasks like this (crontab will start your favourite editor):
$ crontab -e # edit your user specific cron-table HOME=/home/foo
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
# testing - one per line
* * * * * touch ~/cron
#reboot ~/foo.sh
45 11 * * * ~/lunch_message_to_mates.sh
Domain users: it does not work. Poor cron is unable to run scheduled tasks on behalf of domain users on the machine. But there is another way: cron also runs stuff found in the system level cron table in “/etc/crontab”. So insert your suff there, so that SYSTEM does it on its own behalf:
$ touch /etc/crontab
$ chown SYSTEM /etc/crontab
$ mcedit /etc/crontab
HOME=/root
PATH=/usr/local/bin:/usr/bin:/bin:$PATH
* * * * * SYSTEM touch ~/cron
#reboot SYSTEM rm -f /tmp/.ssh*
Finally a few words about crontab entries. They are either environment settings or scheduled commands. As seen above, on Cygwin it’s best to create a usable PATH. Home dir and shell are normally taken from “/etc/passwd”.
As to the columns of scheduled commands see the manual page.
If certain crontab entries do not run, the best diagnostic tool is this:
$ cronevents
Just wanted to add that the options to cron seem to have changed. Need to pass -n rather than -D.
cygrunsrv -I cron -p /usr/sbin/cron -a -n
Applied the instructions from this answer and it worked
Just to point out a more copy paste like answer ( because cygwin installation procedure is kind of anti-copy-paste wise implemented )
Click WinLogo button , type cmd.exe , right click it , choose "Start As Administrator". In cmd prompt:
cd <directory_where_i_forgot_the setup-x86_64.exe> cygwin installer:
set package_name=cygrunsrv cron
setup-x86_64.exe -n -q -s http://cygwin.mirror.constant.com -P %package_name%
Ensure the installer does not throw any errors in the prompt ... If it has - you probably have some cygwin binaries running or you are not an Windows admin, or some freaky bug ...
Now in cmd promt:
C:\cygwin64\bin\cygrunsrv.exe -I cron -p /usr/sbin/cron -a -D
or whatever full file path you might have to the cygrunsrv.exe and
start the cron as windows service in the cmd prompt
net start cron
Now in bash terminal run
crontab -e
set up you cron entry an example bellow:
#sync my gdrive each 10th minute
*/10 * * * * /home/Yordan/sync_gdrive.sh
# * * * * * command to be executed
# - - - - -
# | | | | |
# | | | | +- - - - day of week (0 - 6) (Sunday=0)
# | | | +- - - - - month (1 - 12)
# | | +- - - - - - day of month (1 - 31)
# | +- - - - - - - hour (0 - 23)
# +--------------- minute
I figured out how to get the Cygwin cron service running automatically when I logged on to Windows 7. Here's what worked for me:
Using Notepad, create file C:\cygwin\bin\Cygwin_launch_crontab_service_input.txt with content no on the first line and yes on the second line (without the quotes). These are your two responses to prompts for cron-config.
Create file C:\cygwin\Cygwin_launch_crontab_service.bat with content:
#echo off
C:
chdir C:\cygwin\bin
bash cron-config < Cygwin_launch_crontab_service_input.txt
Add a Shortcut to the following in the Windows Startup folder:
Cygwin_launch_crontab_service.bat
See http://www.sevenforums.com/tutorials/1401-startup-programs-change.html if you need help on how to add to Startup. BTW, you can optionally add these in Startup if you would like:
Cygwin
XWin Server
The first one executes
C:\cygwin\Cygwin.bat
and the second one executes
C:\cygwin\bin\run.exe /usr/bin/bash.exe -l -c /usr/bin/startxwin.exe
The correct syntax to install cron in cygwin as Windows service is to pass -n as argument and not -D:
cygrunsrv --install cron --path /usr/sbin/cron --args -n
-D returns usage error when starting cron in cygwin:
$
$cygrunsrv --install cron --path /usr/sbin/cron --args -D
$cygrunsrv --start cron
cygrunsrv: Error starting a service: QueryServiceStatus: Win32 error 1062:
The service has not been started.
$cat /var/log/cron.log
cron: unknown option -- D
usage: /usr/sbin/cron [-n] [-x [ext,sch,proc,parc,load,misc,test,bit]]
$
Below page has a good explanation.
Installing & Configuring the Cygwin Cron Service in Windows:
https://www.davidjnice.com/cygwin_cron_service.html
P.S. I had to run Cygwin64 Terminal on my Windows 10 PC as administrator in order to install cron as Windows service.
Getting updatedb to work in cron on Cygwin -- debugging steps
1) Make sure cron is installed.
a) Type 'cron' tab tab and look for completion help.
You should see crontab.exe, cron-config, etc. If not install cron using setup.
2) Run cron-config. Be sure to read all the ways to diagnose cron.
3) Run crontab -e
a) Create a test entry of something simple, e.g.,
"* * * * * echo $HOME >> /tmp/mycron.log" and save it.
4) cat /tmp/mycron.log. Does it show cron environment variable HOME
every minute?
5) Is HOME correct? By default mine was /home/myusername; not what I wanted.
So, I added the entry
"HOME='/cygdrive/c/documents and settings/myusername'" to crontab.
6) Once assured the test entry works I moved on to 'updatedb' by
adding an entry in crontab.
7) Since updatedb is a script, errors of sed and find showed up in
my cron.log file. In the error line, the absolute path of sed referenced
an old version of sed.exe and not the one in /usr/bin. I tried changing my
cron PATH environment variable but because it was so long crontab
considered the (otherwise valid) change to be an error. I tried an
explicit much-shorter PATH command, including what I thought were the essential
WINDOWS paths but my cron.log file was empty. Eventually I left PATH alone and
replaced the old sed.exe in the other path with sed.exe from /usr/bin.
After that updatedb ran to completion. To reduce the number of
permission error lines I eventually ended up with this:
"# Run updatedb at 2:10am once per day skipping Sat and Sun'
"10 2 * * 1-5 /usr/bin/updatedb --localpaths='/cygdrive/c' --prunepaths='/cygdrive/c/WINDOWS'"
Notes: I ran cron-config several times throughout this process
to restart the cygwin cron daemon.

Resources