Bash Script works but not in when executed from crontab - linux

I am new to linux and the script below is just an example of my issue:
I have a script which works as expected when I execute it however when I set it to run via crontab it doesn't work as expected because it doesn't read the file content into the variable.
I have a file 'test.txt' which has 'abc' in it. My script puts the text into a variable 'var' and then I echo it out to a log file:
var=$(</home/pi/MyScripts/test.txt)
echo "$var" >/home/pi/MyScripts/log.log
This works perfectly fine when I execute it and it echo's into the log file but not when I set it via crontab:
* * * * * /home/pi/MyScripts/test.sh
The cron job runs, and it sent me the following error message:
/bin/sh: 1: /home/pi/MyScripts/test.sh: Permission denied.
But I have given it 777 permissions:
-rwxrwxrwx 1 pi pi 25 Jun 10 15:31 test.txt
-rwxrwxrwx 1 pi pi 77 Jun 10 15:34 test.sh
Any ideas?

This happens when you run the script with a different shell. It's especially relevant for systems where /bin/sh is dash:
$ cat myscript
echo "$(< file)"
$ bash myscript
hello world
$ sh myscript
$
To fix it, add #!/bin/bash as the first line in your script.

Others have provided answers, but I will give you a big clue from your error message; emphasis mine:
/bin/sh: 1: /home/pi/MyScripts/test.sh: Permission denied.
Note how the cron job was trying to use /bin/sh to run the script. That’s solved by always indicating which shell you want to use at the top of your script like this.
#!/bin/bash
var=$(</home/pi/MyScripts/test.txt)
echo "$var" >/home/pi/MyScripts/log.log
If your script is using bash, then you must explicitly set /bin/bash in some way.
Also, regarding permissions you say this:
But I have given it 777 permissions:
First, 777 permissions is a massive security risk. If you do that it means that anyone or anything on the system can read, write & execute the file. Don’t do that. In the case of a cron job the only entity that needs 7 permissions on a file is the owner of the crontab running that file.
Meaning if this is your crontab, just change the permissions to 755 which allows others to read & execute but not write. Or maybe better yet change it to 700 so only you—as the owner of the file—can do anything to the file. But avoid 777 permissions if you want to keep your system safe, stable & sane.

You have two options. In the first line of your file, tell what program you want to interpret the script
#!/bin/bash
...more code...
Or in your crontab, tell what program you want to interpret the script
* * * * * bash /home/pi/MyScripts/test.sh
In this option, you do not need to make the script executable

Related

How to run cronjob in azure cloud bash shell

I'm trying to run cron job in azure cloud shell
but it is not working
This is my simple cron job
* * * * * /home/meet/clouddrive/temp.sh
where
cat /home/meet/clouddrive/temp.sh
#!/bin/bash
echo "meet" >> /home/meet/clouddrive/test.txt
pwd
/home/meet/clouddrive
meet [ ~/clouddrive ]$ ls
temp.sh
The script is located at /home/meet/clouddrive/temp.sh. However, the pwd command in the script outputs /home/meet/clouddrive, which suggests that the script is not in the current working directory. To fix this, you can either adjust the path to the script in the cron job, or you can change the current working directory in the script to the correct location.
Make sure that the script has the appropriate permissions to be executed. You can check the permissions for the script using the ls -l command, and you can change the permissions using the chmod command. For example, to make the script executable by the owner, you can run chmod u+x /home/meet/clouddrive/temp.sh.
Can you try running the script manually from the command line to see if it works fine?
I tried to reproduce the same in my environment and got the results like below:
I tried to run Cron job in azure cloud shell like below:
when I try crontab -l there is no job from here.
Then create crontab -e
Run */1 * * * * echo "this is a test" /home/imran123/testfile.txt
Then try to create a file using vi testfile.txt and I mention "This is test"
Then try to give execute permission like below:
chmod +x test.sh
Then when I executed cmd it run successfully like below:
crontab -l
cat testfile.txt

Run a cronjob at a specific time

