Crontab not giving results - linux

I am not in the root,
I entered the following commands in the crontab:
*/1 * * * * /home/ajain/testscript.sh
The file testscript.sh has the following commands:
#!/bin/bash
echo "The script begins now"
ping -c 2 live.com
echo The script has been run on `date` >> /home/ajain/testscript.log
echo "The script ends now"
exit
The crontab is not giving the results, however, the following command is giving the result in the testscript.log file correctly, displaying the ping date.
bash testscript.sh
Why is the crontab not working?

You can fix it in two different ways.
To provide full path to the script /home/ajain/testscript.sh. Here you don't even need to add bash because you have clearly mentioned in which shell your script should run i.e. first line of your script #!/bin/bash
Add this line before executing the script
set path=$path:/home/ajain/
testscript.sh # no need to use bash in front of it
Also providing execution permission to a script is not just enough. You need to check whether the user who is going to execute the script has permission to the location of the script or not. That means whether user can do a cd /home/ajain/ or not.
Hope this will help you.

remove >> /home/ajain/script.log, just add line to the top of file /home/ajain/testscript.sh:
#!/bin/bash
exec >> /home/ajain/script.log 2>&1
echo "The script begins now"
ping -c 2 live.com
echo "The script has been run on `date`"
echo "The script ends now"
exit
remove >> /home/ajain/script.log from crontab, just using:
*/1 * * * * /home/ajain/testscript.sh

You need do define script output.
Because of cron man page:
When executing commands, any output is mailed to the owner of the
crontab (or to the user named in the MAILTO environment variable in
the crontab, if such exists). The children copies of cron running
these processes have their name coerced to uppercase, as will be seen
in the syslog and ps output.
Fore everything else than echo The script has been run on 'date' >> /home/ajain/testscript.log you should check your/root's mail, or the syslog (eg. /var/log/syslog).
I could recommend make something like this:
*/1 * * * * /home/ajain/testscript.sh >> /home/ajain/script.log
#Edit
My crontab file on my user:
$crontab -l
# test
*/1 * * * * /home/3sky/tests/test.sh >> /home/3sky/tests/log.log
Script look like that:
#!/bin/bash
echo "The script begins now"
ping -c 2 live.com
echo The script has been run on `date`
echo "The script ends now"
exit
Permission on files:
test.sh - 0755/-rwxr-xr-x
log.log - 0644/-rw-r--r--
Output in log file:
$tail -20 log.log
2 packets transmitted, 0 received, 100% packet loss, time 10999ms
The script has been run on Thu Jun 21 12:18:12 CEST 2018
The script ends now
The script begins now
PING live.com (204.79.197.212) 56(84) bytes of data.
--- live.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 10999ms
The script has been run on Thu Jun 21 12:19:12 CEST 2018
The script ends now
The script begins now
PING live.com (204.79.197.212) 56(84) bytes of data.
--- live.com ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 10999ms
The script has been run on Thu Jun 21 12:20:12 CEST 2018
The script ends now

Related

cron & wget adding new line to each document write

So I am trying to create a cron job that will, on a daily basis, execute a job on a webpage.
My cron command:
0 0 * * */1 wget -t 1 - "http://urlto.job/job9" -O ->> home/password_reset_log.txt
All of this works, however I am trying to carry out the seemingly menial task of adding a new line to each entry in the text file.
Currently I get:
{"error":0,"result":"Password reset email successfully sent to 0 users, 0 emails failed to send","jDateLastRun":"10 Jan 2018, 00:00:07","jHandle":"check_password_resets","jID":"9"}{"error":0,"result":"Password reset email successfully sent to 0 users, 0 emails failed to send","jDateLastRun":"10 Jan 2018, 00:00:07","jHandle":"check_password_resets","jID":"9"}
So all the entries are on a single line. What I want is:
{"error":0,"result":"Password reset email successfully sent to 0 users, 0 emails failed to send","jDateLastRun":"10 Jan 2018, 00:00:07","jHandle":"check_password_resets","jID":"9"}
{"error":0,"result":"Password reset email successfully sent to 0 users, 0 emails failed to send","jDateLastRun":"10 Jan 2018, 00:00:07","jHandle":"check_password_resets","jID":"9"}
So all the entries start on a new line (easier to read and see which jobs ran successfully and which failed and the result of each time the job ran).
Is there a simple way to do this (perhaps adding a parameter to my cron command).
Use | xargs echo to append the newline.
Your entry would look something like this:
0 0 * * */1 wget -t 1 - "http://urlto.job/job9" -O - | xargs echo >> home/password_reset_log.txt
Of course, this will only work if your URL always gives exactly one line each time.
Here the demo for everyone to enjoy:
user#host:~$ echo -n "No newline"
No newlineuser#host:~$ echo -n "With newline" | xargs echo
With newline
user#host:~$

