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

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.

Related

`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.

Running a Shell Script as a Cronjob

I have a written a shell script to automate a build process.
The script checksout some code from an SVN repo, compiles and builds the code before extracting the built binary files and storing these in a central location.
I can manually execute the script ./autobuild.sh and it runs perfectly. There are a few sudo commands executed throughout the script, but I echo the password through for the first sudo command and the password holds for the entire time:
echo mypassword! | sudo -S make clean
When I add executing the script as a crontab it fails to complete all the tasks. I've tried to add it as a cronjob for the normal and root users.
Running crontab -e on my normal user account, I want the script to run at ten past midnight every day:
10 0 * * * /home/username/autobuild.sh
Also running a 32-but Cent OS 7 install with all the latest updates installed.
Can anyone provide any suggestions as to why it might work manually but not when run through a cron?
Try this
10 0 * * * /bin/bash /home/username/autobuild.sh
Step 1. find bash path
:~# whereis bash
Output
bash: /usr/bin/bash
step 2. create sh file add the line on top replace with your bash path
#!/usr/bin/bash
step 3. Make the script executable with command chmod +x .
step 4. add cron like this in for every minute to test
crontab -e
*/1 * * * * /usr/bin/bash ~/backup.sh >>test.log

Creating crontab for non-root user

I am attempting to run a script through crontab that is required to run as an oracle user. I have tried creating a crontab for that user by:
su -u oracle crontab -e which has allowed me to create one. I edited the file to run a perl script:
0 5 * * * /usr/bin/perl /path/master.pl > /tmp/debug.log
However when the time passes nothing is run.
Is this the proper way to create a crontab for non-root user? Also the master.pl file call multiple scripts that also need to be done as a oracle user if that makes a difference.
Use crontab's -u option. The man page says:
-u Appends the name of the user whose crontab is to be modified.
If this option is not used, crontab examines "your" crontab,
i.e., the crontab of the person executing the command. Note
that su(8) may confuse crontab, thus, when executing commands
under su(8) you should always use the -u option. If no
crontab exists for a particular user, it is created for him
the first time the crontab -u command is used under his
username.
So the correct command is:
sudo crontab -e -u oracle

Cron job does not start [duplicate]

This question already has answers here:
CronJob not running
(19 answers)
Closed last month.
I have a cron job that I want to execute every 5 minutes:
0,5,10,15,20,25,30,35,40,45,50,55 * * * * /scr_temp/scheduleSpider.sh
In /var/spool/cron/crontabs/root
The cron should execute a shell script:
#!/bin/sh
if [ ! -f "sync.txt" ]; then
touch "sync.txt"
chmod 777 /scr_temp
curl someLink
fi
That works fine from command line but not from cron. However the cron itself is startet but the script does not start.
I read about the path problem but I dont really understand it. I setup a cron that writes some env data to a file. This is the output:
HOME=/root
LOGNAME=root
PATH=/usr/bin:/bin
SHELL=/bin/sh
If I execute the env command in command line I get following output for PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
What path do I have to set in my shell script?
Your $PATH is fine; leave it alone. On Ubuntu, all the commands you're invoking (touch, chmod, curl) are in /bin and/or /usr/bin.
How did you set up the cron job? Did you run crontab some-file as root?
It seems that /etc/crontab is the usual mechanism for running cron commands as root. On my Ubuntu system, sudo crontab -l says no crontab for root. Running crontab as root, as you would for any non-root account, should be ok, but you might consider using /etc/crontab instead. Note that it uses a different syntax than an ordinary crontab, as explained in the comments at the top of /etc/crontab:
$ head -5 /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.
Run sudo crontab -l. Does it show your command?
Temporarily modify your script so it always produces some visible output. For example, add the following right after the #!/bin/sh:
echo "Running scheduleSpider.sh at \`date\`" >> /tmp/scheduleSpider.sh.log
and see what's in /tmp/scheduleSpider.sh.log after a few minutes. (You can set the command to run every minute so you don't have to wait as long for results.) If that works (it should), you can add more echo commands to your script to see in detail what it's doing.
It looks like your script is designed to run only once; it creates the sync.txt file to prevent it from running again. That could be the root (ahem) of your problem. What that your intent? Did you mean to delete sync.txt after running the command, and just forgot to do it?
root's home directory on Ubuntu is /root. The first time your script runs, it should create /root/sync.txt. Does that file exist? If so, how old is it?
Note that curl someLink (assuming someLink is a valid URL) will just dump the content from the specified link to standard output. Was that your intent (it will show up as e-mail to root? Or did you just not show us the entire command?
First: you can substitute the first field with */5 (see man 5 crontab)
Second: have cron mail the output to your email address by entering MAILTO=your#email.address in your crontab. If the script has any output, it'll be mailed. Instead of that, you may have a local mailbox in which you can find the cron output (usually $MAIL).
A better syntax for you CRON is
*/5 * * * * /scr_temp/scheduleSpider.sh
Also, check the authority of your scheduleSpider.sh file. Cron runs under a different user than the one you are likely executing your program interactively, so it may be that cron does not have authority. Try chmod 777 for now, just to check.
I suggest to:
check that /scr_temp/scheduleSpider.sh has executable bit
set PATH properly inside your script or use absolute path to command (/bin/touch instead of touch)
specify absolute path to sync.txt file (or calculate it relatively to script)
Have you added the comand via crontab -e or just by editing the crontab file? You should use crontab -e to get it correctly updated.
Set the working directory in the cron script, it probably doesn't execute the things where you think it should.
You should add /bin/sh before the absolute path of your script.
*/5 * * * * /bin/sh /scr_temp/scheduleSpider.sh

Resources