I would like to run a specific script at a certain time (only once!). If I run it normally like this:
marc#Marc-Linux:~/tennis_betting_strategy1/wrappers$ Rscript write_csv2.R
It does work. I however would like to program it in a cronjob to run at 10:50 and therefore did the following:
50 10 11 05 * Rscript ~/csv_file/write_csv.R
This does not seem to work however. Any thoughts where I go wrong? These are the details of the cron package im
using:
PID COMMAND
1015 cron
My system time also checks out:
marc#Marc-Linux:~/tennis_betting_strategy1/wrappers$ date
wo mei 11 10:56:46 CEST 2016
There is a special tool for running commands only once - at.
With at you can schedule a command like this:
at 09:05 am today
at> enter you commands...
Note, you'll need the atd daemon running.
Your crontab entry looks okay, however. I'd suggest checking if the cron daemon is running(exact daemon name depends on the cron package; it could be cron, crond, or vixie-cron, for instance). One way to check if the daemon is running is to use the ps command, e.g.:
$ ps -C cron -o pid,args
PID COMMAND
306 /usr/sbin/cron
Some advices.
Read more about the PATH variable. Notice that it is set differently in interactive shells (see your ~/.bashrc) and in cron or at jobs. See also this about Rscript.
Replace your command by a shell script, e.g. in ~/bin/myrscriptjob.sh
That myrscriptjob.sh file should start with #!/bin/sh
Be sure to make that shell script executable:
chmod u+x ~/bin/myrscriptjob.sh
Add some logging in your shell script, near the start; either use logger(1) or at least some date(1) command suitably redirected, or even both:
#!/bin/sh
# file myrscriptjob.sh
/bin/date +"myrscriptjob starting %c %n" > /tmp/myrscriptjob.start
/usr/bin/logger -t myrscript job starting $$
/usr/local/bin/Rscript $HOME/csv_file/write_csv.R
in the last line above, replace /usr/local/bin/Rscript by the output of which Rscript done in some interactive terminal.
Notice that you should not use ~ (but replace them with $HOME when appropriate) in shell scripts.
Finally, use at to run your script once. If you want to run it periodically in a crontab job, give the absolute path, e.g.
5 09 11 05 * $HOME/bin/myrscriptjob.sh
and check in /tmp/myrscriptjob.start and in your system log if it has started successfully.
BTW, in your myrscriptjob.sh script, you might replace the first line #!/bin/sh with #!/bin/sh -vx (then the shell is verbose about execution, and cron or at will send you some email). See dash(1), bash(1), execve(2)
Use full path (started from /) for both Rscript and write_csv2.R. Check sample command as follows
/tmp/myscript/Rscript /tmp/myfile/write_csv2.R
Ensure you have execution permission of Rscript and write permission in folder where write_csv2.R will be created(/tmp/myfile)

Execute shell script whithin another script prompts: No such file or directory