Cron not executing the shell script + Linux [duplicate]

I have a script that checks if the PPTP VPN is running, and if not it reconnects the PPTP VPN. When I run the script manually it executes fine, but when I make a cron job, it's not running.
* * * * * /bin/bash /var/scripts/vpn-check.sh
Here is the script:
#!/bin/sh
/bin/ping -c3 192.168.17.27 > /tmp/pingreport
result=`grep "0 received" /tmp/pingreport`
truncresult="`echo "$result" | sed 's/^\(.................................\).*$$'`"
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
/usr/sbin/pppd call home
fi
finally i found a solution ... instead of entering the cronjob with
crontab -e
i needed to edit the crontab file directly
nano /etc/crontab
adding e.g. something like
*/5 * * * * root /bin/bash /var/scripts/vpn-check.sh
and its fine now!
Thank you all for your help ... hope my solution will help other people as well.
After a long time getting errors, I just did this:
SHELL=/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin
* * * * * /bin/bash /home/joaovitordeon/Documentos/test.sh
Where test.sh contains:
#!/bin/bash
/usr/bin/python3 /home/joaovitordeon/Documentos/test.py;
In my case, the issue was that the script wasn't marked as executable. To make sure it is, run the following command:
chmod +x your_script.sh
If you're positive the script runs outside of cron, execute
printf "SHELL=$SHELL\nPATH=$PATH\n* * * * * /bin/bash /var/scripts/vpn-check.sh\n"
Do crontab -e for whichever crontab you're using and replace it with output of the above command. This should mirror most of your environment in case there is some missing path issue or something else. Also check logs for any errors it's getting.
Though it definitly looks like the script has an error or you messed something up when copying it here
sed: -e expression #1, char 44: unterminated `s' command
./bad.sh: 5: ./bad.sh: [[: not found
Simple alternate script
#!/bin/bash
if [[ $(ping -c3 192.168.17.27) == *"0 received"* ]]; then
/usr/sbin/pppd call home
fi
Your script can be corrected and simplified like this:
#!/bin/sh
log=/tmp/vpn-check.log
{ date; ping -c3 192.168.17.27; } > $log
if grep -q '0 received' $log; then
/usr/sbin/pppd call home >>$log 2>&1
fi
Through our discussion in comments we confirmed that the script itself works, but pppd doesn't, when running from cron. This is because something must be different in an interactive shell like your terminal window, and in cron. This kind of problem is very common by the way.
The first thing to do is try to remember what configuration is necessary for pppd. I don't use it so I don't know. Maybe you need to set some environment variables? In which case most probably you set something in a startup file, like .bashrc, which is usually not used in a non-interactive shell, and would explain why pppd doesn't work.
The second thing is to check the logs of pppd. If you cannot find the logs easily, look into its man page, and it's configuration files, and try to find the logs, or how to make it log. Based on the logs, you should be able to find what is missing when running in cron, and resolve your problem.
Was having a similar problem that was resolved when a sh was put before the command in crontab
This did not work :
#reboot ~myhome/mycommand >/tmp/logfile 2>&1
This did :
#reboot sh ~myhome/mycommand >/tmp/logfile 2>&1
my case:
crontab -e
then adding the line:
* * * * * ( cd /directory/of/script/ && /bin/sh /directory/of/script/scriptItself.sh )
in fact, if I added "root" as per the user, it thought "root" was a command, and it didn't work.
As a complement of other's answers, didn't you forget the username in your crontab script ?
Try this :
* * * * * root /bin/bash /var/scripts/vpn-check.sh
EDIT
Here is a patch of your code
#!/bin/sh
/bin/ping -c3 192.168.17.27 > /tmp/pingreport
result=`grep "0 received" /tmp/pingreport`
truncresult=`echo "$result" | /bin/sed 's/^\(.................................\).*$/\1/'`
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
/usr/sbin/pppd call home
fi
In my case, it could be solved by using this:
* * * * * root ( cd /directory/of/script/ && /directory/of/script/scriptItself.sh )
I used some ./folder/-references in the script, which didn't work.
The problem statement is script is getting executed when run manually in the shell but when run through cron, it gives "java: command not found" error -
Please try below 2 options and it should fix the issue -
Ensure the script is executable .If it's not, execute below -
chmod a+x your_script_name.sh
The cron job doesn’t run with the same user with which you are executing the script manually - so it doesn't have access to the same $PATH variable as your user which means it can't locate the Java executable to execute the commands in the script. We should first fetch the value of PATH variable as below and then set it(export) in the script -
echo $PATH can be used to fetch the value of PATH variable.
and your script can be modified as below - Please see second line starting with export
#!/bin/sh
export PATH=<provide the value of echo $PATH>
/bin/ping -c3 192.168.17.27 > /tmp/pingreport
result=`grep "0 received" /tmp/pingreport`
truncresult="`echo "$result" | sed 's/^\(.................................\).*$$'`"
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
/usr/sbin/pppd call home
fi
First of all, check if cron service is running. You know the first question of the IT helpdesk: "Is the PC plugged in?".
For me, this was happening because the cronjob was executing from /root directory but my shell script (a script to pull the latest code from GitHub and run the tests) were in a different directory. So, I had to edit my script to have a cd to my scripts folder. My debug steps were
Verified that my script run independent of cron job
Checked /var/log/cron to see if the cron jobs are running. Verified that the job is running at the intended time
Added an echo command to the script to log the start and end times to a file. Verified that those were getting logged but not the actual commands
Logged the result of pwd to the same file and saw that the commands were getting executed from /root
Tried adding a cd to my script directory as the first line in the script. When the cron job kicked off this time, the script got executed just like in step 1.
it was timezone in my case. I scheduled cron with my local time but server has different timezone and it does not run at all. so make sure your server has same time by date cmd
first run command env > env.tmp
then run cat env.tmp
copy PATH=.................. Full line and paste into crontab -e, line before your cronjobs.
try this
/home/your site folder name/public_html/gistfile1.sh
set cron path like above

Linux bash shell script output is different from cronjob vs manually running the script

I wrote a linux bash shell script which works fine except the output when I run it manually is different than when I run it from a cronjob.
The particular command is lftp:
lftp -e "lcd $outgoingpathlocal;mput -O $incomingpathremote *.CSV;exit" -u $FTPUSERNAME,$FTPPASSWORD $FTPSERVER >> ${SCRIPTLOGFILE} 2>&1
When I run the script manually, the ${SCRIPTLOGFILE} contains a lot of info such as how many files/bytes/etc transferred. But when I run the same script from a cronjob there is no output unless there was an error (such as could not connect). I have tried various terminal output configurations but none work for this lftp command. Suggestions?
It's worth reading this:
crontab PATH and USER
In particular, cron won't set the same environment variables you're used to an interactive shell.
You might want to wrap your entire cron job up in a script, and then you can, for example, temporarily add some code like export >> scriptenvironment.txt and see what the difference is between the cron invoked script and the interactively invoked script.
Try man 5 crontab for details.
Once you know what envrionment variables you need for your script to run, you can set them in the crontab as necessary, or source at the start of your own script.
EXAMPLE CRON FILE
# use /bin/sh to run commands, overriding the default set by cron
SHELL=/bin/sh
# mail any output to `paul', no matter whose crontab this is
MAILTO=paul
#
# run five minutes after midnight, every day
5 0 * * * $HOME/bin/daily.job >> $HOME/tmp/out 2>&1
# run at 2:15pm on the first of every month -- output mailed to paul
15 14 1 * * $HOME/bin/monthly
# run at 10 pm on weekdays, annoy Joe
0 22 * * 1-5 mail -s "It's 10pm" joe%Joe,%%Where are your kids?%
23 0-23/2 * * * echo "run 23 minutes after midn, 2am, 4am ..., everyday"
5 4 * * sun echo "run at 5 after 4 every sunday"

Running bash script in cron

I have the following bash script:
!/bin/bash
# script to send simple email
#Wait 5 seconds
#sleep 05
# email subject
SUBJECT="SUBJECT"
# Email To ?
EMAIL="EMAIL"
# Email text/message
MYIP=$(curl http://ipecho.net/plain)
LASTIP=$(head -n 1 /home/ubuntu/myip.txt)
echo "Last IP:" $LASTIP
echo "Current IP:" $MYIP
#Check if IPs are the same
if [[ "$MYIP" == "$LASTIP" ]]; then
echo "IP hasn't changed. Do nothing."
else
sendemail -f $EMAIL -t $EMAIL -u $SUBJECT -m $MYIP -s smtp.gmail.com -o tls=yes -xu username -xp password
echo $MYIP > myip.txt
fi
When I try to run it in the command line, it works perfectly. The problem starts when I include it in "crontab -e" like this: "* * * * * /home/ubuntu/myip.sh".
Then it does not work. Seem to be that the sendmail is not functioning properly.
When I do a: tail -f /var/log/syslog
Sep 18 21:48:02 gpuserver sendmail[18665]: r8J1m1gO018665: from=ubuntu, size=314, class=0, nrcpts=1, msgid=<201309190148.r8J1m1gO018665#gpuserver>, relay=ubuntu#localhost
Sep 18 21:48:02 gpuserver sendmail[18665]: r8J1m1gO018665: to=ubuntu, ctladdr=ubuntu (1000/1000), delay=00:00:01, xdelay=00:00:00, mailer=relay, pri=30314, relay=[127.0.0.1] [127.0.0.1], dsn=4.0.0, stat=Deferred: Connection refused by [127.0.0.1]
Any ideas?
When you run a script from the command line you are utilizing your current environment. Cron doesn't have that info ... So what you should do from the command line is:
env > me
Then edit the script and include ./me at the start of the script. That way your cron task will run with the same environment.
When a cron prints something to stdout or stderr, cron itself tries to send a report by e-mail. Since you probably don't have system-wide e-mail configured, this is probably where the error message in syslog is coming from.
To prevent cron from sending any mail, make sure your script and any commands it spawns don't output anything to stdout or stderr. An easy way to do this is to add "&>/dev/null" to your cron line.
You can also add 'MAILTO=""' at the beginning of your crontab.
This all documented in the man pages for cron/crontab (man -k cron).

Starting pppd from cron doesn't work

I want to start pppd whenever it disconnects. I am trying to setup a shell script to run every 1 minute to see if it's down and reconnect.
I have a bash script called vpn-check.sh:
ping -c3 10.8.3.0 > pingreport
result=`grep "0 received" pingreport`
truncresult="`echo "$result" | sed 's/^\(.................................\).*$/\1/'`"
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
pon VPNname
fi
When I run this script from cli directly, it works and starts ppp but when I run the same through cronjob (for root user), it doesn't work.
I tried the below and didn't work
*/1 * * * * bash /root/vpn-check.sh > /root/cronlog.txt 2>&1
I tried the below and didn't work
*/1 * * * * /root/vpn-check.sh > /root/cronlog.txt 2>&1
Finally, I tried:
*/1 * * * * /usr/sbin/pppd call VPNname> /root/cronlog.txt 2>&1
Can't figure out what could be wrong.
I still don't understand why some scripts work and don't work from cron when it is being called as the correct user according to the logs.
The only solution I found is to run:
crontab -e
and add the following lines to the top (even though I am calling the pppd daemon by the full path):
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
I fixed it. All this while I was running crontab -e
but for the user name to be added, it needs to be added to the system-wide cron file found under /etc/crontab
user that starts the job can only be added in the above mentioned system wide cron file.
You are missing the shebang from your shell script.
vpn-check.sh should look like:
#!/bin/bash
ping -c3 10.8.3.0 > pingreport
result=`grep "0 received" pingreport`
truncresult="`echo "$result" | sed 's/^\(.................................\).*$/\1/'`"
if [[ $truncresult == "3 packets transmitted, 0 received" ]]; then
pon VPNname
fi
See:
http://linuxconfig.org/bash-scripting-tutorial
What does the line "#!/bin/sh" mean in a UNIX shell script?
I was getting the same problem too.I used #dave's answer to figure it out. You just need to add the user name to the crontab, Add the next line to the end of /etc/crontab file:
*/1 * * * * root bash /root/vpn.sh
Replace the shell name of your own.

Resources