(I'm new in shell script.)
I've been stuck with this issue for a while. I've tried different methods but without luck.
Description:
When my script attempt to run another script (SiebelMessageCreator.sh, which I don't own) it prompts:
-bash: ./SiebelMessageCreator.sh: No such file or directory
But the file exists and has execute permissions:
-rwxr-xr-x 1 owner ownergrp 322 Jun 11 2015 SiebelMessageCreator.sh
The code that is performing the script execution is:
(cd $ScriptPath; su -c './SiebelMessageCreator.sh' - owner; su -c 'nohup sh SiebelMessageSender.sh &' - owner;)
It's within a subshell because I first thought that it was throwing that message because my script was running in my home directory (When I run the script I'm root and I've moved to my non-root home directory to run the script because I can't move my script [ policies ] to the directory where the other script resides).
I've also tried with the sh SCRIPT.sh ./SCRIPT.sh. And changing the shebang from bash to ksh because the SiebelMessageCreator.sh has that shell.
The su -c 'sh SCRIPT.sh' - owner is necessary. If the script runs as root and not as owner it brokes something (?) (that's what my partners told me from their experience executing it as root). So I execute it as the owner.
Another thing that I've found in my research is that It can throw that message if it's a Symbolic link. I'm really not sure if the content of the script it's a symbolic link. Here it is:
#!/bin/ksh
BASEDIRROOT=/path/to/file/cpp-plwsutil-c
ore-runtime.jar (path changed on purpose for this question)
java -classpath $BASEDIRROOT com.hp.cpp.plwsutil.SiebelMessageCreator
exitCode=$?
echo "`date -u '+%Y-%m-%d %H:%M:%S %Z'` - Script execution finished with exit code $exitCode."
exit $exitCode
As you can see it's a very siple script that just call a .jar. But also I can't add it to my script [ policies ].
If I run the ./SiebelMessageCreator.sh manually it works just fine. But not with my script. I suppose that discards the x64 x32 bits issue that I've also found when I googled?
By the way, I'm automating some tasks, the ./SiebelMessageCreator.sh and nohup sh SiebelMessageSender.sh & are just the last steps.
Any ideas :( ?
did you try ?
. ./SiebelMessageCreator.sh
you can also perform which sh or which ksh, then modify the first line #!/bin/ksh

Crontab Permission Denied [duplicate]

This question already has answers here:
CronJob not running
(19 answers)
Closed last month.
I'm having problem with crontab when I'm running a script.
My sudo crontab -e looks like this:
05 00 * * * /opt/mcserver/backup.sh
10 00 * * * /opt/mcserver/suspend.sh
05 08 * * * /sbin/shutdown -r +1
11 11 * * * /opt/mcserver/start.sh <--- This isn't working
And the start.sh looks like this:
#!/bin/sh
screen java -d64 -Xincgc -Xmx2048M -jar craftbukkit.jar nogui
and have these permissions (ls -l output)
-rwxr-xr-x 1 eve eve 72 Nov 24 14:17 start.sh
I can run the command from the terminal, either using sudo or not
./start.sh
But it wont start with crontab.
If i do
grep -iR "start.sh" /var/log
I get the following output
/var/log/syslog:Nov 27 11:11:01 eve-desk CRON[5204]: (root) CMD (eve /opt/mcserver/start.sh)
grep: /var/log/btmp: Permission denied
grep: /var/log/lightdm/x-0-greeter.log: Permission denied
grep: /var/log/lightdm/lightdm.log: Permission denied
grep: /var/log/lightdm/x-0.log: Permission denied
So my question is, why isn't it working?
And since my script run without using sudo, I don't necessarily need to put it in sudo crontab?
( and I'm using Ubuntu 12.10 )
Thanks in advance,
Philip
Answer to twalberg's response
1. Changed owner on craftbukkit to root, to see if that fixed the problem.
-rw-r--r-- 1 root root 12084211 Nov 21 02:14 craftbukkit.jar
and also added an explicit cd in my start.sh script as such:
#!/bin/sh
cd /opt/mcserver/
screen java -d64 -Xincgc -Xmx2048M -jar craftbukkit.jar nogui
2. I'm not quite sure what you mean here. Should I use the following path in my start.sh file when i start java?
(output from which java)
/usr/bin/java
3. When my server closes, screen is terminated. Is it a good idea to start screen in "detached mode" anyway?
Still got the same "Permission denied" error.
Problem solved!
By using the proper flag on screen, as below, it is now working as it should!
screen -d -m java -d64 -Xincgc -Xmx2048M -jar craftbukkit.jar nogui
Thanks a lot to those who answered, and especially twalberg!
Here are some things to check:
root obviously has read/execute permissions on start.sh, but what are the permissions on craftbukkit.jar - can root read it? You may also want to add an explicit cd /path/to/where/craftbukkit.jar/is in your start.sh script.
Is java in root's default path within cron? Note that this path is not necessarily the same as the one that you get via sudo, su or directly logging in as root - it's typically much more restricted. Use full path names to both java and craftbukkit.jar to work around that.
Since screen will not start with a terminal available, you may need screen -d -m ... instead. Hopefully, you intend to eventually attach to each screen instance and terminate it later, or you have arranged for it to terminate automatically when the script is done...
The /var/log/syslog entry shows that cron did in fact execute the script, so it must have failed for one of the above reasons (or something else I haven't noticed yet)
The other errors from grep are simply due to the fact your non-root user does not have permission to read those specific files (this is normal, and a good thing).
start.sh is owned by "eve:eve" and your crontab is running as root.
You can solve this by running following command
chown root:root /opt/craftbukkit/start.sh
Your crontab will be running as root though.
Tip: When running bash in crontab always use absolute paths (it will make debugging a lot easier).
The log shows the user has no access to dir " /var/log/", You should set the log files' permition for the cron's owner.

Shell script to log server checks runs manually, but not from cron

I'm using a basic shell script to log the results of top, netstat, ps and free every minute.
This is the script:
/scripts/logtop:
TERM=vt100
export TERM
time=$(date)
min=${time:14:2}
top -b -n 1 > /var/log/systemCheckLogs/$min
netstat -an >> /var/log/systemCheckLogs/$min
ps aux >> /var/log/systemCheckLogs/$min
free >> /var/log/systemCheckLogs/$min
echo "Message Content: $min" | mail -s "Ran System Check script" email#domain.com
exit 0
When I run this script directly it works fine. It creates the files and puts them in /var/log/systemCheckLogs/ and then sends me an email.
I can't, however, get it to work when trying to get cron to do it every minute.
I tried putting it in /var/spool/cron/root like so:
* * * * * /scripts/logtop > /dev/null 2>&1
and it never executes
I also tried putting it in /var/spool/cron/myservername and also like so:
* * * * * /scripts/logtop > /dev/null 2>&1
it'll run every minute, but nothing gets created in systemCheckLogs.
Is there a reason it works when I run it but not when cron runs it?
Also, here's what the permissions look like:
-rwxrwxrwx 1 root root 326 Jul 21 01:53 logtop
drwxr-xr-x 2 root root 4096 Jul 21 01:51 systemCheckLogs
Normally crontabs are kept in "/var/spool/cron/crontabs/". Also, normally, you update it with the crontab command as this HUPs crond after you're done and it'll make sure the file gets in the correct place.
Are you using the crontab command to create the cron entry? crontab to import a file directly. crontab -e to edit the current crontab with $EDITOR.
All jobs run by cron need the interpreter listed at the top, so cron knows how to run them.
I can't tell if you just omitted that line or if it is not in your script.
For example,
#!/bin/bash
echo "Test cron jon"
When running from /var/spool/cron/root, it may be failing because cron is not configured to run for root. On linux, root cron jobs are typically run from /etc/crontab rather than from /var/spool/cron.
When running from /var/spool/cron/myservername, you probably have a permissions problem. Don't redirect the error to /dev/null -- capture them and examine.
Something else to be aware of, cron doesn't initialize the full run environment, which can sometimes mean you can run it just fine from a fully logged-in shell, but it doesn't behave the same from cron.
In the case of above, you don't have a "#!/bin/shell" up top in your script. If root is configured to use something like a regular bourne shell or cshell, the syntax you use to populate your variables will not work. This would explain why it would run, but not populate your files. So if you need it to be ksh, "#!/bin/ksh". It's generally best not to trust the environment to keep these things sane. If you need your profile run the do a ". ~/.profile" up front as well. Or a quick and dirty way to get your relatively full env is to do it from su as such "* * * * * su - root -c "/path/to/script" > /dev/null 2>&1
Just some things I've picked up over the years. You're definitely expecting a ksh based on your syntax, so you might want to be sure it's using it.
Thanks for the tips... used a little bit of each answer to get to the bottom of this.
I did have the interpreter at the top (wasn't shown here), but may have been wrong.
Am using #!/bin/bash now and that works.
Also had to tinker with the permissions of the directory the log files are being dumped in to get things working.

Resources